언어 및 도구들 공부/Go

Go) 변수의 재사용, :=

Dr.Mlem 2025. 4. 9. 08:11
여기에서 왜 아래의 err에 새 변수로 인식되지 않는거야?
 

ChatGPT의 말:

아주 좋은 질문이야!
너가 말한 이 코드에서 발생하는 문제는 Go의 변수 선언 범위(scope)와 shadowing 규칙 때문이야.


🔍 상황 다시 보기

go
복사편집
// 먼저 여기서 err 선언 hashedPW, err := utils.HashPassword(req.PW) if err != nil { utils.HandleErrResponse(ctx, 500, "700?", "비밀번호 해싱 실패") return } // 그리고 여기서 또 err := ... 로 선언 _, err := db.DB.Exec(query, req.ID, hashedPW)

🔥 왜 문제가 되냐면?

Go는 같은 블록(scope) 안에서는 같은 이름의 변수를 :=로 다시 선언할 수 없어.
즉, :=은 **"새 변수 선언"**이고, 이미 err가 있는 상태에서 다시 err := ...를 쓰면 Go는 컴파일 에러를 내거나,
의도치 않게 기존 err를 재사용하는 경우도 생겨.


✅ 해결 방법

아래처럼 두 번째 err는 =만 사용해서 기존 변수에 값을 할당해줘야 해:

go
복사편집
_, err = db.DB.Exec(query, req.ID, hashedPW) // ❗ := → = if err != nil { utils.HandleErrResponse(ctx, 500, "7002", fmt.Sprintf("DB 저장 실패: %v", err)) return }

📌 정리: 언제 := 쓰고 언제 = 써야 해?

상황 사용
변수를 처음 선언할 때 := 사용
이미 선언된 변수에 값만 바꿀 때 = 사용

✅ 결론

너가 두 번째 err := ...를 쓴 자리는 이미 위에서 err를 선언했기 때문에,
그냥 err = ...로 바꿔야 하는 상황이야.

Go는 이런 "중복 선언"에 엄격하니까,
처음만 :=, 이후엔 =! 이거 기억해두면 돼 😎

필요하면 err 변수 자체를 블록 분리해서 스코프 짧게 쓰는 팁도 알려줄게!

 
 
 
 

나의 말:

// 4. db에 insert 쿼리 실행 query := "INSERT INTO users (id, pw) VALUES (?, ?)" _, err = db.DB.Exec(query, req.ID, hashedPW) // Exec 함수는 쿼리를 실행하고, 결과를 반환함. 그러나 그 결과값이 필요없기에 _ 처리 // 이 과정에서 비밀번호 암호화가 필요할 것으로 추측측 if err != nil { utils.HandleErrResponse(ctx, 500, "7002", fmt.Sprintf("DB 저장 실패: %v", err)) return } log.Println("[DEBUG] id-pw 가입 3. 입력된 값으로 db insert 완료") // 4. 정상적으로 처리되면 응답 전달 후 종료 resp.Result.Code = "9000" resp.Result.Msg = fmt.Sprintf("Success, %s의 db 등록 확인", req.ID) // resp 구조체를 JSON으로 변환 respJson, err := json.Marshal(resp) if err != nil { utils.HandleErrResponse(ctx, 500, "7003", fmt.Sprintf("JSON 응답 변환 실패: %v", err)) return } utils.WriteJSONResponse(ctx, respJson) 그런데 이 아래에서는 또 멀쩡하게 나오는 이유는 뭐지? 아래에선 err:= 꼴인데?
 

ChatGPT의 말:

좋은 질문이야! 👏
너가 궁금한 건 이거지:

"위에서는 err 변수 선언이 이미 되어 있어서 err := 쓰면 안 되는데,
왜 아래에서는 다시 err := json.Marshal(...)가 가능하냐?"


✅ 핵심 개념: Go의 짧은 선언(:=)은 같은 라인에 새로운 변수가 하나라도 있으면 허용된다


🔍 예제 다시 보기

go
복사편집
respJson, err := json.Marshal(resp)

이 줄에서는 err는 이미 위에서 선언된 적이 있어도,
respJson이라는 새로운 변수가 같이 선언되기 때문에 에러가 나지 않아.

즉, Go의 규칙은 이렇게 되어 있어:

:=를 쓸 때 그 줄에 새로 선언되는 변수가 최소 1개 이상 있으면 괜찮아.


✅ 정리하면

선언 결과
err := ... ❌ 이미 err가 선언되어 있으면 중복 선언 에러
respJson, err := ... ✅ respJson이 새 변수이기 때문에 허용

✅ 추천 패턴

  • 한 번 선언한 변수는 그 이후에 :=로 재선언하지 말고 =로 재할당하자
  • respJson, err := ... 형태처럼 새로운 변수가 함께 있을 때는 괜찮음

🧠 한 줄 요약

Go에서는 :=로 선언할 때, 한 개 이상 새로운 변수가 포함되어 있으면
기존에 있는 변수와 함께 써도 괜찮다. 그래서 respJson, err :=는 OK! 😎

원하면 이걸 linter로 자동 체크하게 하는 설정도 도와줄 수 있어!