1. ホーム
  2. 行く

[解決済み】関数宣言の構文:関数名の前に括弧でくくられたもの

2022-03-24 12:50:33

質問

質問のタイトルが具体的でなくて申し訳ないのですが、私が読んでいたのは、いくつかの 行く のコードで、このような形式の関数宣言に遭遇しました。

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の関数とメソッドの違いは何ですか? この宣言がメソッドだとわかっていたら、こんな疑問は抱かなかったでしょう。もし、ある日、私と同じ疑問を持った人がいたとしても、それがわからないからと言って、"golang methods"と検索してくるとは思えません。それは、数学の式の前にある "sigma" という文字が何を意味するのか疑問に思って(それが和を意味するとは知らずに)、誰かが和と他のものの違いは何かと重複して言うようなものでしょう。

また、この質問に対する短い答え("それは受信機です")は、"関数とメソッドの違いは何ですか"に対する答えではありません。

どのように解決するのですか?

これを「レシーバー」と呼びます。最初の場合 (h handler) は値型であり、2番目の (s *GracefulServer) はポインタです。Goでの動作は、他の言語とは少し異なるかもしれません。しかし、受信型は、ほとんどのオブジェクト指向プログラミングにおけるクラスのように多かれ少なかれ機能します。これはメソッドを呼び出す元となるものです。 A あるクラスの内部 Person という型のインスタンスが必要です。 Person を呼び出すために A (静的ではなくインスタンスメソッドであると仮定して!)。

ここで一つ厄介なのは、Receiverは他の引数と同様にコールスタックにプッシュされるので、Receiverが値型である場合、例えば handler のように、メソッドを呼び出したもののコピーで作業することになります。 h.Name = "Evan" は、呼び出し元のスコープに戻った後、持続しない。このため、受信機の状態を変更しようとする場合は、ポインタを使用するか、変更後の値を返す必要があります(もしそれを望むなら、より不変の型のパラダイムを提供します)。

以下は、仕様書の該当部分である。 https://golang.org/ref/spec#Method_sets