import "fmt"
type Vertex struct {
X int
Y int
}
// 구조체 인스턴스 선언 방법
var (
//① 일반적인 선언방식입니다. X가1, Y가 2로 초기화됩니다.
v1 = Vertex{1, 2}
//② X만 값을 지정해주고, Y는 int에 zero value로 설정됩니다.
v2 = Vertex{X: 1}
//③ X, Y모두 int에 zero value로 설정됩니다.
v3 = Vertex{}
)
func main() {
fmt.Println("v1.X값:", v1.X)
v1.X = 4
fmt.Println("v1.X = 4로 바꾼 v1.X값:", v1.X)
//④ 구조체 포인터로도 구조체의 값을 바꿀 수 있습니다.
var p = &v1
p.X = 10
fmt.Println("포인터로 바꾼 v1.X값:", v1.X)
}
Q1. 위에서,
p.X=10 이 부분은, 원래 *p.X = 10 이어야 맞는 코드가 아닌가?
A1.
아주 예리해!
네 말대로 p는 포인터니까, **원래대로라면 (*p).X = 10**이 맞는 표현이야.
하지만 Go에서는 p.X = 10도 정상적으로 작동해, 그 이유를 정확히 설명해줄게.
✅ 요점 정리 먼저
Go에서는 포인터를 통해 구조체 필드에 접근할 때,
(*p).X = 10이라고 쓰지 않아도 p.X = 10으로 **자동 변환(dereferencing)**이 일어나서 동작함.
📌 왜 p.X = 10이 가능한가?
Go 언어는 개발자의 편의를 위해 다음과 같은 자동 dereferencing 규칙을 제공해:
구조체 포인터에서 필드에 접근할 때,
컴파일러가 자동으로 (*p).X → p.X로 변환해서 처리함
🔍 실제로 어떤 차이가 있나?
var p = &v1
p.X = 10 // ✅ 자동으로 (*p).X = 10 으로 처리됨
(*p).X = 20 // ✅ 원래 문법. 직접 역참조
fmt.Println(v1.X) // 출력: 20
→ 두 문법은 완전히 동일하게 동작하고, 컴파일러가 알아서 도와줘.
🧠 Go의 의도
Go는 “실용주의 언어”라서 C처럼 엄격하게 (*p).X 쓰라고 강요하지 않아.
오히려:
“아, 네가 포인터인 구조체에서 필드에 접근하려는 거지? 자동으로 역참조해줄게!”
이런 식으로 동작해.
✅ 결론
| 표현 | 의미 | 동작 |
| (*p).X = 10 | 직접 역참조 | ✅ |
| p.X = 10 | 자동 역참조 | ✅ (Go에서 허용) |
그래서 네가 말한 "원래는 *p.X = 10이 아니냐"는 개념적으로 맞지만,
Go에서는 편하게 p.X = 10 써도 된다는 거야 😄
궁금하면 구조체 배열 포인터에서도 이런 방식 되는지도 테스트해볼 수 있어!
그것도 보고 싶어?
✅ 정리: Go에서 구조체 필드 접근 시
구조체든 구조체 포인터든 .필드명으로 접근하면,
Go가 자동으로 역참조 처리를 해준다.
즉:
- v.X → 구조체 값에서 필드 접근
- p.X → 구조체 포인터에서 필드 접근 → Go가 자동으로 (*p).X로 처리
📌 왜 이렇게 했을까?
Go는 불필요한 문법적 복잡함을 줄이고,
개발자가 의도를 명확히 표현하는 데 집중하도록 하기 위해 이런 규칙을 제공해.
C나 C++은 이런 걸 직접 써야 해:
(*p).x // 혹은 p->x
Go는 그냥 p.x 쓰면 돼. 알아서 해석해줘.
🔍 예제로 다시 확인
type User struct {
name string
}
func main() {
u := User{name: "Alice"}
up := &u
fmt.Println(u.name) // ✅ 구조체 값
fmt.Println(up.name) // ✅ 구조체 포인터도 동일하게 접근 가능 (자동 역참조)
}
✅ 핵심 요약
| 대상 | 접근 방식 | 작동 방식 |
| 구조체 변수 | v.X | 직접 접근 |
| 구조체 포인터 | p.X | (*p).X로 자동 변환됨 |
| 구조체 포인터 | (*p).X | 직접 역참조 (가능하지만 생략 가능) |
👉 그래서 Go에선 .필드명 하나만 기억하면 돼.
그게 값이든 포인터든 걱정 없이 쓰면 Go가 알아서 처리해줘.
추가로 궁금한 예제나, 이 개념이 슬라이스, 맵, 구조체 배열에서 어떻게 적용되는지도 보여줄 수 있어!
궁금해? 😄
'언어 및 도구들 공부 > Go' 카테고리의 다른 글
| 빈 식별자, blank identifier, _ (0) | 2025.04.04 |
|---|---|
| Go) Unmarshal과 포인터 (0) | 2025.04.04 |
| Go 포인터 3 (0) | 2025.03.29 |
| Go 포인터 공부 2 (0) | 2025.03.29 |
| Go의 main 함수와 main 패키지 (0) | 2024.12.26 |