我正在嘗試列印一個 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)
總之,有沒有辦法將任何字串變數轉換為函式/方法。非常感謝提前
牧師注:例如。我會寫信給終端:
go run main.go "field1"
程式會做這樣的事情
fmt.Fprintf(writer, "option.field is %v", someFuncThatConcatenatesThisTwo("option." os.Args[1]))
順便說一句,有多個欄位要呼叫。預定義當然可以解決某些情況,但我想學習的是另一回事。
uj5u.com熱心網友回復:
總之,有沒有辦法將任何字串轉換為函式/方法。
我不確定你想在這里實作什么。這沒有任何意義。
通常,要使用命令列引數填充結構欄位,您可以執行以下操作。
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。
編輯
在進一步澄清之后,您似乎希望使用 writer 有選擇地寫入結構的欄位,并且希望使用位置命令列引數來指定要寫入的欄位。
我認為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 demo: https://play.golang.org/p/sch53l2bq4O
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/352553.html
