17
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Go言語] reflectパッケージで変数の値を変える

Last updated at Posted at 2013-09-21

以下の記事に書いてあることをまとめる。

変数の値を変える

よく考えれば当たり前だが、一度ポインタにしないと変数の値を変えることができない。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	n := 100

	// ダメ
	nv := reflect.ValueOf(n)
	fmt.Println(nv.CanSet())

	// ポインタを使う
	npv := reflect.ValueOf(&n)
	fmt.Println(npv.Elem().CanSet())
	npv.Elem().SetInt(200)

	fmt.Println(n)
}

一度ポインタにして、Elemメソッドでまたポインタの指す先に戻しているあたりが気持ち悪い。
Elemメソッドのソースを見ると、flagRO フラグは元のValueの物を保持して、flagAddrフラグとflagIndirフラグを立てている。そのため、CanSetメソッドでtrueが返る(つまり、代入可能にしている)ことが分かる。
一方、reflect.ValueOf(100)のようにした場合は、flagIndirしかフラグがたてられない。よって、CanSetはfalseとなり、Setできない。

構造体のフィールドの値を変える

上記と同様に、構造体のフィールドの値を変えるのにも一度ポインタに変換する必要がある。

package main

import (
	"fmt"
	"reflect"
)

type Hoge struct {
	N int
}

func main() {
	h := Hoge{10}
	hpv := reflect.ValueOf(&h)
	hpv.Elem().FieldByName("N").SetInt(200)

	fmt.Println(h)
}
17
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?