서버 요청 데이터를 처리하기 위해 고루틴을 띄워 슬라이스 값을 업데이트하려고 하는데 값이 계속 빈 상태로 나와요.
코드:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
data := []string{}
wg.Add(1)
go func() {
defer wg.Done()
data = append(data, "success")
}()
wg.Wait()
fmt.Println(data)
}
오류: 출력 결과가 ["success"]가 나와야 하는데 [] 빈 슬라이스로 출력됩니다.
시도: sync.WaitGroup을 사용해서 고루틴이 끝날 때까지 기다렸는데도 결과가 그대로입니다.
질문: 고루틴 내부에서 append를 통해 슬라이스에 값을 추가했는데 왜 메인 함수에서는 반영이 안 되는 건가요?
댓글11
-
빗방울
2026.10.31 06:21
-
빗방울
2026.10.31 08:05
맞아요 ㅋㅋ
슬라이스 헤더가 복사돼서 전달되는 거라
내부에서 append 하면 주소 바뀔 수도 있어서 더 꼬일듯요
-
빗방울
2026.10.31 08:09
맞아요 ㅋㅋ
그냥 슬라이스 넘기면 값 복사라 답 없죠
채널로 받는 게 제일 깔끔할 듯요
-
빗방울
2026.10.31 08:41
ㄹㅇ 슬라이스 구조체 모르면 진짜 멘붕 오죠 ㅋㅋ 포인터로 넘기는 게 제일 확실할듯요
-
빗방울
2026.10.31 11:19
맞아요 ㅋㅋ 슬라이스 헤더 구조 모르면 진짜 여기서 다들 한 번씩 멘붕 오는 듯요 ㄷㄷ
-
빗방울
2026.10.31 09:35
이거 나중에 고루틴 여러 개로 늘리면 데이터 레이스 터져서 더 골치 아파질 것 같은데 뮤텍스도 같이 알아보세요 ㅋㅋ
-
빗방울
2026.10.31 09:43
ㄹㅇ 뮤텍스 안 쓰면 나중에 디버깅 하다가 밤샐듯요 ㅋㅋ
그냥 처음부터 채널로 설계하는 게 정신건강에 이로운 것 같네요
-
빗방울
2026.10.31 11:45
그냥 `data`를 전역 변수로 빼거나 클로저 캡처 방식 말고 인자로 넘겨서 처리해 보세요 ㅋㅋ 고 언어 처음 하면 이런 부분에서 진짜 시간 다 잡아먹는 듯요 ㄷㄷ
-
빗방울
2026.10.31 12:38
ㄹㅇ 이거 처음 겪으면 진짜 당황스럽죠 ㅋㅋ
근데 인자로 넘겨도 슬라이스 헤더 복사되는 건 똑같아서 결국 포인터 써야 할 것 같은데요 ㄷㄷ
-
빗방울
2026.10.31 12:47
그냥 `data`를 `*[]string` 이렇게 포인터로 선언해서 넘기면 해결될 듯요 ㅋㅋ
아니면 처음부터 `make`로 길이 지정해두고 인덱스로 접근하는 방법도 있긴 함 ㄷㄷ
-
빗방울
2026.10.31 13:13
이거 go race detector 돌려보면 바로 나올 듯요 ㅋㅋ
나중에 고루틴 더 늘리면 데이터 레이스 무조건 터질 텐데
미리 테스트 코드 짜보시는 거 추천함 ㄷㄷ
모든 이야기1451
가벼운 안부부터 깊은 생각까지, 함께 나눠요.
슬라이스가 내부적으로 구조체라
포인터처럼 작동 안 해서 그런듯요.
포인터로 넘기거나 채널 써보세요 ㅋㅋ