일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- install
- bitcoin
- Sync
- package
- Python
- go언어
- C
- http
- Golang
- range
- c++
- write
- go
- 리뷰
- FOR
- tcp
- window
- 영화
- windows
- API
- json
- JavaScript
- channel
- Callback
- Close
- mutex
- 책
- Linux
- File
- GO 언어
- Today
- Total
Code Habit
Go ) 함수 본문
Go 언어는 다음과 같이 간단하게 함수를 정의하고 호출할 수 있다.
- func 함수명(){}
func hello() {
fmt.Println("Hello, world!")
}
func world()
{ // 컴파일 에러
fmt.Println("world !");
}
func main() {
hello()
}
Go 언어는 함수 정의를 시작한 줄에서 { (여는 중괄호)가 시작된다. 다음 줄에 작성하면 컴파일 에러가 발생한다.
※ Go언어는 함수를 정의할 때 C, C++과 다르게 위치 제약이 없다. 즉 뒤에 정의해도 앞에서 사용할 수 있다.
함수에서 매개변수를 받고 값을 리턴하는 방법을 알아보겠다.
- func 함수명(매개변수명 자료형) 리턴값 자료형 {}
func sum(a int, b int) int {
return a + b
}
func main() {
r := sum(1, 2)
fmt.Println(r) // 3
}
Go 언어는 리턴값에 이름을 지정할 수도 있다.
- func 함수명(매개변수명 자료형) (리턴값 변수명 자료형) {}
func sum(a int, b int) (r int) {
r = a + b // 리턴값 변수 r에 값 대입
return // 리턴값 변수를 사용할 때는 return 뒤에 변수를 지정하지 않음
}
func main() {
r := sum(1, 2)
fmt.Println(r)
}
Go 언어는 함수에서 값을 여러 개 리턴할 수 있다.
- func 함수명(매개변수명 자료형) (리턴값 자료형1, 리턴값 자료형2) { }
func SumAndDiff(a int, b int) (int, int) { // int 형 리턴값이 두 개인 함수 정의
return a + b, a - b // 리턴할 값 또는 변수를 차례대로 나열
}
func main() {
sum, diff := SumAndDiff(6, 2) // 변수 두 개에 리턴값 두 개를 대입
fmt.Println(sum, diff)
_, diff2 := SumAndDiff(8, 3)
fmt.Println(diff2)
}
여기서 리턴값은 함수에서 지정한 순서대로 리턴된다. 따라서 리턴값을 받을 변수 하나만 지정하면 첫 번째 리턴값만 저장된다. 첫 번째 리턴값을 생략하고 두 번째 리턴값부터 사용하고 싶다면 _(밑줄 문자)를 사용한다.
함수의 매개변수 개수가 정해져 있지 않고 유동적으로 변하는 형태를 가변인자라고 한다.
- func 함수명(매개변수명 ...자료형) 리턴값_자료형 {}
func sum(n ...int) int {
total := 0
for _, value := range n {
total += value
}
return total
}
func main() {
r := sum(1, 2, 3, 4 ,5)
fmt.Println(r) // 15
n := []int{1, 2, 3, 4, 5}
r = sum(n...) // ...을 사용하여 가변인자에 슬라이스를 바로 넘겨줌
fmt.Println(r) // 15
}
매개변수의 자료형 앞에 ...을 붙여 가변인자로 지정한다. 여기서 가변인자로 받은 변수는 슬라이스 타입이므로 range키워드를 사용하여 값을 꺼내 사용하면 된다.
가변인자는 슬라이스 타입이므로 슬라이스를 바로 넘겨줄 수도 있다. 단 여기서 가변인자 함수는 int형 값만 여러 개 받도록 되어 있고, 슬라이스 자체는 받을 수 없으므로 매개변수에 슬라이스만 넣지 않고 뒤에 ...을 붙인다. ...을 붙이면 슬라이스에 들어 있는 요소를 각각 넘겨준다.
Go 언어는 간단하게 함수를 변수에 저장할 수 있다.
- var 변수명 func(매개변수명 자료형) 리턴값 자료형 = 함수명
func sum(a int, b int) int {
return a + b
}
func main() {
var hello func(a int, b int) int = sum // 함수를 저장하는 변수를 선언하고 함수 대입
world := sum // 변수 선언과 동시에 함수를 바로 대입
fmt.Println(hello(1,2)) // 3: hello 변수에 저장된 sum 함수 호출
fmt.Println(world(1,2)) // 3: world 변수에 저장된 sum 함수 호출
}
Go 언어는 변수를 선언하고 대입할 때 자동으로 자료형을 추론할 수 있으므로 :=를 사용하면 간단하게 변수에 함수를 저장할 수 있다.
변수뿐만 아니라 슬라이스(배열)에도 함수를 간단하게 저장할 수 있다.
- 슬라이스 = []func(매개변수명 자료형) 리턴값 자료형{함수명1, 함수명2}
func sum(a int, b int) int {
return a + b
}
func diff(a int, b int) int {
return a - b
}
func main() {
f := []func(int, int) int{sum, diff} // 함수를 저장할 수 있는 슬라이스를 생성한 뒤
// 함수로 초기화
fmt.Println(f[0](1,2)) // 3 : 배열의 첫번째 요소로 함수 호출
fmt.Println(f[1](1,2)) // -1 : 배열의 두 번째 요소로 함수 호출
}
[] 뒤에 매개변수의 자료형과 리턴값의 자료형을 지정해야 하며 {} (중괄호) 안에 대입할 함수명을 나열하면 된다.
마찬가지로 맵에도 함수를 간단하게 저장할 수 있다.
- 맵 := map[키 자료형]func(매개변수명 자료형) 리턴값 자료형("키":함수명}
func sum(a int, b int) int {
return a + b
}
func diff(a int, b int) int {
return a - b
}
func main() {
f:= map[string]func(int, int) int { // 함수를 저장할 수 있는 맵을 생성한 뒤
"sum" : sum, // 함수로 초기화
"diff" : diff,
}
fmt.Println(f["sum"](1, 2)) // 3 : 맵에 sum 키를 지정하여 함수 호출
fmt.Println(f["diff"](1, 2)) // -1 : 맵에 diff 키를 지정하여 함수 호출
}
Go 언어는 JavaScript처럼 함수 안에서 이름이 없는 익명 함수를 정의한 뒤 바로 호출할 수 있다.
- func(매개변수명 자료형) 리턴값 자료형{}()
func main() {
func() { // 함수에 이름이 없음
fmt.Println("Hello, world!")
}()
func(s string) { // 익명 함수를 정의한 뒤
fmt.Println(s)
}("Hello, world!") // 바로 호출
r := func(a int, b int) int {
return a + b
}(1, 2)
fmt.Println(r) // 3
}
// 실행 결과
Hello, world!
Hello, world!
3
익명 함수는 함수를 정의한 뒤 () (괄호)를 사용하여 바로 함수를 호출한다. 이때도 매개변수 및 리턴값을 사용할 수 있다. 이런 익명함수는 코드 양을 줄일 수 있으며 클로저, 지연 호출(defer), 고루틴(go)에서 주로 사용된다.