转换命令行参数以用作结构字段
Converting command line argument to use as struct field
我正在尝试打印一个 JSON(转换为结构)字段,特别是作为终端输入的字段。
type foo struct{
field1 string
field2 int
}
这是我创建的结构示例,我想将“field1”作为命令行参数并通过解码 JSON 输出将其打印到 html 正文或控制台。
通常我可以这样打印,但我找不到将 os.Args[1] 值转换为已定义的结构字段的方法。
var res *foo
_=json.NewDecoder(resp.Body).Decode(&res)
fmt.Println(res.field1)
综上所述,有没有办法将任何字符串变量转换为 function/method。非常感谢
牧师。注意:例如。
我会写信给终端:
go run main.go "field1"
程序会做这样的事情
fmt.Fprintf(writer, "option.field is %v", someFuncThatConcatenatesThisTwo("option."+ os.Args[1]))
顺便说一句,有多个字段要调用。预定义当然可以解决某些情况,但我想学习的是其他东西。
In summary, is there a way to convert any string to function/method.
我不确定你想在这里实现什么。这没有任何意义。
一般来说,要使用命令行参数填充结构字段,您可以执行如下操作。
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
(or 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
to avoid manually declaring command-line flags. Another alternative is 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
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
我正在尝试打印一个 JSON(转换为结构)字段,特别是作为终端输入的字段。
type foo struct{
field1 string
field2 int
}
这是我创建的结构示例,我想将“field1”作为命令行参数并通过解码 JSON 输出将其打印到 html 正文或控制台。
通常我可以这样打印,但我找不到将 os.Args[1] 值转换为已定义的结构字段的方法。
var res *foo
_=json.NewDecoder(resp.Body).Decode(&res)
fmt.Println(res.field1)
综上所述,有没有办法将任何字符串变量转换为 function/method。非常感谢
牧师。注意:例如。 我会写信给终端:
go run main.go "field1"
程序会做这样的事情
fmt.Fprintf(writer, "option.field is %v", someFuncThatConcatenatesThisTwo("option."+ os.Args[1]))
顺便说一句,有多个字段要调用。预定义当然可以解决某些情况,但我想学习的是其他东西。
In summary, is there a way to convert any string to function/method.
我不确定你想在这里实现什么。这没有任何意义。
一般来说,要使用命令行参数填充结构字段,您可以执行如下操作。
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
(or 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
to avoid manually declaring command-line flags. Another alternative is 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
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