在接口golang中对方法进行迭代



我正在尝试迭代接口中的所有方法。我已经找到了一些例子,但我似乎无法让我的例子发挥作用。我试图用一个封装的结构来实现这一点,我在其他包中使用这个结构,但在本例中,它在同一个包中。

我正在尝试迭代所有的get函数(在我的例子中,我只有一个(,但在现实生活中,我有几个

我希望我的输出是两行

  • "2009/11/10 23:00:00 getTenantUIDQueryInString">
  • "2009/11/10 23:00:00(tenant_uuid IN(uuid_TO_BIN('8df030a1-a057-4f53-a011-a2b1cff673a1'(

相反,我得到了第一行,然后恐慌

  • "2009/11/10 23:00:00 getTenantUIDQueryInString">
  • "恐慌:反思:反思的呼唤。Value。调用零值">

这是一个正在进行的游乐场https://go.dev/play/p/YsnJ46QnifT

package main
import (
"fmt"
"log"
"reflect"
"strings"
"github.com/google/uuid"
)
func main() {
pipedTenantUUIDs := "8df030a1-a057-4f53-a011-a2b1cff673a1|8df030a1-a057-4f53-a011-a2b1cff673a1"
so, responseCode, err := createTenantSearch(pipedTenantUUIDs)
if err != nil {
log.Println(err, responseCode)
}
t := reflect.TypeOf(&so).Elem()
v := reflect.ValueOf(&so)
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
if strings.HasPrefix(method.Name, "get") {
log.Println(method.Name)
whereVal := v.MethodByName(method.Name).Call(nil)
log.Println(whereVal[0])
}
}
}
// I want my output to be two lines
//  "2009/11/10 23:00:00 getTenantUUIDQueryInString"
//  "2009/11/10 23:00:00 (tenant_uuid IN (UUID_TO_BIN('8df030a1-a057-4f53-a011-a2b1cff673a1'),UUID_TO-BIN('9df030a1-a057-4f53-a011-a2b1cff673a1'))"
//
// instead i get a the first line and then panic
// "2009/11/10 23:00:00 getTenantUUIDQueryInString"
// "panic: reflect: call of reflect.Value.Call on zero Value"
// this is how i have everything set up
type iTenantSearch interface {
mapTenantUUID(pipedString string) error
getTenantUUIDQueryInString() string
}
type tenantSearch struct {
tenantUUID []uuid.UUID
}
func (ts *tenantSearch) mapTenantUUID(pipedString string) error {
splitString := strings.Split(pipedString, "|")
for i := 0; i < len(splitString); i++ {
parsedUUID, err := uuid.Parse(splitString[i])
if err != nil {
ts.tenantUUID = []uuid.UUID{}
return fmt.Errorf("tenant uuid failed to parse: %s", err)
}
ts.tenantUUID = append(ts.tenantUUID, parsedUUID)
}
return nil
}
func (ts *tenantSearch) getTenantUUIDQueryInString() string {
inString := ""
if ts.tenantUUID != nil {
inString = inString + `(tenant_uuid IN (`
for i, s := range ts.tenantUUID {
if i == (len(ts.tenantUUID) - 1) {
inString = inString + `UUID_TO_BIN('` + s.String() + `')`
} else {
inString = inString + `UUID_TO_BIN('` + s.String() + `'),`
}
}
inString = inString + `))`
}
return inString
}
func createTenantSearch(tenantUUIDs string) (iTenantSearch, int, error) {
var tso tenantSearch
if tenantUUIDs != "" {
err := tso.mapTenantUUID(tenantUUIDs)
return nil, 400, err
}
return &tso, 200, nil
}

多亏了Cerise Limón,我找到了答案。。这是更正后的代码。。。

  1. create函数中的固定逻辑
  2. 导出了我的get方法
  3. 将v设置为iTenantSearch:v:=反射。Value Of(&so(.Elm((–Cerise Limón

这是上的工作代码https://go.dev/play/p/7fG9FcIr6vQ

package main
import (
"fmt"
"log"
"reflect"
"strings"
"github.com/google/uuid"
)
func main() {
pipedTenantUUIDs := "8df030a1-a057-4f53-a011-a2b1cff673a1|8df030a1-a057-4f53-a011-a2b1cff673a1"
so, responseCode, err := createTenantSearch(pipedTenantUUIDs)
if err != nil {
log.Println(err, responseCode)
}
t := reflect.TypeOf(&so).Elem()
v := reflect.ValueOf(&so).Elem()
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
if strings.HasPrefix(method.Name, "Get") {
log.Println(method.Name)
whereVal := v.MethodByName(method.Name).Call(nil)
log.Println(whereVal[0])
}
}
}
type iTenantSearch interface {
mapTenantUUID(pipedString string) error
GetTenantUUIDQueryInString() string
}
type tenantSearch struct {
tenantUUID []uuid.UUID
}
func (ts *tenantSearch) mapTenantUUID(pipedString string) error {
splitString := strings.Split(pipedString, "|")
for i := 0; i < len(splitString); i++ {
parsedUUID, err := uuid.Parse(splitString[i])
if err != nil {
ts.tenantUUID = []uuid.UUID{}
return fmt.Errorf("tenant uuid failed to parse: %s", err)
}
ts.tenantUUID = append(ts.tenantUUID, parsedUUID)
}
return nil
}
func (ts *tenantSearch) GetTenantUUIDQueryInString() string {
inString := ""
if ts.tenantUUID != nil {
inString = inString + `(tenant_uuid IN (`
for i, s := range ts.tenantUUID {
if i == (len(ts.tenantUUID) - 1) {
inString = inString + `UUID_TO_BIN('` + s.String() + `')`
} else {
inString = inString + `UUID_TO_BIN('` + s.String() + `'),`
}
}
inString = inString + `))`
}
return inString
}
func createTenantSearch(tenantUUIDs string) (iTenantSearch, int, error) {
var tso tenantSearch
err := tso.mapTenantUUID(tenantUUIDs)
if err != nil {
return nil, 400, err
}
return &tso, 200, nil
}

最新更新