>백엔드 개발 >Golang >값 수신자 메서드 내에서 Go 구조체의 필드를 수정해도 지속되지 않는 이유는 무엇입니까?

값 수신자 메서드 내에서 Go 구조체의 필드를 수정해도 지속되지 않는 이유는 무엇입니까?

DDD
DDD원래의
2024-12-13 03:17:13634검색

Why Doesn't Modifying a Go Struct's Field Within a Value Receiver Method Persist?

값 수신기를 통한 구조체 수정: 그림자 효과 이해

Go에서는 메서드 수신기의 동작이 가변성에 큰 영향을 미칠 수 있습니다. 구조체의. 값 수신자와 포인터 수신자의 차이점을 이해하는 것은 구조체를 올바르게 조작하는 데 중요합니다.

문제 컨텍스트

제공된 예는 예상치 못한 동작을 보여줍니다. 구조체의 필드는 메서드 내에서 수정되지만 메서드 외부에서는 수정 사항이 유지되지 않습니다.

type Test struct {
    someStrings []string
}

func (this Test) AddString(s string) {
    this.someStrings = append(this.someStrings, s)
    this.Count() // will print "1"
}

func (this Test) Count() {
    fmt.Println(len(this.someStrings))
}

이 코드가 실행되면 다음이 인쇄됩니다.

1
0

이 동작이 발생합니다. AddString 메서드는 메서드가 호출될 때 본질적으로 구조체의 복사본을 생성하는 값 수신기를 사용하기 때문입니다. 메서드 내에서 수정된 사항은 원본 구조체가 아닌 이 복사본에 적용됩니다. 결과적으로 Count가 메서드 외부에서 호출되면 수정되지 않은 원래 구조체에서 작동합니다.

포인터 수신기와 값 수신기

이 문제를 해결하려면 포인터 값 수신기 대신 수신기를 사용해야 합니다. 포인터 수신기는 원본 구조체에 대한 참조를 생성하여 직접적인 조작이 가능합니다.

func (t *Test) AddString(s string) {
    t.someStrings = append(t.someStrings, s)
    t.Count() // will print "1"
}

포인터 수신기를 사용하면 AddString 메서드가 수신기의 구조체에서 직접 작동합니다. 따라서 someStrings에 대한 수정 사항은 원래 구조체에 반영됩니다. 결과적으로 Count가 메서드 외부에서 호출되면 수정된 구조체에서 작동합니다.

결론

값 수신기와 포인터 수신기의 차이점을 이해하면 Go에서 구조체를 효과적으로 조작할 수 있습니다. 값 수신기는 복사본을 생성하는 반면 포인터 수신기는 원본 구조체에 대한 직접 액세스를 제공합니다. 이 미묘한 차이는 메서드 내에서 변경된 사항이 해당 메서드 외부에서도 지속되도록 하는 데 중요합니다.

위 내용은 값 수신자 메서드 내에서 Go 구조체의 필드를 수정해도 지속되지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.