如何附加到空介面(已被驗證為 *[]struct)?
func main() {
var mySlice []myStruct // myStruct can be any struct (dynamic)
decode(&mySlice, "...")
}
func decode(dest interface{}, src string) {
// assume dest has been verified to be *[]struct
var modelType reflect.Type = getStructType(dest)
rows, fields := getRows(src)
for _, row := range rows {
// create new struct of type modelType and assign all fields
model := reflect.New(modelType)
for field := fields {
fieldValue := getRowValue(row, field)
model.Elem().FieldByName(field).Set(fieldValue)
}
castedModelRow := model.Elem().Interface()
// append model to dest; how to do this?
// dest = append(dest, castedModelRow)
}
}
我嘗試過的事情:
這只是恐慌:reflect: call of reflect.Append on ptr Value(因為我們通過 &mySlice 而不是 mySlice)
dest = reflect.Append(reflect.ValueOf(dest), reflect.ValueOf(castedModelRow))
這有效,但不會將值設定回 dest... 在主函式中,呼叫 decode 函式后 len(mySlice) 保持為 0。
func decode(dest interface{}, src string) {
...
result := reflect.MakeSlice(reflect.SliceOf(modelType), rowCount, rowCount)
for _, row : range rows {
...
result = reflect.Append(result, reflect.ValueOf(castedModelRow))
}
dest = reflect.ValueOf(result)
}
uj5u.com熱心網友回復:
這是修復decode問題中顯示的第二個函式的方法。該宣告
dest = reflect.ValueOf(result)
修改區域變數dest,而不是呼叫者的值。使用以下陳述句修改呼叫者的切片:
reflect.ValueOf(dest).Elem().Set(result)
問題中的代碼在reflect.MakeSlice 中創建的元素之后附加解碼的元素。結果切片具有len(rows)零值,后跟len(rows)解碼值。通過更改修復
result = reflect.Append(result, reflect.ValueOf(castedModelRow))
到:
result.Index(i).Set(model)
這是decode問題中第二個函式的更新版本:
func decode(dest interface{}, src string) {
var modelType reflect.Type = getStructType(dest)
rows, fields := getRows(src)
result := reflect.MakeSlice(reflect.SliceOf(modelType), len(rows), len(rows))
for i, row := range rows {
model := reflect.New(modelType).Elem()
for _, field := range fields {
fieldValue := getRowValue(row, field)
model.FieldByName(field).Set(fieldValue)
}
result.Index(i).Set(model)
}
reflect.ValueOf(dest).Elem().Set(result)
}
在 Playground 上運行它。
uj5u.com熱心網友回復:
您非常接近您的原始解決方案。在呼叫 append 操作之前,您必須取消對指標的參考。如果您的目標已經有一些現有元素并且您不想通過創建newSlice.
tempDest := reflect.ValueOf(dest).Elem()
tempDest = reflect.Append(tempDest, reflect.ValueOf(model.Interface()))
與@I Love Reflection 指出的類似,您最終需要將新切片設定回指標。
reflect.ValueOf(dest).Elem().Set(tempDest)
整體解碼:
var modelType reflect.Type = getStructType(dest)
rows, fields := getRows(src)
tempDest := reflect.ValueOf(dest).Elem()
for _, row := range rows {
model := reflect.New(modelType).Elem()
for _, field := range fields {
fieldValue := getRowValue(row, field)
model.FieldByName(field).Set(fieldValue)
}
tempDest = reflect.Append(tempDest, reflect.ValueOf(model.Interface()))
}
reflect.ValueOf(dest).Elem().Set(tempDest)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/352543.html
