例如,如果我有一個結構,例如:
type Example struct {
Foo string
Bar string
Baz struct{
A int
B string
}
Qux []string
}
將其轉換為表示每個結構欄位的點路徑的扁平字串切片的最佳方法是什么?
我想要一個類似于以下切片的輸出:
["Example.Foo", "Example.Bar", "Example.Baz.A", "Example.Baz.B", "Example.Qux.0", "Example.Qux.1"]
確切的結構將在編譯時已知。此外,從結構體到平面串列的轉換是一個熱門路徑,因此性能將是一個重要的考慮因素。
任何提示將不勝感激!
uj5u.com熱心網友回復:
你必須自己編碼,用反射。
這是一個演示函式,用于列印您提供的輸出:
package main
import (
"fmt"
"reflect"
"strconv"
)
type Example struct {
Foo string
Bar string
Baz struct{
A int
B string
}
Qux []string
}
func main() {
example := Example{Qux: []string{"a", "b"}}
t := reflect.ValueOf(example)
prefix := t.Type().Name()
fmt.Println(ToPathSlice(t, prefix, make([]string, 0)))
}
func ToPathSlice(t reflect.Value, name string, dst []string) []string {
switch t.Kind() {
case reflect.Ptr, reflect.Interface:
return ToPathSlice(t.Elem(), name, dst)
case reflect.Struct:
for i := 0; i < t.NumField(); i {
fname := t.Type().Field(i).Name
dst = ToPathSlice(t.Field(i), name "." fname, dst)
}
case reflect.Slice, reflect.Array:
for i := 0; i < t.Len(); i {
dst = ToPathSlice(t.Index(i), name "." strconv.Itoa(i), dst)
}
default:
return append(dst, name)
}
return dst
}
將列印:
[Example.Foo Example.Bar Example.Baz.A Example.Baz.B Example.Qux.0 Example.Qux.1]
注意:
- 反思會帶來性能損失;如果您對此感到擔心,您應該分析相關的代碼路徑,看看它是否是一個交易破壞者
- 上面的代碼是人為的,例如它不處理地圖,它不處理
nil等;你可以自己擴展 - 在您想要的輸出中,將列印切片/陣列欄位的索引。切片沒有陣列的固有長度。為了知道切片的長度,您必須使用
reflect.Value. 這個 IMO 使代碼更加笨拙。如果您可以接受不列印切片索引,那么您可以使用reflect.Type.
游樂場:https : //play.golang.org/p/isNFSfFiXOP
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/352556.html
標籤:走
上一篇:用于將函式解組為結構的正確模式?
