[解決済み] reflectを使用して、構造体フィールドの値を設定するにはどうすればよいですか?
質問
を使って構造体フィールドを扱うのに苦労しています。
reflect
特に、フィールドの値を設定する方法がわかっていません。
type t struct { fi int; fs string } です。 var r t = t{ 123, "jblow" }. var i64 int64 = 456
-
iフィールドの名前を取得する - これは動作するようです。
var field = reflect.TypeOf(r).Field(i).Name
-
フィールドiの値をa) interface{}, b) intとして取得する - これは動作するようです。
var iface interface{} = reflect.ValueOf(r).Field(i).Interface()
var i int = int(reflect.ValueOf(r).Field(i).Int())
-
iフィールドの値を設定する - 1つ試してみて - パニック
reflect.ValueOf(r).Field(i).SetInt( i64 )
パニック : unexported フィールドを使用して取得した値を使用する reflect.Value-SetInt
フィールド名 "id" と "name" を嫌っていると仮定して、 "Id" と "Name" にリネームしています。
a) この仮定は正しいですか?
b) もし正しいのであれば、同じファイル/パッケージの中にあるので、必要ないと思いました。
-
フィールドiの値を設定する - 2を試してみてください(フィールド名は大文字で) - パニック
reflect.ValueOf(r).Field(i).SetInt( 465 )
reflect.ValueOf(r).Field(i).SetInt( i64 )
パニック : アドレス指定不可能な値を使用する reflect.Value-SetInt
以下の @peterSO さんの指示は、徹底的で高品質です。
4.これはうまくいく。
reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 )
また、フィールド名はエクスポート可能でなければならない(大文字で始まる)ことを文書化しています。
どのように解決するのですか?
Go jsonパッケージは、Go構造体からのJSONのマーシャルとアンマーシャル、およびGo構造体へのJSONのマーシャルとアンマーシャルを行います。
の値を設定するステップバイステップの例です。
struct
フィールドの値を設定し、エラーを慎重に回避するステップバイステップの例です。
碁は
reflect
パッケージには
CanAddr
という関数があります。
func (v Value) CanAddr() bool
CanAddrは、値のアドレスがAddrで取得できる場合に真を返します。 のアドレスがAddrで取得できる場合は真を返します。 このような値はaddressableと呼ばれます。A 値は、それがスライスの要素である場合、アドレス指定可能です。 スライスの要素、アドレス指定可能な配列の要素、または アドレス指定可能な配列の要素、アドレス指定可能な構造体のフィールド アドレス指定可能な構造体のフィールド、またはポインタのデリファレンスの結果であれば ポインタの参照解除の結果であれば,アドレス指定可能です。もしCanAddr が偽を返した場合,Addrを呼び出すと を呼び出すとパニックになります。
Goは
reflect
パッケージには
CanSet
関数があり、もし
true
の場合、以下のようになります。
CanAddr
はまた
true
.
func (v Value) CanSet() bool
CanSetは、vの値が変更可能であれば真を返します。 の値が変更可能であれば真を返します。値を変更できるのは アドレス指定可能で、かつ アドレス指定が可能で、かつ、未エクスポートの 構造体フィールドの使用によって取得されたものでない場合に限り、 変更できる。CanSetがfalseを返した場合 が偽を返した場合、Setまたは任意の 型固有のセッター(例えば,SetBool, SetInt64など)を呼び出すとパニックになります。
私たちは
Set
は
struct
というフィールドがあります。例えば
package main
import (
"fmt"
"reflect"
)
func main() {
type t struct {
N int
}
var n = t{42}
// N at start
fmt.Println(n.N)
// pointer to struct - addressable
ps := reflect.ValueOf(&n)
// struct
s := ps.Elem()
if s.Kind() == reflect.Struct {
// exported field
f := s.FieldByName("N")
if f.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if f.CanSet() {
// change value of N
if f.Kind() == reflect.Int {
x := int64(7)
if !f.OverflowInt(x) {
f.SetInt(x)
}
}
}
}
}
// N at end
fmt.Println(n.N)
}
Output:
42
7
もし、すべてのエラーチェックが不要であることが確認できれば、この例は単純化されます。
package main
import (
"fmt"
"reflect"
)
func main() {
type t struct {
N int
}
var n = t{42}
fmt.Println(n.N)
reflect.ValueOf(&n).Elem().FieldByName("N").SetInt(7)
fmt.Println(n.N)
}
ところで として、囲碁が利用できます。 オープンソースコード . リフレクションについて学ぶ良い方法は、Goのコア開発者がリフレクションをどのように使っているかを見ることです。たとえば、Goの fmt と json パッケージがあります。パッケージのドキュメントには、パッケージファイルという見出しの下に、ソースコードファイルへのリンクがあります。
関連
-
[解決済み] リフレクションを使用して文字列からプロパティ値を取得する
-
[解決済み] コードが含まれるアセンブリのパスを取得するにはどうすればよいですか?
-
[解決済み] Goで複数行の文字列はどのように書くのですか?
-
[解決済み] リフレクションを使って、パッケージ内のすべてのクラスを見つけることができますか?
-
[解決済み] 構造体変数をコンソールに表示するには?
-
[解決済み] Goでオブジェクトの型を見つけるには?
-
[解決済み] time.Sleepを使わずにすべてのゴルーチンが終了するのを待つには?
-
[解決済み] response.Bodyを閉じないとどうなりますか?
-
[解決済み] Goを使って大きなファイルを効率よくダウンロードするにはどうしたらいいですか?
-
[解決済み] マップから構造体への変換
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] サーバーでSSLが有効になっていない
-
[解決済み] time.Sleepを使わずにすべてのゴルーチンが終了するのを待つには?
-
[解決済み] intをint64に変換するには?
-
[解決済み] response.Bodyを閉じないとどうなりますか?
-
[解決済み] ゴルーチンの停止方法
-
[解決済み] Goを使って大きなファイルを効率よくダウンロードするにはどうしたらいいですか?
-
[解決済み] スライスを宣言するのか、スライスを作るのか?
-
[解決済み] オブジェクトのプロパティを二重引用符で囲んで使用するには?
-
[解決済み] GoのToString()関数
-
[解決済み] マップから構造体への変換