2016-04-13 5 views
0

私はNode.jsの背景から来て、そしてそこに典型的なパターンは、オブジェクトのオプションを取る機能を持つことで、あなたは、オプションのパラメータのプロパティを設定オブジェクト、すなわち、のようだ:Goでオプションのパラメータを指定する方法は?

foo({ 
    bar: 23, 
    baz: 42 
}); 

これは、JavaScriptのオプションパラメータと名前付きパラメータとの「同等」です。

ここでは、可変パラメータを除いて、Goにオプションのパラメータはありませんが、名前付きパラメータの可読性が不足していることがわかりました。したがって、通常のパターンは構造体を渡すように見えます。

OTOH構造体をデフォルト値で定義することはできないため、構造体を設定する関数が必要です。

だから私はで終わる:

  • 構造体を作成し、デフォルト値で、それを満たす関数を呼び出します。
  • 変更したい値を上書きします。
  • 実際に呼び出す関数を呼び出して、構造体を渡します。

これは、JavaScriptのソリューションに比べてかなり複雑で時間がかかります。

実際には、これはGoのオプションパラメータと名前付きパラメータを扱う慣用的な方法ですか、それとも簡単なバージョンですか?

+0

あなたが持っている問題を示す例を提供した場合、あなたに「行く」方法を示す方が簡単かもしれません。 – sberry

+0

http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apisそのトピックについて大きな洞察を与えます –

答えて

1

最初の質問は、このような複雑さが必要なのでしょうか?柔軟性はいいですが、標準ライブラリのほとんどのものは、これを避けるために一度に1つのデフォルトの情報/ロジックを扱うことを試みます。

ゼロ値を利用できる方法はありますか?すべてのデータ型はゼロ値に初期化されるため、これはデフォルトロジックの一形式です。

オプションオブジェクトは、かなり一般的なイディオムです。 etcd client libraryには、次のようないくつかの例(SetOptions、GetOptions、DeleteOptions)があります。

type MyOptions struct { 
    Field1 int 
    Field2 string 
} 

func DoAction(arg1, arg2 string, options *MyOptions){ 
    var defaultValue1 int = 30  // some reasonable default 
    var defaultValue2 string = "west" // some reasonable default 

    if MyOptions != nil { 
     defaultValue1 = options.Field1 // override with our values 
     defaultValue2 = options.Field2 
    } 
    doStuffWithValues 
0

シナリオに依存して、このアプローチが有用であるかどうかが、いくつかの場合には、少なくともあなたは、このためにmapを使用することができます。

すべてのオプションが同じタイプの場合は、map[string]typeを使用してください。それはあなたに名前付きの選択肢を与え、あなたが望むようにいくつかまたは多くを与えます。

彼らの存在は、マップを作成するときにリテラルマップを使用することができ、デフォルト値を設定するには

if val, exists := opts["bar"]; exists { 
    // Do something here 
} 

のようなものとするためにテストするのは簡単です。

オプションのタイプが同じでない場合は、map[string]interface{}を使用すると、マップにすべてのタイプを格納できます。検索後に値を型キャストするだけで済みます。

関連する問題