値レシーバ
CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 7/68。
値レシーバを使用してメソッドを定義すると、そのメソッドはオリジナルのインスタンスではなく、構造体インスタンスのコピーに対して動作します。これは、メソッド内でレシーバに対して行われた変更が、元の構造体変数には影響を与えないことを意味します。
type Counter struct {
Value int
}
func (c Counter) increment() {
c.Value++ // これはコピーを変更するもので、オリジナルは変更されません
}この例では、increment メソッドは値レシーバ (c Counter) を持っています。Counter インスタンスに対してこのメソッドを呼び出すと、Go は構造体のコピーを作成し、それをメソッドに渡します。メソッド内での c.Value に対する変更は、このコピーにのみ影響します。
値レシーバは、メソッドが構造体を変更せずにデータを読み取るだけでよい場合に便利です。元のデータが変更されないことが保証されるため、安全に使用でき、コードの予測可能性が高まり、意図しない副作用を防ぐことができます。
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
チャレンジ
簡単このチャレンジでは、シンプルな温度監視システムを作成することで、値レシーバ(value receiver)の扱いを練習します。Sensor構造体を作成し、値レシーバが構造体のコピーに対してどのように機能するかを示すメソッドを定義します。
3つの入力を受け取ります:
- センサーIDを表す文字列(例:
"TEMP001") - 現在の温度の読み取り値を表す文字列(例:
"23.5") - 温度調整値を表す文字列(例:
"2.0")
あなたのタスクは以下の通りです:
- 2つのフィールドを持つ
Sensor構造体を定義します:ID(string)とTemperature(float64) "Sensor [ID]: [temperature]°C"という形式でセンサー情報を出力する、値レシーバを持つdisplayReadingメソッドを作成します。- 温度に調整値を加え、
"Adjusted reading: [new_temperature]°C"と出力する、値レシーバを持つadjustTemperatureメソッドを作成します。 - 入力をパースして
Sensorインスタンスを作成します。 displayReadingメソッドを呼び出して、元の温度を表示します。- 調整値を引数に指定して
adjustTemperatureメソッドを呼び出します。 - 再度
displayReadingメソッドを呼び出し、元の構造体が変更されていないことを示します。
このチャレンジは、値レシーバを持つメソッドが構造体のコピーに対して動作するため、adjustTemperatureメソッドを呼び出した後でも元の構造体の温度値が変更されないことを証明します。温度値は小数点以下1桁の精度で表示してください。
チートシート
値レシーバは、元のインスタンスではなく、構造体インスタンスのコピーに対して動作します。メソッド内で行われた変更は、元の構造体には影響しません。
type Counter struct {
Value int
}
func (c Counter) increment() {
c.Value++ // これはコピーを変更するものであり、オリジナルは変更しません
}値レシーバは、メソッドが元の構造体を変更せずにデータを読み取るだけでよい場合に便利であり、コードの予測可能性を高め、意図しない副作用を防ぐことができます。
自分で試してみよう
package main
import (
"fmt"
"strconv"
)
// TODO: ここで Sensor 構造体を定義してください
// TODO: ここで値レシーバを持つ displayReading メソッドを定義してください
// TODO: ここで値レシーバを持つ adjustTemperature メソッドを定義してください
func main() {
// 入力を読み込む
var sensorID string
var tempStr string
var adjustStr string
fmt.Scanln(&sensorID)
fmt.Scanln(&tempStr)
fmt.Scanln(&adjustStr)
// 温度と調整値をパースする
temperature, _ := strconv.ParseFloat(tempStr, 64)
adjustment, _ := strconv.ParseFloat(adjustStr, 64)
// TODO: Sensor インスタンスを作成し、必要なメソッドを呼び出してください
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。