2017-09-21 3 views
0

私は非常に多くの質問を確認しましたが、今はかなり使っていますが、解決策が見つかりませんこのため。フィールドがポインタへのポインタのときに構造体フィールドの値を設定する

基本的に、私はさまざまなプリミティブへのポインタの構造体を持っています。構造体はアプリケーションのための設定であり、フィールドがポインタである理由は、デフォルトに設定されたフィールドと全く設定されていないフィールドの間で "必須"フィールドを強制するために判断できます。

私が最後にソースコードをリンクする今の簡単な例を使用することができます:

type Config struct { 
    A *string 
    B *int 
    C *bool 
    D *[]string // wildcard! 
} 

だから私は、私はを反復処理私の各要素に対して.Fieldを与えるreflect.ValueOf(*cfg)経由reflect.Valueを、つかみます。

各要素はCanAddrまたはCanSetを渡しません。ポインタの後ろにある値を設定する方法が見つからないようです。これは言語の制限ですか?フィールドを非ポインタにする必要がありますか?これは、ユーザーが空の文字列を指定したか、まったく設定していないかどうかを判断する方法がないためにうまくいくでしょう。

[]文字列フィールドを設定/追加するためのボーナスポイント!それものミックスでスローされずに私を混乱させた!とにかく

、関連するコードはここにある:アドレス指定可能な値を取得するために

v := reflect.ValueOf(cfg).Elem() 
t := v.Type() 

t := reflect.TypeOf(*cfg) 
v := reflect.ValueOf(*cfg) 

https://github.com/Southclaws/sampctl/blob/master/settings.go#L95-L116

答えて

1

は、これらの行を交換してください。

reflect.ValueOf(*cfg)によって作成された値には、アドレス指定可能なメモリへの参照がありません。この問題を解決するには、反映ドメイン内のポインタを逆参照することです。

[]文字列について。空のスライスと空のスライスには違いがあるため、* []文字列を使用する必要はありません。いずれにしても、reflect.Append関数を使用してスライスに追加します。

var s []string 
v := reflect.ValueOf(&s).Elem() 
v.Set(reflect.Append(v, reflect.ValueOf("hello"))) 
v.Set(reflect.Append(v, reflect.ValueOf("world"))) 
fmt.Println(s) // prints [hello world] 
関連する問題