메서드 식

M이 타입 T메서드 집합 중 하나라면, T.M은 같은 인자를 가진 일반적인 함수처럼 호출할 수 있는 함수이며, 이때 M 뒤에는 추가적인 인자인 메서드의 수신자(receiver)가 위치한다.

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

2개의 메서드가 있는 struct 타입 T 에서 Mv 메서드는 T 타입의 수신자, Mp 메서드는 *T 타입의 수신자를 가지고 있다.

type T struct {
    a int
}
func (tv  T) Mv(a int) int         { return 0 }  // 값 수신자
func (tp *T) Mp(f float32) float32 { return 1 }  // 포인터 수신자

var t T

아래 식은

T.Mv

명시적으로 수신자를 첫번째 인자로 가진다는 차이만 있을 뿐 Mv 와 동일한 함수가 된다; 이 함수의 시그니처는 다음과 같다.

func(tv T, a int) int

이 함수는 명시적으로 수신자를 사용해 정상적으로 호출할 수 있기 때문에, 아래의 5개 호출은 같은 것이다:

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

아래와 같은 시그니처를 가진 Mp를 나타내는 함수 값(function value)이 된다.

func(tp *T, f float32) float32

값 수신자를 가진 메서드는 명시적으로 포인터 수신자를 가진 함수를 제공할 수 있기 때문에

(*T).Mv

는 아래의 시그니처를 가진 Mv를 나타내는 함수 값이 된다.

func(tv *T, a int) int

이러한 함수는 내재 메서드에 대한 수신자처럼 전달할 값을 생성하기 위해 수신자를 통해 참조된다; 이 메서드는 함수 호출에서 전달된 주소에 있는 값을 겹쳐쓰지 않는다.

마지막으로 포인터 수신자를 가진 메서드에 대한 값 수신자 함수는 허용되지 않는다. 그 이유는 포인터 수신자 메서드가 값 타입의 메서드 집합에 포함되어 있지 않기 때문이다.

메서드로부터 파생된 함수 값들은 함수 호출 문법을 통해 호출된다; 호출시 수신자가 첫번째 인자로 제공된다. 즉, f := T.Mv에 대해, ft.f(7) 가 아니라 f(t, 7) 와 같은 형태로 호출된다. 수신자와 관련된 함수를 만들려면, 함수 리터럴이나 메서드 값을 사용하라.

인터페이스 타입의 메서드에서 함수 값을 만드는 것은 허용된다. 그 결과로 나오는 함수는 해당 인터페이스 타입의 명시적인 수신자를 인자로 갖는다.

results matching ""

    No results matching ""