『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트입니다.
가변 인수 함수
...키워드 사용 하여 배열인자로 받아 올 수 있다.
package main
import (
"fmt"
)
func sum(nums ...int) int {
sum := 0
fmt.Printf("nums type : %T\n", nums)
for _, v := range nums {
sum += v
}
return sum
}
func main() {
fmt.Println(sum(1, 2, 3, 4, 5))
fmt.Println(sum(10, 20))
fmt.Println(sum())
}
//fmt.Println 함수를 참고해보자(아래)
//빈 인터페이스(interface{})를 가변인자로 받는다.
//이전 수업시간에 빈인터페이스는 모든 타입을 받는다는 것을 배웠다.
//가변인자와 빈 인터페이스로 고급 함수사용법을 알 수 있다.
func Print(a ...interface{})(n int, err error) {
return Fprintln(os.Stdout, a...)
}
defer 지연 실행
defer 명령문
- 함수 종료 전에 실행을 보장한다.
- 주로 OS 자원을 반납할때 사용한다.
- 프로그램에서 파일 작업을 시작할 때, OS에 File Handler(OS 자원 중 하나) 를 요청한다.
- 작업이 완료하고 이 File Handler 요청한 것을 반드시 반환해야한다.
- defer 는 FIFO 구조이다.(Stack)
함수 타입 변수
함수 타입 변수란 함수를 값으로 갖는 변수
어떻게 함수를 값으로 갖을 수 있을까?
- 함수의 시작위치 = 함수의 주소
즉, 함수도 숫자로 표현 가능하다. 숫자이기 때문에 변수처럼 값으로 가질 수 있다.
함수 타입은 함수 시그니쳐로 표현할 수 있다.
//함수
func add(a, b int) int{
return a+b
}
//함수 시그니쳐
func(int, int) int
package main
import (
"fmt"
)
func add(a, b int) int {
return a + b
}
func mul(a, b int) int {
return a * b
}
//func(int, int) int 타입의 함수를 반환하는 함수
func getOperator(op string) func(int, int) int {
if op == "+" {
return add
} else if op == "*" {
return mul
} else {
return nil
}
}
func main() {
//함수 타입의 변수 생성
var operator func(int, int) int
operator = getOperator("+")
var result = operator(3, 4)
fmt.Println(result)
}
함수 리터럴(람다)
일반 함수는 상태(State)를 가질 수 없지만 함수 리터럴은 내부 상태를 가질 수 있다.(First Class)
함수 리터럴에서 외부 함수의 상태를 가져오는 것(캡쳐)는 값 복사가 아닌 레퍼런스 복사이다. 즉, 포인터가 복사되는 것이다.
package main
import (
"fmt"
)
type OpFn func(int, int) int
//함수 리터럴 사용
func getOperator(op string) OpFn {
if op == "+" {
return func(a, b int) int {
return a + b
}
} else if op == "*" {
return func(a, b int) int {
return a * b
}
} else {
return nil
}
}
func main() {
//함수 타입의 변수 생성
var operator OpFn
operator = getOperator("+")
var result = operator(3, 4)
fmt.Println(result)
}
package main
import (
"fmt"
)
func main() {
i := 0
//함수 리터럴
f := func() {
//변수 상태를 가져온다 = 외부 변수의 상태를 가져와(캡쳐) 사용할 수 있다.
i += 10
}
i++
//함수 리터럴로 선언한 함수 호출
f()
//11 출력
fmt.Println(i)
}
의존성 주입
외부에서 로직을 주입하는 것을 의존성 주입이라고 한다.
package main
import (
"fmt"
"os"
)
type Writer func(string)
func writeHello(writer Writer) {
writer("Hello world2")
}
func main() {
f, err := os.Create("test.txt")
if err != nil {
fmt.Println("Faled to create a file")
return
}
defer f.Close()
writeHello(func(msg string) {
fmt.Fprintln(f, msg)
})
}
참고
https://www.youtube.com/c/TuckerProgramming/videos
'Programming Language > go' 카테고리의 다른 글
Go 언어 프로그래밍 - 자료구조 - 2 (0) | 2021.07.28 |
---|---|
Go 언어 프로그래밍 - 자료구조 - 1 (0) | 2021.07.26 |
Go 언어 프로그래밍 - 인터페이스 (0) | 2021.07.21 |
Go 언어 프로그래밍 - 숫자맞추기 게임 (0) | 2021.07.19 |
Go 언어 프로그래밍 - 문자열, 모듈과 패키지 (0) | 2021.07.16 |