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

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

確定是否可以將任意類型的實例設置為任意類型的值

確定是否可以將任意類型的實例設置為任意類型的值

Go
元芳怎么了 2022-08-01 11:06:38
是否可以確定(使用)任意類型的實例是否可以設置為任意值,即確定是否由于類型不兼容而導致死機?reflectValue.Set()MCVE如下所述。我想知道的是有效的“我可以在不使用延遲/恢復構造的情況下編寫嗎?set()我想避免不僅因為它看起來很丑陋,而且因為可能因為其他原因而恐慌。deferValue.Set()請注意,這不僅僅是比較類型相等的問題,如下面的示例所示。o2package mainimport (    "fmt"    "reflect")// set a value V to interface i, returning true if this can be done, else false//// CAN WE WRITE THIS WITHOUT HAVING TO USE DEFER / RECOVER?//func set(v reflect.Value, i interface{}) bool {    success := true    defer func() {        if r := recover(); r != nil {            success = false        }    }()    v.Set(reflect.ValueOf(i))    return success}// get the type of a typed nilfunc getType(typedNil interface{}) reflect.Type {    return reflect.TypeOf(typedNil).Elem()}func main() {    t1 := getType((*int)(nil))    o1 := reflect.New(t1)    t2 := getType((*interface{})(nil))    o2 := reflect.New(t2)    var ok bool    var aInt = 456    var aString string = "hello"    var aUint uint = 123    // Set o1 to various types        ok = set(o1.Elem(), aInt) // Should return true    fmt.Printf("After o1 set to aInt returned %v: obj is type %T content '%v'\n", ok, o1.Elem().Interface(), o1.Elem().Interface())    ok = set(o1.Elem(), aString) // Should return false    fmt.Printf("After o1 set to aString returned %v: obj is type %T content '%v'\n", ok, o1.Elem().Interface(), o1.Elem().Interface())    ok = set(o1.Elem(), aUint) // Should return false    fmt.Printf("After o1 set to aUint returned %v: obj is type %T content '%v'\n", ok, o1.Elem().Interface(), o1.Elem().Interface())}
查看完整描述

1 回答

?
30秒到達戰場

TA貢獻1828條經驗 獲得超6個贊

反映。類型有一個方法:Type.AssignableTo()


// AssignableTo reports whether a value of the type is assignable to type u.

AssignableTo(u Type) bool

因此,您可以使用它來簡化您的函數:set()


func set(v reflect.Value, i interface{}) bool {

    if !reflect.TypeOf(i).AssignableTo(v.Type()) {

        return false

    }

    v.Set(reflect.ValueOf(i))

    return true

}

輸出將相同(在Go Playground上嘗試):


After o1 set to aInt returned true: obj is type int content '456'

After o1 set to aString returned false: obj is type int content '456'

After o1 set to aUint returned false: obj is type int content '456'


After o2 set to aInt returned true: obj is type int content '456'

After o2 set to aString returned true: obj is type string content 'hello'

After o2 set to aUint returned true: obj is type uint content '123'

您也可以(另外)調用 Value.CanSet() 來檢測某些“不可設置”的情況:


可以設置報告是否可以更改 v 的值。僅當 Value 可尋址且未通過使用未導出的結構字段獲取時,才能更改該值。如果 CanSet 返回 false,則調用 Set 或任何特定于類型的 setter(例如,SetBool、SetInt)將會死機。


查看完整回答
反對 回復 2022-08-01
  • 1 回答
  • 0 關注
  • 112 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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