Go gotcha examples

2023. 6. 22. 08:17Programming/JAVA, C++, Go, Rust

    목차
반응형

예를들어 다음과 같은 대표적인 'Go gotcha'들이 존재합니다.

  • variable shadowing
    Go 에서는 inner scope에서 같은 이름으로 변수를 선언할 수 있습니다. 이는 이전의 변수에 접근할 수 없게 만드는 소위 'shadowing' 역할을 수행합니다.

    func main() {
     a := 1
     fmt.Println(a)
    
     if true {
         a := 2
         fmt.Println(a)
     }
    
     fmt.Println(a)
    }

위 코드의 출력은 다음과 같습니다.

1
2
1
  • slices and arrays
    Go에서 slice와 array는 매우 유사한 type 입니다. slices는 arrays에 대한 references이며 동적인 길이를 갖습니다. 반면에 arrays는 고정된 길이를 갖습니다. 함수 호출 시 slices는 reference로 넘겨야 하며, arrays는 값으로 넘거야 합니다.
func updateSlice(vals []int) {
    vals[0] = 200
}

func updateArray(vals [2]int) {
    vals[0] = 200
}

func main() {
    vals := []int{1, 2}

    updateSlice(vals)

    fmt.Println(vals)

    arrs := [3]int{1, 2}

    updateArray(arrs)

    fmt.Println(arrs)
}
[200 2]
[1, 2]

reference로 넘기는 slice의 경우에는 값이 변경 됩니다. 그러나 값으로 (복사해서) 넘기는 array의 경우에는 복사본의 값을 지닌 변수가 updateArray 함수 scope의 (즉, stack에) 새롭게 선언되어 값을 변경되고, 다시 updateArray 함수를 종료(리턴)하는 순간 해당 복사본이 제거됩니다. 즉, 원본의 값에 변경을 가하지 않습니다.
이런 동작은 예상하지 못한 동작 일 수 있습니다.

  • struct 초기화
    struct 변수 초기화 시 new 키워드를 사용할 수 있습니다. new는 0의 값으로 초기회된 객체에 대한 pointer를 반환하지만, struct 내 속성에 기본값을 적용할 수 없습니다. 그렇기에 다음과 같이 생성된 객체에 값을 할당해야 합니다.
func main() {
    type Item struct {
        value int
        name  string
    }

    item1 := Item{value: 1, name: "a"}

    item2 := new(Item)
    item2.value = 2
    item2.name = "b"
}
반응형