Skip to Content

入門Goプログラミング Lesson13(メソッド)から学んだこと

メソッド

新しい型の宣言

独自の型を定義、可読性と信頼性を向上させる
celsius(摂氏)型を宣言
この場合はfloat64と同じ振る舞い

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

import "fmt"

func main() {
	type celsius float64

	var temperature celsius = 30
	fmt.Println(temperature)

}

実行結果

30

memo
celsius型はユニークな型であり、型の別名ではない
そのため、celsius型float64を足すとエラーになる

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package main

import "fmt"

func main() {
	type celsius float64

	var temperature celsius = 30
	var warmUP float64 = 2
	temperature += warmUP
	fmt.Println(temperature)

}

コンパイルエラー

invalid operation: temperature += warmUP (mismatched types celsius and float64)

独自の型に変換すれば足せる
変換方法: celsius(xxx)

1
	temperature += celsius(warmUP)

信頼性という意味では、間違って比較したりすることを防止できる
celius型(摂氏)と、fahrenheit型(華氏)を誤って比較してみる

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
	type celsius float64
	type fahrenheit float64

	var c celsius = 30
	var f fahrenheit = 100

	if c == f {
		fmt.Println("同じ")
	}

}

コンパイルエラー

invalid operation: c == f (mismatched types celsius and fahrenheit)

関数で独自の型を使う

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

type celsius float64
type kelvin float64

// kelvin型で受け取り、celsius型で返す
func kelvinToCelsius(k kelvin) celsius {
	return celsius(k - 273.15) // 型の変換が必要
}

func main() {
	var k kelvin = 300.0
	c := kelvinToCelsius(k) // 関数はkelvin型でないと受け取れない

	fmt.Printf("%vKは、%v℃です", k, c)
}

実行結果

300Kは、26.850000000000023℃です

型振る舞いを加える

メソッドの呼び出し
適切な型の変数の後ろに、.メソッド名
関数とは異なり、受け取る型が違えば同じ名前のメソッド名は可能
下の.celsiusは受け取る値の型がkelvin型か、fahrenheit型によって振る舞いが異なる

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import "fmt"

type celsius float64
type kelvin float64
type fahrenheit float64

// 関数
func kelvinToCelsius(k kelvin) celsius {
	return celsius(k - 273.15)
}

// celsiusメソッド(kelvin型がきたら版)
func (s kelvin) celsius() celsius {
	return celsius(s - 273.15)
}

// celsiusメソッド(fahrenheit型がきたら版)
func (s fahrenheit) celsius() celsius {
	return celsius((s - 32.0) * 5.0 / 9.0)
}

func main() {
	var k kelvin = 300.0
	c := kelvinToCelsius(k) //関数を呼び出す

	fmt.Printf("%vKは、%v℃です\n", k, c)

	c2 := k.celsius() //メソッド(kelvin型を与え)を呼び出す
	fmt.Printf("%vKは、%v℃です\n", k, c2)

	var f fahrenheit = 100
	c3 := f.celsius() //メソッド(fahrentheit型を与え)を呼び出す
	fmt.Printf("%vFは、%v℃です\n", f, c3)

実行結果

300Kは、26.850000000000023℃です
300Kは、26.850000000000023℃です
100Fは、37.77777777777778℃です

メソッドに引数も渡せる

サンプルでは引数がなかったので試してみた

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main

import "fmt"

type celsius float64
type kelvin float64
type fahrenheit float64

// celsiusメソッド(kelvin型がきたら版)
func (s kelvin) celsius(test string) celsius {
	fmt.Println(test)
	return celsius(s - 273.15)
}

// celsiusメソッド(fahrenheit型がきたら版)
func (s fahrenheit) celsius(test string) celsius {
	fmt.Println(test)
	return celsius((s - 32.0) * 5.0 / 9.0)
}

func main() {
	var k kelvin = 300.0
	var f fahrenheit = 100
	argTest := "テスト"

	c2 := k.celsius(argTest) //メソッド(kelvin型を与え)を呼び出す
	fmt.Printf("%vKは、%v℃です\n", k, c2)

	c3 := f.celsius(argTest) //メソッド(fahrentheit型を与え)を呼び出す
	fmt.Printf("%vFは、%v℃です\n", f, c3)
}

実行結果

テスト
300Kは、26.850000000000023℃です
テスト
100Fは、37.77777777777778℃です

まとめ

  • 独自の型は可読性と、信頼性を向上させる
  • メソッドは型に関数を割り当てた感じ

感想

手を動かしてみるまで全然イメージ掴めなかったけど、 実際に書いてみると理解できた
便利で型によって振る舞いが変わるから変なエラーの防止(信頼性)にも繋がりそうだ

参考

なし