>백엔드 개발 >Golang >Go 구조체의 포인터: 언제, 왜 사용해야 합니까?

Go 구조체의 포인터: 언제, 왜 사용해야 합니까?

Susan Sarandon
Susan Sarandon원래의
2024-12-15 20:27:18183검색

Pointers in Go Structs: When and Why Should I Use Them?

구조체 필드의 포인터 사용: 의미 및 장단점 ​​해결

제공한 코드 조각에 설명된 구조체 필드의 포인터 활용 , 값 필드를 사용하는 것에 비해 미묘하면서도 중요한 의미를 가져올 수 있습니다. 이러한 파급 효과를 이해하는 것은 Go에서 구조체 디자인에 대해 현명한 결정을 내리는 데 중요합니다.

구조체 정의

포인터는 형식 앞에 별표(*)가 붙어 있습니다. 구조체 필드 정의. 이러한 필드는 값을 직접 보유하는 대신 실제 값을 가리킵니다.

//With pointers
type Employee struct {
    FirstName *string
    Salary    *int
    FullTime  *bool
}

//Without pointers (value fields)
type EmployeeV struct {
    FirstName string
    Salary    int
    FullTime  bool
}

JSON 마샬링 및 역마샬링

JSON 인코딩/디코딩을 사용할 때 포인터 필드는 omitempty 태그를 사용하면 명시적으로 설정된 필드와 JSON 데이터에 없는 필드를 구별할 수 있습니다. 예:

type Foo struct {
    Bar string  `json:"bar"`
    Foo *string `json:"foo,omitempty"`
}

Foo 필드 없이 JSON에서 Foo를 역마샬링하면 Foo.Foo는 nil이 됩니다. 반대로 0과 같은 0 값을 사용하면 Foo.Foo는 해당 값이 있는 정수를 가리킵니다.

메서드 수신기

포인터에는 장점이 있지만 잠재력도 있습니다. 함정. 그러한 함정 중 하나는 포인터 필드를 수정하는 메서드에 값 수신기를 사용할 때입니다.

//Employee with pointer in struct field
func (e Employee) SetName(name string) {
    e.FirstName = &name //This works only if FirstName is not nil
}

//EmployeeV with value field
func (e EmployeeV) SetName(name string) {
    e.FirstName = name //This never works
}

이 문제를 피하려면 포인터 필드를 수정하는 메서드에 포인터 수신기를 사용하세요.

type Employee struct {
    FirstName string
}

func (e *Employee) SetName(name string) {
    e.FirstName = name //This always works
}

동시성 및 데이터 경합

포인터와 관련된 또 다른 위험은 여러 개의 포인터가 있을 때 데이터 경합입니다. 루틴은 동일한 공유 데이터에 액세스합니다. 다음 예를 고려하십시오.

type Employee struct {
    FirstName *string
}

func main() {
    n := "name"
    e := Employee{FirstName: &n}

    go func() {
        *e.FirstName = "foo"
    }()

    //Race condition where multiple routines access and modify e.FirstName concurrently
}

데이터 경합을 방지하려면 동기화 프리미티브와 같은 기술을 사용하여 공유 포인터에 대한 액세스를 동기화하세요.

메모리 고려 사항

메모리 사용량 측면에서 정수 및 부울과 같은 개별 필드는 메모리 소비에 큰 영향을 미치지 않습니다. 그러나 더 큰 구조체의 경우 구조체에 포인터를 전달하는 것이 메모리 효율적일 수 있습니다. 그러나 포인터를 통해 값에 액세스하면 추가적인 간접 오버헤드가 발생합니다.

결론적으로 구조체 필드의 포인터는 필드 부재와 0 값을 구별하는 등 특정 이점을 제공할 수 있지만 잠재적인 위험을 신중하게 고려하는 것이 중요합니다. , 수신기 유형, 데이터 경합 및 메모리 영향을 포함합니다. 이러한 개념을 이해하면 Go 구조체에서 포인터 필드를 사용할 때 정보를 바탕으로 선택하는 데 도움이 됩니다.

위 내용은 Go 구조체의 포인터: 언제, 왜 사용해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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