1. ホーム
  2. go

[解決済み] 構造体のプロパティに名前でアクセスする

2023-03-18 19:05:43

質問

簡単な囲碁のプログラムが動作しません。

package main
import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    fmt.Println(getProperty(&v, "X"))
}

func getProperty(v *Vertex, property string) (string) {
    return v[property]
}

エラーです。

prog.go:18: 無効な操作: v[property] (型 *Vertex のインデックス)

私がしたいのは、その名前を使用して頂点Xのプロパティにアクセスすることです。もし私が v.X とすればうまくいきますが v["X"] は動作しません。

誰かこれを動作させる方法を教えてください。

どのように解決するのですか?

ほとんどのコードでは、この種の動的検索は必要ないはずです。直接アクセスに比べて非効率的です (コンパイラーは頂点構造体の X フィールドのオフセットを知っているので、v.X を 1 つの機械命令にコンパイルできますが、動的検索にはある種のハッシュ テーブル実装または類似のものが必要です)。コンパイラーは、未知のフィールドに動的にアクセスしようとしていないことを確認する方法がなく、結果としてどのような型になるべきかを知ることができないため、静的型付けも阻害します。

しかし...この言語では を反映します。 モジュールが用意されているので、これが必要になることは稀です。

package main

import "fmt"
import "reflect"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    fmt.Println(getField(&v, "X"))
}

func getField(v *Vertex, field string) int {
    r := reflect.ValueOf(v)
    f := reflect.Indirect(r).FieldByName(field)
    return int(f.Int())
}

ここではエラーチェックを行っていませんので、存在しないフィールドを要求したり、フィールドの型がintでない場合、パニックになります。チェック のドキュメントを参照してください。 のドキュメントを参照してください。