[go] 함수 선언 구문 : 함수 이름 앞에 괄호 안에있는 것

질문 제목을 더 구체적으로 지정할 수 없어서 미안하지만 Go 코드를 읽고 있었고 다음 형식의 함수 선언이 발생했습니다.

func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    ...
}

에서 https://github.com/mattermost/platform/blob/master/api/context.go

func (s *GracefulServer) BlockingClose() bool {
    ...
}

에서 https://github.com/braintree/manners/blob/master/server.go

뭐라고합니까 (h handler)(s *GracefulServer)괄호의 평균 사이를? 괄호 안에있는 것들의 의미를 고려하여 전체 함수 선언은 무엇을 의미합니까?

편집하다

이것은 Go의 기능과 방법의 차이점은 무엇입니까? :이 질문은 함수 이름 앞에 괄호 안에있는 것이 무엇인지 알지 못했기 때문에 나에게 왔습니다. 함수와 메소드의 차이점이 무엇인지 궁금해했기 때문이 아닙니다 …이 선언이 메소드라는 것을 알고 있다면 처음부터이 질문을했습니다. 누군가 언젠가 나와 같은 의심을 품고 있다면 이것이 사실인지 알지 못하기 때문에 “골랑 방법”을 검색하리라고 믿지 않습니다. 그것은 “시그마”라는 문자가 수학적 표현 이전에 의미가 무엇인지 궁금해하는 것과 같을 것입니다 (누름을 의미하지는 않음). 누군가 그것이 합계와 다른 것의 차이점이 중복된다고 말합니다.

또한이 질문에 대한 짧은 대답 ( “수신자”)은 “함수와 방법의 차이점”에 대한 답이 아닙니다.



답변

이것을 ‘수신자’라고합니다. 첫 번째 경우 (h handler)에는 값 유형이고 두 번째 (s *GracefulServer)경우에는 포인터입니다. Go에서 작동하는 방식은 다른 언어와 약간 다를 수 있습니다. 그러나 수신 유형은 대부분의 객체 지향 프로그래밍에서 클래스처럼 작동합니다. 메소드를 A클래스에 추가 하면 호출 할 Person유형의 인스턴스가 필요합니다 (정적이 아닌 인스턴스 메소드라고 가정).PersonA

여기서 한 가지 단점은 수신자가 다른 인수와 마찬가지로 호출 스택에 푸시되므로 수신자가 값 유형 인 경우와 같이 handler메소드를 호출 한 것의 사본을 작업하는 것 h.Name = "Evan"입니다. 호출 범위로 돌아간 후에도 지속되지 않습니다. 이러한 이유로 수신기의 상태를 변경하려는 경우 포인터를 사용하거나 수정 된 값을 반환해야합니다 (원하는 경우 불변 유형 패러다임을 더 제공함).

다음은 스펙의 관련 섹션입니다. https://golang.org/ref/spec#Method_sets


답변

ServeHTTP독립형 기능이 아님을 의미 합니다. 함수 이름 앞의 괄호는 이러한 함수가 작동 할 오브젝트를 정의하는 이동 방법입니다. 따라서 기본적으로 ServeHTTP핸들러 유형의 메소드이며 핸들러 유형의 h와 같은 오브젝트를 사용하여 호출 할 수 있습니다.

h.ServeHTTP(w, r)

또한 수신자라고도합니다. 그들을 정의하는 두 가지 방법이 있습니다. 수신기를 수정하려면 다음과 같은 포인터를 사용하십시오.

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

수신자를 수정할 필요가없는 경우 수신자를 다음과 같은 값으로 정의 할 수 있습니다.

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

Go 놀이터 의이 예는 개념을 보여줍니다.

package main

import "fmt"

type Mutatable struct {
    a int
    b int
}

func (m Mutatable) StayTheSame() {
    m.a = 5
    m.b = 7
}

func (m *Mutatable) Mutate() {
    m.a = 5
    m.b = 7
}

func main() {
    m := &Mutatable{0, 0}
    fmt.Println(m)
    m.StayTheSame()
    fmt.Println(m)
    m.Mutate()
    fmt.Println(m)

위 프로그램의 출력은 다음과 같습니다.

&{0 0}
&{0 0}
&{5 7}


답변