我有下面的代碼,我正在嘗試進行遞回。但是,go 編譯器抱怨回圈參考。當然我有一個回圈參考;這是一個遞回。
我嘗試將遞回移入主函式并移出。同樣的問題。我怎樣才能實作這種遞回?錯誤行是:return lookup(deref.Interface()) // recursion error 'cyclic definition'
christianb@christianb-mac terraform-provider% go build
# github.com/terraform-provider/pkg/foo/repositories.go:773:5: initialization loop:
/Users/christianb/dev/terraform-provider/pkg/foo/repositories.go:773:5: lookup refers to
/Users/christianb/dev/terraform-provider/pkg/foo/repositories.go:774:18: glob..func6.1 refers to
/Users/christianb/dev/terraform-provider/pkg/foo/artifactory/repositories.go:773:5: lookup
type AutoMapper func(field reflect.StructField, thing reflect.Value) map[string]interface{}
var lookup = func() func(payload interface{}) map[string]interface{} {
var handlePtr = func(field reflect.StructField, thing reflect.Value) map[string]interface{} {
deref := reflect.Indirect(thing)
if deref.CanAddr() {
if deref.Kind() == reflect.Struct {
return lookup(deref.Interface()) // recursion error 'cyclic definition'
}
return map[string]interface{}{
field.Tag.Get("hcl"): deref.Interface(),
}
}
return map[string]interface{}{}
}
var checkForHcl = func(mapper AutoMapper) AutoMapper {
return func(field reflect.StructField, thing reflect.Value) map[string]interface{} {
if field.Tag.Get("hcl") != "" {
return mapper(field, thing)
}
return map[string]interface{}{}
}
}
lk := map[reflect.Kind]AutoMapper{}
find := func(payload interface{}) map[string]interface{} {
values := map[string]interface{}{}
var t = reflect.TypeOf(payload)
var v = reflect.ValueOf(payload)
if t.Kind() == reflect.Ptr {
t = t.Elem()
v = v.Elem()
}
for i := 0; i < t.NumField(); i {
field := t.Field(i)
thing := v.Field(i)
for key, value := range lk[thing.Kind()](field, thing) {
values[key] = value
}
}
return values
}
lk[reflect.Struct] = checkForHcl(func(f reflect.StructField, t reflect.Value) map[string]interface{} {
return find(t.Interface())
})
lk[reflect.Slice] = checkForHcl(func(field reflect.StructField, thing reflect.Value) map[string]interface{} {
return map[string]interface{}{
field.Tag.Get("hcl"): thing.Interface().([]string),
}
})
lk[reflect.Ptr] = checkForHcl(handlePtr)
return find
}()
uj5u.com熱心網友回復:
問題是初始化回圈,而不是遞回。您指的是該變數定義中的變數。你可以做:
var lookup func() func(payload interface{}) map[string]interface{}
func init() {
lookup=func() func(payload interface{}) map[string]interface{} {...}
}
uj5u.com熱心網友回復:
您的函式不能通過名稱參考自身,因為它是一個匿名函式。它只有在被分配給變數后才會被命名lookup。從詞法上講,只有在完全決議分配的值后才會發生這種情況。這與普通func宣告不同,在普通宣告中,名稱立即可用(這使得遞回更清晰):
func myFunc(arg) result {
// ... do something ...
// now we can call the function recursively
return myFunc(arg)
}
在您的情況下,常規func宣告不起作用,因此您需要某種“前向宣告”以使名稱可用,這需要少量重復:
// forward declare the function
var myFunc func(arg) result
myFunc = func(arg) result {
// ... do something ...
// now we can call the function recursively
return myFunc(arg)
}
要在全球范圍內做同樣的事情,請參閱Burak 的回答。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/344879.html
上一篇:通過在另一個資料幀中的所有行上迭代資料幀中的一行來檢查最小值
下一篇:理解字串置換遞回案例之間的區別
