6

Go がテンプレートやオーバーロードされた関数をサポートしていないことは知っていますが、何らかのジェネリック プログラミングを行う方法はあるのでしょうか?

次のような多くの機能があります。

func (this Document) GetString(name string, default...string) string {
    v, ok := this.GetValueFromDb(name)
    if !ok {
        if len(default) >= 1 {
            return default[0]
        } else {
            return ""
        }
    }
    return v.asString
}

func (this Document) GetInt(name string, default...int) int {
    v, ok := this.GetValueFromDb(name)
    if !ok {
        if len(default) >= 1 {
            return default[0]
        } else {
            return 0
        }
    }
    return v.asInt
}

// etc. for many different types

冗長なコードをあまり使わずにこれを行う方法はありますか?

4

3 に答える 3

12

達成できることのほとんどはinterface{}、次のような型の使用です。

func (this Document) Get(name string, default... interface{}) interface{} {
    v, ok := this.GetValueFromDb(name)
    if !ok {
        if len(default) >= 1 {
            return default[0]
        } else {
            return 0
        }
    }
    return v
}

GetValueFromDb関数もinterface{}値を返すように微調整する必要があり、現在のようなラッパーではありません。

次に、クライアント コードで次の操作を実行できます。

value := document.Get("index", 1).(int)  // Panics when the value is not int

また

value, ok := document.Get("index", 1).(int)  // ok is false if the value is not int

ただし、これにより実行時のオーバーヘッドが発生します。別の関数に固執し、何らかの方法でコードを再構築することをお勧めします。

于 2013-02-27T09:06:06.857 に答える
3

これは、コードを変更する方法の実例です。

指定された名前に期待するタイプがわかっているので、Getメソッドを一般的な方法で記述し、を返しinterface{}、呼び出しサイトでタイプをアサートできます。タイプアサーションに関する仕様を参照してください。

Goでジェネリックのいくつかの側面をエミュレートするさまざまな方法があります。メーリングリストにはたくさんの議論がありました。多くの場合、ジェネリックスへの依存度が低くなるようにコードを再構築する方法があります。

于 2013-02-27T09:11:14.353 に答える
0

クライアントコードでは、次のようにすることができます:

res := GetValue("name", 1, 2, 3)
// or
// res := GetValue("name", "one", "two", "three")

if value, ok := res.(int); ok {
    // process int return value
} else if value, ok := res.(string); ok {
    // process string return value
}

// or
// res.(type) expression only work in switch statement
// and 'res' variable's type have to be interface type
switch value := res.(type) {
case int:
    // process int return value
case string:
    // process string return value
}
于 2014-12-04T03:32:26.330 に答える