2021. 2. 3. 23:15ㆍ내가 좋아해서 하는 Go
1. If else 문
golang의 if문은 다음과 같은 문법을 지닙니다.
if 조건문 {
}
else나 else if를 사용하고 싶다면 끝나는 중괄호와 같은 라인에 와야 합니다.
if 조건문 {
} else if 조건문 {
} else {
}
간단한 구문을 실행할 수 있고, 만약 그 구문에서 변수를 선언하면, if, else if, else 세트의 안에서만 스코프가 존재합니다.
if a := 2; a > 5{
} else {
fmt.Println(a) // 성공
}
fmt,Println(a) // 실패
2. For 문
Golang의 For문은 괄호를 필요로 하지 않는다. 그 대신 반드시 중괄호가 같은 줄에 와야합니다.
for 초기구문; 조건 구문; 사후 구문 {
}
초기 구문과 사후 구문은 생략이 가능합니다.
Golang은 While이 없기 때문에 다음과 같이 while의 기능을 수행합니다.
for 조건 구문 {
}
3. Switch 문
if-else if -else가 길어질 경우, switch로 대체할 수 있습니다.
이 때, 다른언어와는 다르게, break문이 필요하지 않습니다.
switch value {
case 1:
fmt.Println("a")
case 2:
fmt.Println("b")
case 3:
fmt.Println("c")
case 4:
fmt.Println("d")
default:
fmt.Println("e")
}
아래와 같은 형식으로 switch문을 구현할 수도 있습니다. 이 경우 switch true와 같고, 위의 case문부터 실행되기 때문에, if - else if문과 같은 역할을 합니다.
switch {
case a < 1:
fmt.Println("a")
case a < 2:
fmt.Println("b")
case a < 3:
fmt.Println("c")
case a < 4:
fmt.Println("d")
}
4. Defer 문
조금 어려운 개념이 등장합니다. "평가 : 위치, 수행 : 연기"되는 함수의 호출 방식이 있습니다.
이 말을 이해하기가 좀 어려운데, 아래의 코드를 봐보는 게 좋을 것 같습니다.
func main(){
i := 1
defer fmt.Println(i)
i++
}
defer의 뒤에 있는 함수의 호출은 defer가 위치한 함수의 종료로 연기되었습니다.
따라서, 화면에는 i++까지 수행한 뒤, fmt.Println(i) 가 수행되기 때문에 2가 출력될 것처럼 느껴집니다.
그러나, 위에서 말했는 함수의 평가는 defer의 위치에서 이루어집니다.
즉, 화면에는 defer fmt.Println(i) 위치에서의 i값인 1이 출력됩니다.
아래의 코드는 직접 실행하여 보시면 좋겠습니다.
package main
import (
"fmt"
)
func main() {
i := 1
defer fmt.Println(i) //1
i++
defer fmt.Println(i) //2
}
아래의 코드가 어떻게 나오나요?
1번 defer는 1을 출력할테고, 2번 defer는 2를 출력할테니,
1
2
가 나올것 같지만, 늦게 나온 defer가 먼저 수행되기 때문에, (FILO : first in last out)
2
1
로 출력됩니다.
더 어렵게 가보겠습니다.
package main
import (
"fmt"
)
func add(a *int, b int) int {
*a *= 3
return *a + b
}
func main() {
i := 1
defer fmt.Println(add(&i, 2))
fmt.Println(i)
defer fmt.Println(add(&i, 2))
i++
defer fmt.Println(i)
}
출력
3
10
11
5
이해가 가질 않습니다.
package main
import (
"fmt"
)
func add(a *int, b int) int {
*a *= 3
return *a + b
}
func main() {
i := 1
defer add(&i, 2)
fmt.Println(i)
defer fmt.Println(add(&i, 2))
i++
defer fmt.Println(i)
}
출력
1
4
5
?????????
1번 코드부터 설명하겠습니다.
우리는 아래 코드에서 구문의 실행순서가
2 -> 4 -> 5 -> 3 -> 1
일 것이라고 믿습니다.
package main
import (
"fmt"
)
func add(a *int, b int) int {
*a *= 3
return *a + b
}
func main() {
i := 1
defer fmt.Println(add(&i, 2)) //1
fmt.Println(i) //2
defer fmt.Println(add(&i, 2)) //3
i++ //4
defer fmt.Println(i) //5
}
그러나, 안타깝게도 그렇게 간단한 것만은 아닙니다.
Haskell과 같은 함수형 언어를 사용해보지 않으신 분들은 낯설텐데요.
defer는 "자신의 뒤에 온 함수"를 나중에 실행하고, 인자의 평가는 당장합니다.
즉 함수의 콜 순서가
add(&i, 2) - (가)
fmt.Println(i) // 3 출력
add(&i, 2) - (나)
i++
fmt.Println(add(&i, 2)) - (3) // add는 이미 나에서 실행되어 값으로 바뀜 -> 즉 i = 3이므로 3+2 = 5출력
fmt.Println(add(&i, 2)) - (1) // add는 이미 가에서 실행되어 값으로 바뀜 -> 즉 i = 9이므로 9+2 = 11출력
가 됩니다.
꼭 헷갈리더라도 이해하고 넘어가주세요!
위에를 이해했다면, 2번째 코드를 직접 해독해 봅시다!
package main
import (
"fmt"
)
func add(a *int, b int) int {
*a *= 3
return *a + b
}
func main() {
i := 1
defer add(&i, 2)
fmt.Println(i)
defer fmt.Println(add(&i, 2))
i++
defer fmt.Println(i)
}
모르시겠다면, 댓글 남겨주세요!
'내가 좋아해서 하는 Go' 카테고리의 다른 글
분석하는 Go : ReadAll (0) | 2021.02.08 |
---|---|
내가 좋아해서 하는 Go 1 : Go의 기초 (0) | 2021.02.02 |