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


249

질문 제목을 더 구체적으로 지정할 수 없어서 미안하지만 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의 기능과 방법의 차이점은 무엇입니까? :이 질문은 함수 이름 앞에 괄호 안에있는 것이 무엇인지 알지 못했기 때문에 나에게 왔습니다. 함수와 메소드의 차이점이 무엇인지 궁금해했기 때문이 아닙니다 ...이 선언이 메소드라는 것을 알고 있다면 처음부터이 질문을했습니다. 누군가 언젠가 나와 같은 의심을 품고 있다면 이것이 사실인지 알지 못하기 때문에 "골랑 방법"을 검색하리라고 믿지 않습니다. 그것은 "시그마"라는 문자가 수학적 표현 이전에 의미가 무엇인지 궁금해하는 것과 같을 것입니다 (누름을 의미하지는 않음). 누군가 그것이 합계와 다른 것의 차이점이 중복된다고 말합니다.

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


27
@Volker는 스택 오버 플로우에있는 Go 사람들이 Tour of Go에없는 질문에 대해서만 답변한다고 부인합니다. Haskell 커뮤니티에서 사람들은 Haskell의 목록에서 요소를 얻는 방법n 과 같은 질문을 할 수 있습니다 . , 소개에 나와 있습니다. 대단한 이익을위한 하스켈 학습에 대한 소란없이 질문에 대한 답변을 얻으십시오.
Marcus Vinícius Monteiro

23
이 질문이 있었을 때, 나는 먼저 Go Tour에 갔다. 모든 "함수"제목을 확인했지만이 중 어떤 예제도 다루지 않았습니다. tour.golang.org/basics/4 tour.golang.org/basics/5 메소드와 인터페이스를 확장하는 방법을 모르면 "메소드가 함수입니다"라는 제목이 표시되지 않습니다. 이 질문은 Google 색인 생성에 유효하고 훌륭합니다. 중복 깃발 열광이 밝아 져야합니다.
Bruno Bronosky

14
답변을 찾는 데 도움이 되었기 때문에 귀하의 질문에 구체적이지 않은 것에 감사드립니다!
David K

1
당신은 내가 찾은 것을 정확하게 물었습니다. 감사합니다. 모든 종류의 함수 정의를 읽었으며 아무도 이것을 설명하지 않았습니다. 나는 여전히 내 nube 질문을 작성하려고 시도하고 이것을 찾았습니다.
Ajak6

답변:


200

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

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

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


6
관련 사양에 연결하기위한 좋은 설명과 추가 카르마 포인트
Marius Waldal

4
golang 둘러보기에도 유용한 예제가 있습니다. tour.golang.org/methods/1
tw_hoff

90

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}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.