Closed2

Go言語のレシーバってやつはどんな時に使うのがよいのか考えたメモ( func ("ここに構造体") f() )

eisukeeisuke

レシーバって何?

これ

// Personという名前の構造体を定義
type Person struct {
    FirstName string
    LastName  string
}

// 関数の名前の前に構造体を入れる引く数のようなものがあるやつ。
// これがレシーバ
func (p Person) greet() {
    fmt.Printf("Hello, my name is %s %s.\n", p.FirstName, p.LastName)
}

func main() {
    // Person構造体のインスタンスを生成
    var p Person = Person{
        FirstName: "John",
        LastName:  "Doe",
    }

    // greetメソッドを呼び出す
    // これで実行できる
    p.greet()  // "Hello, my name is John Doe."と出力されます
}

自分なりに解釈してみる

構造体を利用したり中身を変更するときに使うやつ。
これだけだと普通に構造体を宣言し値ごとに代入したり取得して通常の関数の引数に持ってきたりして扱えるやんと思いました。

// 関数
func greet(p Person) {
    fmt.Printf("Hello, my name is %s %s.\n", p.FirstName, p.LastName)
}

// メソッド
func (p Person) greet() {
    fmt.Printf("Hello, my name is %s %s.\n", p.FirstName, p.LastName)
}

そう、なくても良いものではある。

ただ大きなプロジェクトだったり、意識して読みやすいコードを目指すとなるとやっぱり必要になりそうです!

見やすさ比較

関数だけ

type Circle struct {
    Radius float64
}

type Rectangle struct {
    Width, Height float64
}

func AreaOfCircle(c Circle) float64 {
    return math.Pi * c.Radius * c.Radius
}

func AreaOfRectangle(r Rectangle) float64 {
    return r.Width * r.Height
}

func main() {
    c := Circle{Radius: 5}
    r := Rectangle{Width: 3, Height: 4}
    fmt.Println("Area of Circle:", AreaOfCircle(c))
    fmt.Println("Area of Rectangle:", AreaOfRectangle(r))
}

レシーバを使った場合

package main

import (
    "fmt"
    "math"
)

type Circle struct {
    Radius float64
}

type Rectangle struct {
    Width, Height float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func main() {
    c := Circle{Radius: 5}
    r := Rectangle{Width: 3, Height: 4}
    fmt.Println("Area of Circle:", c.Area())
    fmt.Println("Area of Rectangle:", r.Area())
}

面積を呼び出すときは何を呼べばよいか明確にわかるようになっててめちゃよいという結果でした

eisukeeisuke

インターフェースとジェネリクス使えばもっといい感じになるよねこれ

このスクラップは2023/06/23にクローズされました