为了账号安全,请及时绑定邮箱和手机立即绑定

变量可以用作函数调用的占位符吗?

变量可以用作函数调用的占位符吗?

Go
三国纷争 2023-08-07 11:12:15
我正在编写一个程序,它有几个结构和函数来以不同的方式处理这些结构。我有一个通用函数,它根据输入调用所需的函数。是否有通用方法来使用getStruct()返回的值?package mainvar X func(s []string) Avar Y func(s []string) Btype A struct {    Name  string    Place string}type B struct {    Name  string    Place string    Value string}func newA(s []string) A {    a := A{        Name:  s[0],        Place: s[1],    }    return a}func newB(s []string) B {    a := B{        Name:  s[0],        Place: s[1],        Value: s[2],    }    return a}func getStruct(t string) interface{} {    switch {    case t == "A":        return X    case t == "B":        return Y    default:        return //someStruct    }}func main() {    buildNewStruct := getStruct("A") //Lets assume "A" here is got as an argument    var strSlice = []string{"Bob", "US"}    buildNewStruct(strSlice) //How to do this operation?                              //I am hoping to use buildNewStruct(strSlice) to dynamically call                              //either of newA(strSlice) or newB(strSlice) function}由于我是新手,我不确定这样的事情是否可能。
查看完整描述

2 回答

?
慕慕森

TA贡献1856条经验 获得超17个赞

您可以使用该reflect包将结构属性设置为[]interface{}切片中的等效索引定位值。


package main


import (

    "fmt"

    "log"

    "reflect"

)


func main() {

    var a A

    err := decode(&a, []interface{}{"Name", "Place"})

    log.Println(err)

    log.Println(a)

}


func decode(dst interface{}, values []interface{}) error {

    rvptr := reflect.ValueOf(dst)

    if rvptr.Kind() != reflect.Ptr {

        return fmt.Errorf("value must be ptr")

    }

    rv := rvptr.Elem()

    if rv.NumField() < len(values) {

        return fmt.Errorf("too many values")

    }

    if rv.NumField() > len(values) {

        return fmt.Errorf("too few values")

    }

    rvalues := reflect.ValueOf(values)

    for i := range values {

        f := rv.FieldByIndex([]int{i})

        f.Set(rvalues.Index(i).Elem())

    }

    return nil

}


type A struct {

    Name  string

    Place string

}


type B struct {

    Name  string

    Place string

    Value string

}

印刷


$ go run main.go 

2019/11/21 17:00:17 <nil>

2019/11/21 17:00:17 {Name Place}


查看完整回答
反对 回复 2023-08-07
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

问题在于函数的返回类型。


func newA(in []string) interface{} {...}

func newB(in []string) interface{} {...}


func getStruct(name string) func([]string) interface{} {

  switch name {

     case "A": return newA

     case "B": return newB

  }

  return nil

}


func main() {

  buildNewStruct := getStruct("A") 

  var strSlice = []string{"Bob", "US"}

  str:=buildNewStruct(strSlice)

  if a, ok:=str.(A); ok {

     ...

  }

}

使用这种方法,即使您通过调用统一节省了一些代码buildNewStruct(),您也必须使用类型断言来确定该函数返回的内容,因此这可能没有多大意义。但这取决于您的具体用例。


查看完整回答
反对 回复 2023-08-07
  • 2 回答
  • 0 关注
  • 92 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信