2010-05-02 4 views

답변

5

type bar의 변수를 선언하거나 할당하면 rd uint8foo foo_ 모두에 대해 메모리를 예약하고 초기화합니다. type foo_의 변수 중 하나는 항상 변수 type bar에 임베드됩니다. 당신이 선언하거나 type barP의 변수를 할당하는 경우

var b bar // declare b 

, 당신은 예약과 rd uint8foo *foo_ 모두 제로 메모리 초기화합니다. 0 값 포인터는 nil 포인터입니다. type foo_의 변수가 할당되지 않습니다. 당신은 별도로해야합니다. 0 (foo == nil) 또는 type foo_의 변수 중 하나가 type barP이라는 변수로 지정됩니다. type barP의 변수는 다른 변수가 인 type foo_의 동일 변수를 가리킬 수 있으며, 변수의 동일한 사본은 type foo_입니다. 공유 사본에 대한 변경 사항은 공유 사본을 가리키는 모든 변수에서 볼 수 있습니다. 사용하는 하나의

var bp barP   // declare bp 
bp.foo = new(foo_) // allocate bp.foo 

type barPtype bar의 특성에 따라 달라집니다. 어떤 유형이 당신이 해결하려고하는 문제를 더 잘 반영하고 있습니까?

예를 들어,이 송장 문제를 고려해보십시오. 우리는 항상 청구서 수신 주소가 있습니다. 우리는 항상 돈을 요구할 것입니다. 그러나 청구서 수신 주소로 발송하는 경우가 있지만 항상 그렇지는 않습니다. 배송 주소가 nil 인 경우 청구서 수신 주소를 사용하십시오. 그렇지 않으면 별도의 운송 주소를 사용하십시오. 우리는 두 개의 창고를 보유하고 있으며 항상 하나 또는 다른 창고에서 출하합니다. 두 개의 창고 위치를 공유 할 수 있습니다. 주문이 창고에서 배송 될 때까지 인보이스를 보내지 않으므로 창고 위치는 결코 nil이 아닙니다.

type address struct { 
    street string 
    city string 
} 

type warehouse struct { 
    address string 
} 

type invoice struct { 
    name  string 
    billing address 
    shipping *address 
    warehouse *warehouse 
} 
2

답변은 언어와는 크게 관련이 없습니다. C의 동일한 문제는 동일한 문제가 있습니다.

값이 내장되어 있으면 (bar처럼) 구조는 전체 하위 구조와 다른 부분을 보유 할만큼 충분히 큽니다.

barP과 같은 값에 대한 포인터가 있으면 barP 유형의 구조가 동일한 foo을 공유 할 수 있습니다. barP 중 하나가 foo의 일부를 수정하면 동일한 위치를 가리키는 다른 모든 barP 구조에 영향을줍니다. 또한 주석에서 알 수 있듯이 barPfoo이라는 두 개의 개별 객체를 일반 bar 유형과 대조하여 관리해야합니다.

일부 언어에서는 포인터가 매달 리거나 초기화되지 않은 값 등이 있는지 걱정해야합니다. Go는 가비지 수집되며 일반적으로 다른 언어보다 더 형식 안전합니다.

따라서 복수 barP 개체가 동일한 foo 개체를 공유하도록하려면 포인터를 사용하십시오. 그렇지 않으면 개체에 대한 포인터가 아니라 명시 적 멤버 개체를 사용하십시오.

+1

'type barP'의 변수가 선언되거나 할당되면, foo의 초기 값은'nil' 포인터가됩니다. – peterSO

2

Golang FAQ 지금의 차이를 요약

func (s *MyStruct) pointerMethod() { } // method on pointer 
func (s MyStruct) valueMethod() { } // method on value 

먼저, 그리고 가장 중요한, 방법은 수신기을 수정해야합니까?
그렇다면 수신기는 포인터 여야합니다. 슬라이스와 맵은 참조 유형이므로 해당 스토리는 좀 더 미묘합니다. 예를 들어 메서드에서 슬라이스의 길이를 변경하려면 수신기가 여전히 포인터 여야합니다.
pointerMethod이 필드가 s이면 호출자는 이러한 변경 사항을 볼 수 있지만 호출자의 인수 사본 (값 전달의 정의)을 사용하여 valueMethod이 호출되므로 호출자가 변경할 수 없습니다.
그런데 포인터 수신기는 자바의 상황과 동일합니다. 자바에서는 포인터가 커버 아래에 숨겨져 있습니다. 평범한 Go의 가치있는 수신기입니다.

두 번째는 효율성입니다. 수신기가 큰 경우, 예를 들어 큰 구조체 인 경우 포인터 수신기를 사용하는 것이 훨씬 저렴합니다.

이 (효율이 지점은 또한 " Memory, variables in memory, and pointers"에 도시되어있다)

다음 일관성이다. 유형의 메소드 중 일부가 포인터 수신자를 가져야하는 경우 나머지도 있어야하므로 유형 세트 사용 방법에 관계없이 메소드 세트가 일관됩니다. 자세한 내용은 method sets 섹션을 참조하십시오.

관련 문제