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

将命令行参数转换为结构字段

将命令行参数转换为结构字段

Go
慕斯709654 2022-10-10 19:15:56
我正在尝试打印一个 JSON(转换为 struct)字段,特别是它作为终端的输入。type foo struct{ field1 stringfield2 int}这是我创建的结构示例,我想将“field1”作为命令行参数,并通过达到解码的 JSON 输出将其打印到 html 正文或控制台。通常我可以用这种方式打印它,但我找不到将os.Args[1]值转换为已经定义的结构字段的方法。var res *foo_=json.NewDecoder(resp.Body).Decode(&res)fmt.Println(res.field1)总之,有没有办法将任何字符串变量转换为函数/方法。非常感谢提前修订说明:例如。我会写信给终端:go run main.go "field1"程序会做这样的事情fmt.Fprintf(writer, "option.field is %v", someFuncThatConcatenatesThisTwo("option."+ os.Args[1]))顺便说一句,要调用多个字段。预定义当然可以解决某种情况,但我想学习的是另一回事。
查看完整描述

1 回答

?
不负相思意

TA贡献1777条经验 获得超10个赞

总之,有没有办法将任何字符串转换为函数/方法。


我不确定你想在这里实现什么。这没有任何意义。


通常,要使用命令行参数填充结构字段,您可以执行以下操作。


package main


import (

    "fmt"

    "log"

    "strconv"

    "os"

)


type Options struct {

    Field1 string

    Field2 int64

}


func main() {

    if len(os.Args) < 2 {

        log.Fatal("missing two required positional arguments: Field1 and Field2")

    }


    opts := &Options{}

    opts.Field1 = os.Args[1]


    var err error

    opts.Field2, err = strconv.ParseInt(os.Args[2], 10, 64)

    if err != nil {

        log.Fatalf("failed to parse integer value: %v", os.Args[2])

    }


    fmt.Println(opts)

}

为了让您的生活更轻松,您可以使用flag(或pflag)包将输入参数声明为命令行标志。


import (

    "flag"

    "fmt"

)


type Options struct {

    Field1 string

    Field2 int

}


var opts Options


func init() {

    flag.StringVar(&opts.Field1, "field1", "", "help message for field1")

    flag.IntVar(&opts.Field2, "field2", 0, "help message for field2")

    flag.Parse()

}


func main() {

   fmt.Println(opts)

}

或者,就像@Jomaar 回答的那样,您可以使用帮助程序库go-arg来避免手动声明命令行标志。另一种选择是go-flags.

编辑

在进一步澄清之后,您似乎希望使用编写器有选择地编写结构的字段,并且您希望使用位置命令行参数来指定要写入的字段。


我认为map在这种情况下存储选项将是一种更合适的数据结构,因为它允许您使用它们的string键简单地引用字段。


import (

    "fmt"

    "os"

)


func main() {

    options := map[string]interface{} {

        "field1": "some-value",

        "field2": 1,

    }


    for _, arg := range os.Args[1:] {

        if val, ok := options[arg]; ok {

            fmt.Println(val)

        }

    }

}

如果要继续使用结构,可以使用reflect包。


import (

    "fmt"

    "os"

    "reflect"

)


type Options struct {

    Field1 string

    Field2 int

}


func main() {

    opts := &Options{Field1: "some-value", Field2: 1}


    for _, arg := range os.Args[1:] {

        fmt.Println(getAttr(opts, arg))

    }

}


// copied from https://stackoverflow.com/a/66470232/2410641

func getAttr(obj interface{}, fieldName string) (reflect.Value, error) {

    pointToStruct := reflect.ValueOf(obj) // addressable

    curStruct := pointToStruct.Elem()

    if curStruct.Kind() != reflect.Struct {

        return reflect.Value{}, fmt.Errorf("obj is not a struct")

    }

    curField := curStruct.FieldByName(fieldName) // type: reflect.Value

    if !curField.IsValid() {

        return reflect.Value{}, fmt.Errorf("field not found: %s", fieldName)

    }

    return curField, nil

}

Go Playground 演示: https: //play.golang.org/p/sch53l2bq4O


查看完整回答
反对 回复 2022-10-10
  • 1 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号