モジュール 5 · レッスン 2 / 5コース内の 22/50~14 min
モジュールのレッスン (2/5)
メソッド: 値とポインター レシーバー
Go の メソッド は レシーバー を備えた関数です。つまり、特別な
func とメソッド名の間で宣言されたパラメーター。
メソッドを型に変換します。クラスはありません: メソッドは定義できます
現在のパッケージで宣言されている名前付き型。
構文
Go
type Person struct {
Name string
}
func (p Person) Greet() string {
return "ciao " + p.Name
}
p := Person{Name: "Ada"}
fmt.Println(p.Greet()) // "ciao Ada"レシーバー p Person は、Greet を Person のメソッドにします。内部
メソッド p は、他の変数と同様の変数です。
値レシーバーとポインターレシーバー
Go
// VALUE receiver: operates on a COPY of the value
func (p Person) NameUpper() string {
return strings.ToUpper(p.Name)
}
// POINTER receiver: operates on the original value, can mutate it
func (p *Person) Rename(n string) {
p.Name = n
}ポインタ レシーバを使用すると、レシーバを変更し、その変更を行うことができます メソッドの外側から見ることができます。値レシーバーを使用すると、次のことはできません。 ローカルコピーのみを変更してください。
Go
p := Person{Name: "Ada"}
p.Rename("Grace")
fmt.Println(p.Name) // "Grace" — change is visibleポインターレシーバーを使用する場合
実際のルールを優先順位順に示します。
- レシーバーを変更する必要があります → ポインタ レシーバー。必須。
- 構造体が大きい (数十のフィールド、内部に配列) → ポインタ 高価なコピーを避けるための受信機。
- 一貫性: 型の少なくとも 1 つのメソッドにポインター レシーバーがある場合、次を使用します。 他のものに対するポインタ受信機も同様です。にとって非常に重要な大会 インターフェイス (モジュール 6)。
- 小さく、不変の、「値」型 (time.Time、複素数、小さい) 構造体) → 値レシーバー、より読みやすくなります。
非構造体型のメソッド
パッケージ内で宣言された任意の NAMED 型に対してメソッドを定義できます。
Go
type Celsius float64
func (c Celsius) ToFahrenheit() float64 {
return float64(c)*9/5 + 32
}
t := Celsius(20)
fmt.Println(t.ToFahrenheit()) // 68他のパッケージの型 (int、string など) にそれらを定義することはできません。
まずローカルの名前付き型を作成します。
試してみてください
運動#go.m5.l2.e1
試行回数: 0読み込み中…
「ciao <Name>」を返す Greet() 文字列メソッド (値受信者) を Person に追加します。
エディターを読み込み中…
ヒントを表示
メソッド名の前のかっこ内のレシーバー。
3 回の試行後に解決策が利用可能になります
運動#go.m5.l2.e2
試行回数: 0読み込み中…
p.Name を変更する POINTER レシーバーを備えた Rename(n string) メソッドを追加します。
エディターを読み込み中…
ヒントを表示
ポインタ受信者: `(p *人)`。
3 回の試行後に解決策が利用可能になります
Quiz#go.m5.l2.e3
準備完了ポインタ レシーバ (p *T) を使用する必要があるのはどのような場合ですか?
Go
func (t ?T) M() { ... }要約
- メソッド = レシーバーを備えた関数:
func (r T) Name(...) ... { ... }。 - 値レシーバ: コピーに対して動作します。ポインタ受信機: オリジナルで動作します。
- Go は呼び出しサイトで
T↔*T変換を自動的に実行します。 - ポインター レシーバーの場合: 突然変異 + 大きな構造体 + この型の他のメソッドとの一貫性。
- 同じ型で値レシーバーとポインター レシーバーを決して混在させないでください。
- メソッドは、現在のパッケージ (非構造体を含む) 内の NAMED 型に適用されます。