亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何根據結構字段類型對值進行類型轉換?

如何根據結構字段類型對值進行類型轉換?

Go
九州編程 2022-06-21 10:44:09
我正在嘗試創建一個填充給定字段的方法struct,但是要設置正確的值,我需要轉換值以檢查類型是否與結構字段類型匹配。例子:type S struct {    Name string    Age int}該值將始終是string因為它來自 URL。const stubQuery = "name=sam&page=30"query, _ := url.ParseQuery(stubQuery)// e.g result: {"name": ["sam"], "age": ["30"]}我已經設法迭代query并從S結構中獲取字段,但是我怎樣才能獲取字段類型并將“30”轉換為結構類型?structValue := reflect.ValueOf(&S{}).Elem()structFieldValue := structValue.FieldByName("Age")structFieldType := structFieldValue.Type()val := reflect.ValueOf("30")if structFieldType != val.Type() {} // Always false
查看完整描述

2 回答

?
UYOU

TA貢獻1878條經驗 獲得超4個贊

應用程序必須將字符串解析為可分配給該字段的值。


使用類型開關和值開關查找要解析的類型或種類。


使用strconv 包解析數值和布爾值。使用time 包來解析時間和持續時間。


這是一些示例代碼:


v := reflect.ValueOf(&s).Elem()

t := v.Type()

for i := 0; i < t.NumField(); i++ {

    sf := t.Field(i)


    // Get value from query. Skip if not set.

    values, ok := query[strings.ToLower(sf.Name)]

    if !ok || len(values) == 0 {

        continue

    }


    // Use type switch for specific types.

    switch f := v.Field(i).Addr().Interface().(type) {


    case *time.Time:

        var err error

        *f, err = time.Parse(time.RFC3339, values[0])

        if err != nil {

            log.Fatal(err)

        }

    case *time.Duration:

        var err error

        *f, err = time.ParseDuration(values[0])

        if err != nil {

            log.Fatal(err)

        }


    default:

        // The specific type was not handled. Fallback

        // to using the field kind. This allows us to

        // handle all numeric and bool types without knowing

        // those types explicitly.


        switch sf.Type.Kind() {

        case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:

            n, err := strconv.ParseInt(values[0], 10, sf.Type.Bits())

            if err != nil {

                log.Fatal(err)

            }

            v.Field(i).SetInt(n)

        case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:

            n, err := strconv.ParseUint(values[0], 10, sf.Type.Bits())

            if err != nil {

                log.Fatal(err)

            }

            v.Field(i).SetUint(n)

        case reflect.Float64, reflect.Float32:

            n, err := strconv.ParseFloat(values[0], sf.Type.Bits())

            if err != nil {

                log.Fatal(err)

            }

            v.Field(i).SetFloat(n)

        case reflect.Bool:

            b, err := strconv.ParseBool(values[0])

            if err != nil {

                log.Fatal(err)

            }

            v.Field(i).SetBool(b)

        case reflect.String:

            v.Field(i).SetString(values[0])

        default:

            log.Fatal("unknown type")

        }

    }

}

首先檢查類型,以便將 time.Duration 解析為持續時間而不是整數。


將 log.Fatal 調用替換為適合您的場景的錯誤處理。


查看完整回答
反對 回復 2022-06-21
?
牧羊人nacy

TA貢獻1862條經驗 獲得超7個贊

val := reflect.ValueOf("30")

傳入參數的類型("30"在您的示例代碼中)是string。它的類型永遠不會匹配數字字段的類型。


你必須檢查structFieldType,以確定你應該應用什么轉換val。


另一種方法可能是向您的結構添加一個特定的方法來填充它的字段:


AssignFields(in url.Values) error

# or

AssignField(name string, value string) error


查看完整回答
反對 回復 2022-06-21
  • 2 回答
  • 0 關注
  • 152 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號