2017-12-24 64 views
0

golangのjsonプロセッサーへのクイックssh設定を書いています。構造体プロパティへのGolang動的アクセス

type SshConfig struct { 
    Host string 
    Port string 
    User string 
    LocalForward string 
    ... 
} 

私は現在、私のsshのconfigファイルのすべての行を超えるループとスペースと更新するプロパティのチェックに線を分割しています:私は、次のstuctを持っています。

if split[0] == "Port" { 
    sshConfig.Port = strings.Join(split[1:], " ") 
} 

プロパティが存在するかどうかを確認して動的に設定する方法はありますか?

+0

私があなたに求めていることは明らかではありませんが、なぜYAMLやJSONなどの設定にシリアル化していないのですか? –

答えて

2

は、名前でフィールドを設定するreflectパッケージを使用して:あなたは、実行時に動的に構造体を検査するパッケージを反映して使用することができ

var config SshConfig 

... 

err := setField(&config, split[0], strings.Join(split[1:], " ")) 
if err != nil { 
    // handle error 
} 

playground example

0

// setField sets field of v with given name to given value. 
func setField(v interface{}, name string, value string) error { 
    // v must be a pointer to a struct 
    rv := reflect.ValueOf(v) 
    if rv.Kind() != reflect.Ptr || rv.Elem().Kind() != reflect.Struct { 
     return errors.New("v must be pointer to struct") 
    } 

    // Dereference pointer 
    rv = rv.Elem() 

    // Lookup field by name 
    fv := rv.FieldByName(name) 
    if !fv.IsValid() { 
     return fmt.Errorf("not a field name: %s", name) 
    } 

    // Field must be exported 
    if !fv.CanSet() { 
     return fmt.Errorf("cannot set field %s", name) 
    } 

    // We expect a string field 
    if fv.Kind() != reflect.String { 
     return fmt.Errorf("%s is not a string field", name) 
    } 

    // Set the value 
    fv.SetString(value) 
    return nil 
} 

はこのようにそれを呼び出します。 docsおよびblogを参照してください。

しかし、あなたがしたいことがあれば、そのファイルを構造体に読み込み、map[string]stringのようなものを使うのがよいでしょう。実行時に地図を検査する方がはるかにクリーンです(例:range、メンバーシップをチェック...など)。

m := make(map[string]string) 
... 
m[split[0]] = strings.Join(split[1:], " ") 
関連する問題