以下代碼嘗試為任何簡單結構實現通用 CSV 編寫器?!昂唵巍笔侵附Y構的字段值是標準的簡單類型(int、string 等)。type ( CSV interface { Header() []string String([]string) (string, error) } CSVArray []CSV)func CSVOutput(w io.Writer, data CSVArray, cols []string) error { if len(data) == 0 { return nil } _, err := fmt.Fprintln(w, data[0].Header()) if err != nil { return err } for _, d := range data { str, err := d.String(cols) if err != nil { return err } _, err = fmt.Fprintln(w, str) if err != nil { return err } } return nil}問題是CSVOutput()實際上不起作用。例如:var data []Employee //the Employee struct implements CSV interfaceCSVOutput(w, data, nil)編譯失?。篶annot use data (type []Employee) as type CSVArray in argument to CSVOutput我了解 []CSV 與 []Employee 不同,如此處所述,以及許多其他在線可用資源。也就是說,是否可以CSVOutput()使用反射重寫函數:func CSVOutput(w io.Writer, data interfac{}, cols []string) error { sliceOfIntf = castToSlice(data) //how to do this? if !implementedCSV(sliceOfIntf[0]) { //and how to do this? return errors.New("not csv") } ... ...}
1 回答

慕容森
TA貢獻1853條經驗 獲得超18個贊
是否可以使用反射重寫 CSVOutput() 函數
是的
// if data is []Employee{...}, then you can do the following:
rv := reflect.ValueOf(data)
if rv.Kind() != reflect.Slice {
return fmt.Errorf("data is not slice")
}
if !rv.Type().Elem().Implements(reflect.TypeOf((*CSV)(nil)).Elem()) {
return fmt.Errorf("slice element does not implement CSV")
}
csvArr := make(CSVArray, rv.Len())
for i := 0; i < rv.Len(); i++ {
csvArr[i] = rv.Index(i).Interface().(CSV)
}
// now csvArr is CSVArray containing all the elements of data
https://go.dev/play/p/gcSOid533gx
- 1 回答
- 0 關注
- 143 瀏覽
添加回答
舉報
0/150
提交
取消