いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-355 (メソッド値とメソッド式)(method value, method expression)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。よく忘れるのでここにメモメモ。。。

メソッド値とメソッド式について、どっちがどっちだったかよく忘れるのでここにサンプルを貼っておく。

サンプル

メソッド値

package methods

import (
    "bytes"
    "io"
    "os"
)

// MethodValue は、Goのメソッド値のサンプルです.
//
// メソッド値と対をなすものがメソッド式となる。
// メソッド式のサンプルは methodexpression.go を参照。
//
// # REFERENCES
//   - https://go.dev/ref/spec#Method_expressions
//   - https://zenn.dev/spiegel/articles/20201212-method-value-and-expression
//   - https://stackoverflow.com/questions/48883754/can-any-one-explain-this-go-program-which-uses-a-method-expression
func MethodValue() error {
    //
    // メソッド値は、インスタンスが紐づいた状態の関数オブジェクトのこと
    // 既にレシーバーが紐づいているので、呼び出す際にレシーバーを渡す必要はない
    //

    var (
        buf  = &bytes.Buffer{}
        fn   = buf.Write // メソッド値
        data = []byte("hello world")
    )

    if _, err := fn(data); err != nil {
        return err
    }

    io.Copy(os.Stdout, buf)

    return nil

    /*
      $ task
      task: [build] go build .
      task: [run] ./try-golang -onetime

      ENTER EXAMPLE NAME: methods_method_value

      [Name] "methods_method_value"
      hello world

      [Elapsed] 7.22µs
   */

}

メソッド式

package methods

import (
    "bytes"
    "io"
    "os"
)

// MethodExpression は、Goのメソッド式のサンプルです.
//
// メソッド式と対をなすものがメソッド値となる。
// メソッド値のサンプルは methodvalue.go を参照。
//
// # REFERENCES
//   - https://go.dev/ref/spec#Method_expressions
//   - https://zenn.dev/spiegel/articles/20201212-method-value-and-expression
//   - https://stackoverflow.com/questions/48883754/can-any-one-explain-this-go-program-which-uses-a-method-expression
func MethodExpression() error {
    //
    // メソッド式は、インスタンスが紐づいていない状態の関数オブジェクトのこと
    // レシーバーが紐づいていないので、呼び出す際にレシーバーを渡す必要がある
    // (Python の self と思うと分かりやすい)
    //

    var (
        buf  = &bytes.Buffer{}
        fn   = (*bytes.Buffer).Write // メソッド式
        data = []byte("hello world")
    )

    // メソッド式は、レシーバーが紐づいていないので、第一引数にレシーバーを渡して呼び出す
    if _, err := fn(buf, data); err != nil {
        return err
    }

    io.Copy(os.Stdout, buf)

    return nil

    /*
      $ task
      task: [build] go build .
      task: [run] ./try-golang -onetime

      ENTER EXAMPLE NAME: methods_method_expression

      [Name] "methods_method_expression"
      hello world

      [Elapsed] 6.16µs
   */

}

メソッド値の方はよく利用しますね個人的に。

参考情報

Goのおすすめ書籍

Go言語による並行処理

Go言語による並行処理

Amazon

上の書籍の日本語版が下です。


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。