인스턴스 복사 시 포인터 수신기의 중요성
데이터를 조작할 때 참조 또는 값으로 값을 전달하는 미묘한 차이를 이해하는 것이 중요합니다. Go에서 메서드는 값 또는 포인터 수신기로 정의될 수 있으며, 특히 인스턴스를 복사할 때 이 선택의 의미를 이해하는 것이 중요합니다.
값 수신기
값 수신자가 있는 메서드는 수신한 값의 복사본에서 작동합니다. 메서드 내에서 수정한 사항은 원래 값에 영향을 주지 않습니다. 이렇게 하면 복사된 인스턴스에 대한 호출 메서드가 원본 데이터를 손상시키지 않게 됩니다.
포인터 수신기
반대로, 포인터 수신기가 있는 메서드를 사용하면 원래 값에 직접 액세스하고 수정할 수 있습니다. . 이러한 방법은 데이터를 변형시킬 가능성이 있으며, 이로 인해 미묘하고 의도하지 않은 부작용이 발생할 수 있습니다. 포인터 수신기를 사용하여 인스턴스를 복사하면 원본 데이터와 복사된 데이터 사이에 불일치가 발생할 위험이 있습니다.
예: Wrapper Struct
이 문제를 설명하려면 Wrapper라는 유형을 고려하세요. v(값) 및 p(값에 대한 포인터) 필드 포함:
type Wrapper struct {
v int
p *int
}
포인터 수신기가 있는 Set() 메서드는 v와 지정된 값을 모두 수정합니다.
func (w *Wrapper) Set(v int) {
w.v = v
*w.p = v
}
Wrapper 인스턴스가 있다고 가정합니다. a:
a := Wrapper{v: 0, p: new(int)}
Calling Set() a에서는 v와 *p를 모두 수정합니다.
a.Set(1)
이제 a를 복사하여 b를 생성하면 두 인스턴스 모두 일관된 값을 가질 것으로 예상됩니다. :
b := a
그러나 Set()을 사용하여 a에 대한 후속 수정은 포인터 p 복사로 인해 b로 전파되지 않으며 결과적으로 일관성 없는 데이터가 발생합니다.
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
a.Set(1)
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
출력:
a.v=0, a.p=0; b.v=0, b.p=0 a.v=1, a.p=1; b.v=0, b.p=1
결론
포인터 수신기가 있는 메서드가 있는 유형을 처리할 때 데이터 불일치를 방지하기 위해 인스턴스 복사를 피하는 것이 중요합니다. 대신 동일한 기본 데이터를 참조하는 모든 인스턴스에 수정 사항이 반영되도록 포인터 값을 조작하세요.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3