func main() {
x := 10
if x > 5 {
fmt.Println(x)
x := 5
fmt.Println(x)
}
fmt.Println(x)
}
- 그림자로 가리우듯, 앞서 등장한 변수의 값을, 동일한 이름을 가진 지역적 변수가 가려버린다.
- 그래서 앞서 등장한 변수를 전혀 접근할 수 없게 되어버린다.
- 심지어 패키지 이름으로 장난치는것도 가능하다. 그러면, shadowing 된 영역에서는 해당 패키지 접근 자체가 불가능하다.
$ go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
$ shadow ./...
- Makefile 룰에 추가해두는것이 좋다
- golangci-lint 에서 이것도 이미 지원한다.
- C-style
for i := 0; i < 10; i++ {}
- condition-only
i := 1
for i < 100 {}
- infinite for
for {}
- for-range (여기 안에서 조작되는
v
는 카피된 것이다)
for i, v := range vals {}
m := map[string]int{
"a": 1,
"c": 3,
"b": 2,
}
for i := 0; i < 3; i++ {
fmt.Println("Loop", i)
for k, v := range m {
fmt.Println(k, v)
}
}
samples := []string{"hello", "apple_π!"}
for _, sample := range samples {
for i, r := range sample {
fmt.Println(i, r, string(r))
}
fmt.Println()
}
두 번째 문자열 관련 출력 결과
0 97 a
1 112 p
2 112 p
3 108 l
4 101 e
5 95 _
6 960 π
8 33 !
func main() {
samples := []string{"hello", "apple_π!"}
outer:
for _, sample := range samples {
for i, r := range sample {
fmt.Println(i, r, string(r))
if r == 'l' {
continue outer
}
}
fmt.Println()
}
}
for 반복문 내에 위치한 switch 문에서, for 반복문을 원큐에 탈출하고싶다면 레이블링 기법을 쓰면 좋다.
func main() {
loop:
for i := 0; i < 10; i++ {
switch {
case i%2 == 0:
fmt.Println(i, "is even")
case i%3 == 0:
fmt.Println(i, "is divisible by 3 but not 2")
case i%7 == 0:
fmt.Println("exit the loop!")
break loop
default:
fmt.Println(i, "is boring")
}
}
}
가능하면 피하는게 좋다.
너무 중구난방 메뚜기식 널뛰길르 방지하기 위해 두 가지 제한 사항을 둔다.
- 변수 선언된 부분을 건너뛸 순 없다
- 블록 내부로 건너뛸 순 없다.
아래는 두 경우를 모두 보여주는 예제이다.
func main() {
a := 10
goto skip
b := 20
skip:
c := 30
fmt.Println(a, b, c)
if c > a {
goto inner
}
if a < b {
inner:
fmt.Println("a is less than b")
}
}
일종의 try-catch-final 처럼 쓸 수 있다. 쓰기 나름인데, 어찌되었든 예측 가능한 수준으로 작성하면 된다.