var k int = 10
var p = &k //k의 주소를 할당
println(*p) //p가 가리키는 주소에 있는 실제 내용을 출력
// 괄호를 쓰지 않아도 된다.
// 조건 블록 시작 괄호 { 가 같은 라인에 있어야 한다.
if k == 1 { //같은 라인
println("One")
}
// if 조건식을 실행하기 전에 val := i * 2; 라는 식을 실행할 수 있다.
if val := i * 2; val < max {
// if 조건식 이전에 선언된 식은 if 블록 안에서만 사용될 수 있다.
println(val)
}
// 아래 처럼 사용하면 Scope 벗어나 에러
val++
func grade(score int) {
// switch 뒤에 조건문이 없을 수 있다 -> 이 경우 true로 인식한다.
switch {
// case 조건문을 순서대로 검사하여 조건에 맞는 경우 case 블럭을 실행하고 switch 문을 빠져나온다.
case score >= 90:
println("A")
case score >= 80:
println("B")
case score >= 70:
println("C")
case score >= 60:
println("D")
default:
println("No Hope")
}
}
// 변수 타입 검사
switch v.(type) {
case int:
println("int")
case bool:
println("bool")
case string:
println("string")
default:
println("unknown")
}
// Go는 case 마지막에 break이 없어도 break 하여 switch문 빠져나온다.
//
func check(val int) {
switch val {
case 1:
fmt.Println("1 이하")
// fallthrough를 사용하면 하단 case도 검사한다.
fallthrough
case 2:
fmt.Println("2 이하")
fallthrough
case 3:
fmt.Println("3 이하")
fallthrough
default:
fmt.Println("default 도달")
}
}
sum := 0
// () 소괄호 생략 -> 사용하면 에러 발생
for i := 1; i <= 100; i++ {
sum += i
}
println(sum)
// 조건문만 사용할 수 있다.
// while문이 없는 대신 while처럼 사용할 수 있다.
func main() {
n := 1
// n이 100 이하인지 여부만 확인한다.
for n < 100 {
n *= 2
//if n > 90 {
// break
//}
}
println(n)
}
// 무한루프는 조건식을 생략하면 가능하다.
func main() {
// 무한으로 println만 작동한다.
for {
println("Infinite loop")
}
}
// 컬렉션에서 한 요소씩 가져와 for문 블럭 문장을 실행한다.
names := []string{"홍길동", "이순신", "강감찬"}
for index, name := range names {
println(index, name)
}
// for문에서 바로 빠져나올 때 break을 사용한다.
// for 블록 실행 중에 조건식으로 돌아가려면 continue를 사용한다.
// goto 문을 사용하면 임의의 문장으로 이동할 수 있다.
package main
func main() {
var a = 1
for a < 15 {
if a == 5 {
a += a
continue // for루프 시작으로
}
a++
if a > 10 {
break //루프 빠져나옴
}
}
if a == 11 {
goto END //goto 사용예
}
println(a)
END:
println("End")
}
// break 레이블을 사용하여 지정된 레이블로 이동할 수 있다.
// for문 바깥쪽으로 빠져나와 break이 있는 루프를 건너뛰고 다음 문장으로 이동한다.
package main
func main() {
i := 0
L1:
for {
if i == 0 {
break L1
}
}
println("OK")
}
Go가 C++, Java, Python의 장점을 뽑아 만들었다는데 이제 이해가 간다.
다만 C++을 잠깐 배웠을 때 goto를 사용하면 가독성이 떨어지고 구조를 이해하기 힘드니 사용을 지양하라고 배웠던 거 같은데, Go에서 추가가 된 걸 보니 의아해서 찾아봤다.
https://stackoverflow.com/questions/11064981/why-does-go-have-a-goto-statement
스택 오버플로우에 내가 궁금했던 것과 같은 질문을 한 사람이 있어 읽어보니, 결론은 잘 사용하면 유용하게 쓸 수 있다고 한다.
그리고 Go의 goto는 버그를 피하기 위해 제한 사항을 두었다는데, C++의 goto는 쓰지 말라고 한 내용만 기억나서 차이점은 잘 모르겠다.
https://go.dev/ref/spec#Goto_statements
평소에 while이 for문에 흡수되어도 무방하겠다 생각했었는데 나와 비슷한 생각을 한 사람이 있었는지 for만 사용해서 while처럼 쓸 수 있게 한 부분도 흥미롭다.
switch case에서 break이 컴파일 될 때 자동으로 들어간다는 특징도 마음에 든다.
Java로 시작해 Kotlin, JS, TS를 거쳐 Go까지 왔다. 새로운 언어를 배울 때 가끔 이렇게 만든 사람의 생각을 단편적으로나마 알 수 있어 무척 재밌다.