猿问

Go 中的通用编程。避免硬编码类型断言

我正在编写一个通用缓存机制,我需要在结构中设置一些属性,只知道它们的reflect.Type、属性名称和reflect.Value 要在属性中设置,但我无法避免类型断言,这使得我的代码不通用...


func main() {

    addressNew := Address{"New Address description!"}


    // In the real problem, i know the reflect.Type of value, but

    // the struct came to me as a interface{}, just like this method

    // Return many kinds of values from redis as interface{}, 

    // (Customer, Order, Address, Product, SKU etc), in a generic way,

    // but returns the reflect.Type of value also.

    interfaceSomeValue := getMyValue()


    fmt.Printf("%v", interfaceSomeValue)

    fmt.Println("")


    // This portion of code comes from my cache mechanism, that is a library 

    // used by other projects. My cache lib really can't know all others

    // type structs to perform the type assertion, but the cache mechanism know 

    // the reflect.Type of the interface. 

    // If you try at this way, will cause a panic by try to access a FieldByName

    // in a interface, because the Customer comes from getMyValue and 

    // becomes a interface{}, and now a type assertion is 

    // required -> http://play.golang.org/p/YA8U9_KzC9

    newCustomerNewAttribute := SetAttribute(&interfaceSomeValue, "Local", interface{}(addressNew), reflect.TypeOf(Customer{}))


    fmt.Printf("%v", newCustomerNewAttribute)

    fmt.Println("")

}


func SetAttribute(object interface{}, attributeName string, attValue interface{}, objectType reflect.Type) interface{} {

    if reflect.ValueOf(object).Kind() != reflect.Ptr {

        panic("need a pointer")

    }


    value := reflect.ValueOf(object).Elem()

    field := value.FieldByName(attributeName)

    valueForAtt := reflect.ValueOf(attValue)

    field.Set(valueForAtt)

    return value.Interface()

}


万千封印
浏览 181回答 1
1回答
随时随地看视频慕课网APP

相关分类

Go
我要回答