2013-09-01 49 views
0

我有一個函數可以從一個數組數組中初始化結構數組。這是我正在做它目前:重構函數使它可以在類型中重用使用Go

type Loadable interface { 
    Load([]interface{}) 
} 

type FooList struct { 
    Foos []*Foo 
} 

func (fl *FooList) Load(vals []interface{}) { 
    fl.Foos = make([]*Foo, len(vals)) 
    for i, v := range vals { 
    foo := &Foo{} 
    foo.Load(v.([]interface{})) 
    fl.Foos[i] = foo 
    } 
} 

這只是正常的,但現在我還需要初始化BarLists和BazLists包含酒吧和Bazs。而不是整個灑我的代碼相同的片段,所有看起來像這樣:

type BarList struct { 
    Bars []*Bar 
} 

func (fl *BarList) Load(vals []interface{}) { 
    fl.Bars = make([]*Bar, len(vals)) 
    for i, v := range vals { 
    bar := &Bar{} 
    bar.Load(v.([]interface{})) 
    fl.Bars[i] = bar 
    } 
} 

什麼是重構這個代碼,使其更乾燥的正確方法?

回答

1

您顯示的代碼不是違反了DRY原則。執行Loader接口的代碼(我拒絕使用javaism)類型FooListBarList只共享一行 - 範圍語句。否則,它們是特定類型的。

由於Go有沒有仿製藥,有沒有直接的方法如何型專門版本在通用方式(模像一切糟糕的選擇是interface{}等和/或減慢你的代碼10通過使用反射次)

+0

猜猜我還是習慣了沒有泛型。剪切和粘貼這麼多的代碼感覺不對,但似乎是一個合適的方式來做到這一點。謝謝! – Bill

0

我能想出使用反射會是這樣的(未測試)最簡單的:

import "reflect" 

// example_of_type should be an instance of the type, e.g. Foo{} 
// returns slice of pointers, e.g. []*Foo 
func Load(vals []interface{}, example_of_type interface()) interface{} { 
    type := reflect.TypeOf(example_of_type) 
    list := reflect.MakeSlice(type.PtrOf().SliceOf(), len(vals), len(vals)) 
    for i, v := range vals { 
    bar := reflect.New(type) 
    bar.Interface().(Loadable).Load(v.([]interface{})) 
    list.Index(i).Set(bar) 
    } 
    return list.Interface() 
} 

你會使用它像:

fl.Foos = Load(vals, Foo{}).([]*Foo) 
fl.Bars = Load(vals, Bar{}).([]*Bar) 
相關問題