2016-09-23 1 views
1

메소드를 첫 번째 인수가이 메소드의 구조체를 가리키는 포인터로 변환하는 이상한 코드를 읽었습니다.Golang의 구조체에 대한 포인터를 사용하여 함수로 메소드 변환

나는 그것을 입증하는 예를 쓰기 :

package main 

import "fmt" 

type fooS struct{} 

func (s *fooS) fooF(fooArg interface{}) { 
    fmt.Println("fooF: ", fooArg) 
} 

type wowS struct { 
    callback func(s *fooS, fooArg interface{}) 
} 

func main() { 
    wow := new(wowS) 
    wow.callback = (*fooS).fooF // strange 
    wow.callback(nil, 123) 
} 

Golang Playground Link

예제의 구문은 이상하다하지만 오류가 없습니다.

이 코드가 어떻게 작동하는지 나에게 공식적인 문서를 제공 할 수 있습니까?

감사 :)

답변

5

Method expressions는 :

MT에있어서 설정되어 있으면 T.M는 접두사 M 같은 인자 정규 함수 호출 인 함수 메소드의 수신자 인 추가 인수로

MethodExpr = ReceiverType "." MethodName . 
ReceiverType = TypeName | "(" "*" TypeName ")" | "(" ReceiverType ")" . 

수신기 형 *T이다 개의 수신기 형 T이다 방법 Mv, 및 Mp 가진 구조체 타입 T을 고려한다.

type T struct { 
    a int 
} 
func (tv T) Mv(a int) int   { return 0 } // value receiver 
func (tp *T) Mp(f float32) float32 { return 1 } // pointer receiver 

var t T 

발현

T.Mv 

Mv뿐만 첫 번째 인수로서 명시 수신기와 동등한 기능을 수득; 마찬가지로

t.Mv(7) 
T.Mv(t, 7) 
(T).Mv(t, 7) 
f1 := T.Mv; f1(t, 7) 
f2 := (T).Mv; f2(t, 7) 

표현식

(*T).Mp 

함수를 산출한다 : 너무 이 다섯 가지 호출은 동일하다, 즉, 기능이 명시 적으로 수신기에 일반적으로 호출 될 수있다

func(tv T, a int) int 

서명이 서명이있는 Mp를 나타내는 값

func(tp *T, f float32) float32 
값이 수신기와 방법

은, 하나는 명시 포인터 수신기 함수를 도출 할 수 있으므로

(*T).Mv 

는 서명

func(tv *T, a int) int 

이러한 기능 indirects를 Mv을 나타내는 함수 값을 산출 수신기를 통해 값을 생성하여 기본 메소드에 수신기로 전달합니다. 이 메서드는 주소가 함수 호출에서 전달 된 값을 덮어 쓰지 않습니다.

포인터 수신기 메서드가 값 형식의 메서드 집합에 없기 때문에 마지막 경우 인 포인터 수신기의 값 수신기 함수는 잘못된 형식입니다.

메서드에서 파생 된 함수 값은 함수 호출 구문과 함께 호출됩니다. 수신자는 호출의 첫 번째 인수로 제공됩니다. 즉, f := T.Mv이 주어진 경우 은 f(t, 7)이 아닌 t.f(7)으로 호출됩니다. 수신자를 바인드하는 함수를 작성하려면 함수 리터럴 또는 메소드 값을 사용하십시오.

인터페이스의 메소드 유형에서 함수 값을 유도하는 것이 타당합니다. 결과 함수는 해당 인터페이스 유형의 명시 적 수신자를 사용합니다.


그리고 참조 :
Go - difference between parameter and receiver
Is there a performance penalty for passing "this" by value in Go methods?
differences between pointer and value slice in for-range loop

관련 문제