1 回答

TA貢獻1830條經驗 獲得超9個贊
因此,正如我在評論中提到的,如果您希望能夠從字段中獲取單個元素,最簡單的方法tableRecord.Data就是將字段類型更改為實際類型:
type tableRecord struct {
PrimaryKey string
Data []interface{} // slice of whatever
}
這樣,你可以寫一些非常通用的東西:
for tbl, record := range records {
fmt.Printf("First record from table %s\n", tbl)
b, _ := json.MarshalIndent(record[0], " ", " ")
fmt.Println(string(b))
fmt.Prinln("other records...")
b, _ = json.MarshalIndend(record[1:], " ", " ")
fmt.Println(string(b))
}
不過,如果我是你,我會考慮在我的數據庫類型中實現一個接口。類似的東西:
type DBType interface {
PrimaryKey() string
TableName() string // xorm can use this to get the table name
Slice() []DBType // can return []user or whatever
}
所以你真的不需要tableRecord類型了,可以像這樣使用 var:
listOfTables := []DBType{user{}, ...}
for _, tbl := range listOfTables {
data := tbl.Slice()
// find data here
fmt.Printf("First record from table %s\n", tbl.TableName())
b, _ := json.MarshalIndent(data[0], " ", " ")
fmt.Println(string(b))
fmt.Prinln("other records...")
b, _ = json.MarshalIndend(data[1:], " ", " ")
fmt.Println(string(b))
}
所以 TL;DR 我的回答/評論中缺少的內容:
[]user{}從 type (or []DBTable) to 的轉換[]interface{}不起作用,因為您不能在單個表達式中轉換切片中的所有元素。您必須創建第二個類型切片[]interface{}并像這樣復制值:
slice := userVar.Slice() data := make([]interface{}, len(slice)) for i := range slice { data[i] = slice[i] // 復制類型到 interface{} slice } 返回表記錄{userVar.PrimaryKey(), 數據}
我已經創建了一個小的工作示例來說明如何使用上述接口。
演示
為避免太多混亂,您可以更改Slicefunc 以[]interface{}立即返回 a:
func(v T) Slice() []interface{
return []interface{
&T{},
}
}
你的實施有什么問題Slice是你有這樣的事情:
func (u *user) Slice() []DBTable {
u = &user{} // you're re-assigning the receiver, losing all state!
return []DBTable{u}
}
接收器是指針類型,因此您所做的任何重新分配都會影響調用 func 的變量。那不是一個好主意。只使用值接收器,或者,如果你想確保接口只在指針變量上實現(一個常見的技巧,例如 gRPC 使用的)是像這樣實現函數:
func(*user) Slice() []DBTable{
return []DBTable{&user{}}
}
pb.go這個技巧的一個很好的例子可以在使用協議緩沖區時生成的文件中找到。消息類型將具有如下功能:
func(*MsgType) ProtoMessage() {}
- 1 回答
- 0 關注
- 178 瀏覽
添加回答
舉報