オブジェクト指向言語では
関数
- オブジェクト関係なく、呼ぶと何か処理をする
プログラムの部品
メソッド
- オブジェクト指向で登場する用語で、
オブジェクトの動作を定義したもの
らしい。
golangはオブジェクト指向??
- golangを勉強し始めて1週間。
- 今まで、同義的に使っていたメソッドと関数という言葉・・・
- golangがオブジェクト指向なのかはよくわからない(オブジェクト指向言語としてGolangをやろうとするとハマること)けど、まとめてみたらオブジェクト指向言語っぽく使えることを理解した。
- とにかく、関数とメソッドは明確に違いがあるらしいとのことでまとめてみた
- 諸先輩方、認識が違ったらご指摘お願いいたします。
- ※比較しやすいよう同じ処理をする
関数
-
func
で始まる処理の塊の中で構造体(型)に紐づけられていないもの
main.go
type Square struct {
X, Y int
}
func Area(s Square) int {
return s.X * s.Y
}
func main() {
s := Square{5, 5}
fmt.Println(Area(s)) // >>25
}
メソッド
- 構造体(型)に紐づく処理の塊
-
Area(s Square)
の部分が↑の型に紐づく
を実装している部分 - こうすることで
Area
は構造体:Square
の持ち物となり、s.Area()
として呼び出すことができる。これがメソッド。 - この紐づけた構造体(型)のことを
レシーバ(receiver)
と呼ぶらしい。
main.go
type Square struct {
X, Y int
}
func (s *Square) Area() int {
return s.X * s.Y
}
func main() {
s := Square{5, 5}
fmt.Println(s.Area()) // >>25
}
ポインタレシーバ
- ↑の
レシーバ
を使用して実態を書き換えることをポインタレシーバ
と呼ぶらしい。耳なじみのある言い方で言うと参照渡し
。 - 例えば、SquareのArea()の前にSquareを拡張する
Scale
というメソッドを用意してみる。実態が変わるため出力は2500
となる。 -
(s *Square) Scale
の部分のアスタリスク(*)を削除すると値レシーバ(値渡し)
となり出力は25
となるのでコチラでこのソースをコピペして試してみてください。
main.go
type Square struct {
X, Y int
}
func (s Square) Area() int {
return s.X * s.Y
}
func (s *Square) Scale(i int) {
s.X = s.X * i
s.Y = s.Y * i
}
func Area(s Square) int {
return s.X * s.Y
}
func main() {
s := Square{5, 5}
s.Scale(10)
fmt.Println(s.Area()) // >> 2500
}
- とりあえず、関数とメソッドの違いでした。