[Go言語] reflectパッケージで変数の値を変える
September 21, 2013
この記事はQiitaの記事をエクスポートしたものです。内容が古くなっている可能性があります。
以下の記事に書いてあることをまとめる。
変数の値を変える
よく考えれば当たり前だが、一度ポインタにしないと変数の値を変えることができない。
http://play.golang.org/p/grX4uYh2VO
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
できない。
構造体のフィールドの値を変える
上記と同様に、構造体のフィールドの値を変えるのにも一度ポインタに変換する必要がある。
http://play.golang.org/p/SSW28W5bXn
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)
}