2016-04-06 7 views
0

Goのスライスでアクションを処理できる汎用関数を作成しようとしています。たとえば、同じタイプのスライスに任意のタイプの項目を追加します。これは単純に、より複雑なソリューションのための一般的な目的であるが、全体的な問題は、この例に沸く:Goでマルチタイプ配列の汎用関数を作成する

package main 

type car struct { 
    make string 
    color string 
} 

type submarine struct { 
    name string 
    length int 
} 

func genericAppender(thingList interface{}, thing interface{}) []interface{} { 
    return append(thingList, thing) 
} 

func main() { 

    cars := make([]car, 0, 10) 
    cars[0] = car{make: "ford", color: "red"} 
    cars[1] = car{make: "chevy", color: "blue"} 

    subs := make([]submarine, 0, 10) 
    subs[0] = submarine{name: "sally", length: 100} 
    subs[1] = submarine{name: "matilda", length: 200} 

    newCar := car{make: "bmw", color: "white"} 
    genericAppender(&cars, newCar) 

} 

コード遊び場は、このlocation

である上記のエラー、次のように:

prog.go:14: first argument to append must be slice; have interface {} 

答えて

3

この変更後も、ランタイムエラー(インデックスが範囲外です)が発生しますが、thingListのタイプは[]interface{}ではなく、interface{}であるため、追加できません。ここには、追加の行にある[]interface{}に変換するタイプアサーションを行う、プレイグランド上のコードの更新版があります。実際には、別の行でこれを行い、エラーをチェックする必要があります。だからここにいくつかのコードを入れて

https://play.golang.org/p/YMed0VDZrv

func genericAppender(thingList interface{}, thing interface{}) []interface{} { 
    return append(thingList.([]interface{}), thing) 
} 

は、あなたが直面している基本的な問題を解決します。前述のように、スライスにインデックスを付けるときにはランタイムエラーが発生します。また、これを避けるために引数を変更することもできます。

func genericAppender(thingList []interface{}, thing interface{}) []interface{} { 
    return append(thingList, thing) 
} 

ここでは2番目のタイプの完全な例を示します。 https://play.golang.org/p/dIuW_UG7XY

注記ランタイムエラーも修正しました。 3つの引数をつけてmakeを使うと、型、長さ、容量の順になります。これは、配列の長さが0であることを意味します。したがって、インデックス0と1に割り当てようとすると、IndexOutoFRangeのパニックが発生していました。代わりに中間の引数を削除して、make([]interface{}, 10)の長さは最初に10に設定されているので、それらのインデックスに割り当てることができます。

+0

私はあなたの提案をここで試してみましたが(https://play.golang.org/p/ecJv730Zrd)、genericAppenderNewの引数でtype [] interface {}として "cars(type [] car)を使用できません" "私はこれがまだ可能であるかどうかはわかりません... – gextra

+0

@gextraその場合、2番目のオプションを使用しています。このメソッドを使用する場合は、 'genericInterface'を' genericAppender'に渡す前に型を '[] interface {}'にする必要があります。最初の例では、現在持っているコレクションを取り込み、メソッド内に型アサーションを行います。 – evanmcdonnal

+1

@gextraエラーなしで実行する2番目の提案の完全な例を含めるように更新しました。 – evanmcdonnal

関連する問題