「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > レシーバー型 `T` の Go メソッドは型 `*T` の変数で呼び出すことができますか?

レシーバー型 `T` の Go メソッドは型 `*T` の変数で呼び出すことができますか?

2024 年 12 月 22 日に公開
ブラウズ:115

Can Go Methods with Receiver Type `T` Be Called on Variables of Type `*T`?

ポインター型の Go メソッド: ポインター型のレシーバー T を使用したメソッドの呼び出し *T

質問:

Go 仕様では、ポインタ型 T のメソッド セットには、対応する型 T のメソッド セットが含まれると記載されています。これは、型 T の変数に対してレシーバー T を使用してメソッドを呼び出すことができることを意味します?

Answer:

仕様ではこれを示唆していますが、次の点に注意することが重要です。 T 上で *T のメソッドを直接呼び出すことはできません。代わりに、コンパイラーは自動的に変数を &T に逆参照し、メソッドを呼び出して、効率的に実行します。 (&T).m().

この動作は Go 仕様で明示的に定義されています:

"Calls: メソッド呼び出し x.m() は、(の型のメソッド セットの場合に有効です) ) x に m が含まれており、引数リストを m のパラメータ リストに割り当てることができます。x がアドレス指定可能で、&x のメソッド セットに m が含まれている場合、x.m() は (&x).m() の短縮形です。 "

Demonstration:

次の例は、この動作を示しています:

package main

import (
    "fmt"
    "reflect"
)

type User struct{}

func (this *User) SayWat() {
    fmt.Println(reflect.TypeOf(this))
    fmt.Println("WAT\n")
}

func main() {
    var user = User{}

    fmt.Println(reflect.TypeOf(user))

    user.SayWat()
}

*User のレシーバーを使用して SayWat メソッドを宣言しているにもかかわらず、User 型の user でメソッドを呼び出すことができます。コンパイラは自動的に逆参照を処理し、(&user).SayWat().

Exception:

を呼び出します。ただし、これはアドレス指定可能な変数にのみ適用されます。アドレス指定できない値に対してポインター メソッドを呼び出そうとすると、エラーが発生します。例:

func aUser() User {
    return User{}
}

...

aUser().SayWat() // Error: cannot call pointer method on aUser()
でポインタ メソッドを呼び出すことができません
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3