Go의 make 함수는 오직 slice, map 및 channel 유형의 객체를 초기화하는 데 사용됩니다. 필요한 데이터 구조를 выдел하고 작업할 준비가 된 객체(포인터 아님)를 반환합니다.
예제:
s := make([]int, 5, 10) // 길이가 5이고 용량이 10인 슬라이스 m := make(map[string]int) // 빈 맵 ch := make(chan int, 2) // 2개의 버퍼가 있는 채널
세부 사항:
slice의 경우: 길이(len) 및 (선택적) 용량(cap) 매개변수.map 및 chan의 경우 — (선택적) 용량(초기 크기/버퍼)만.make 함수는 이미 초기화된 객체를 반환하며 사용 준비가 되어 있습니다.make를 사용하지 않고 리터럴이나 new를 통해 초기화합니다(이는 zero value의 포인터를 반환함).new와의 비교:
new(T)는 모든 필드가 0인 *T를 반환합니다.make(T)는 오직 세 가지 유형: slice, map, chan에 대해서만 T를 반환합니다.make 대신 new를 사용하여 작업할 수 있는 map을 얻을 수 있나요?
m := new(map[string]int) (*m)["a"] = 1 // 무슨 일이 발생할까요?
많은 사람들이 이것이 올바르다고 생각하지만, runtime에서 panic이 발생합니다: assignment to entry in nil map. 왜냐하면 변수 *m에 nil이 있기 때문입니다!
올바른 방법: make를 사용하세요:
m := make(map[string]int) m["a"] = 1 // OK
이야기
캐시를 저장하는 마이크로서비스에서 var cache map[string]interface{}를 초기화 없이 만들었고, 이로 인해 생산 중 기록 시 panic이 발생하여 이해할 수 없는 스택 트레이스를 남겼습니다. 코드 분석 후 문제를 발견했습니다: map이 nil이었습니다.
이야기
데이터 파이프라인을 작성할 때 채널의 버퍼를 잊어버리고 make(chan int)를 통해 생성했습니다. 그 결과, 고루틴이 읽기를 기다리면서 멈췄고 비동기 교환이 예상되었습니다. 오류는 대규모 테스트에서만 발견되었습니다.
이야기
new로 초기화하는 프로젝트에서, 일부 개발자들이 make([]int, 10) 대신 new([]int)를 사용하려 했고, 그 결과 nil 슬라이스의 포인터를 얻어 첫 번째 기록 시에 runtime panic이 발생했습니다.