Empty interface{} in function type

后端 未结 2 866
没有蜡笔的小新
没有蜡笔的小新 2021-02-04 09:44

An object of any type can be assigned to an empty interface. For example, we have the following function

func Println(i interface{} ) {
  fmt.Println(i)
}


        
相关标签:
2条回答
  • 2021-02-04 10:21

    I do realise its an old discussion, but came across the post and wanted to play around with the concept of having arbitrary function func (interface{}) within another function, instead of interface{}. I could write a simple implementation, by providing an inline implementation of a function which would accept interface{}. And we can call this function from within another function

    varForGenFunc := func(in interface{}) int {                             
                        fmt.Println("type of this object: ",reflect.TypeOf(in))
                        return 1}
    
    TakeGenericFunc(varForGenFunc, variableForGen)
    

    Going by this, we can write any implementations of func(interface{}) and pass it as parameter to TakeGenericFunc

    You can play around with it here:

    https://play.golang.org/p/f5UUhyhEx7u

    0 讨论(0)
  • 2021-02-04 10:24

    It fails because the signatures don't match.

    When you call Println(3), the function isn't taking an integer as its first argument. Rather the integer gets packed inside an interface{} variable (an automatic conversion, since integers conform to the interface), and that variable is passed to the function. This conversion happens on the calling side, so the process of calling the function is different to calling a function matching func(i int).

    If you want to write a function that accepts arbitrary unary functions, you will need to declare it to take an interface{} variable as its argument and then check the value using the reflect package. The reflect package can also help you call arbitrary functions where you don't know the signature at compile time.

    For example:

    func Map(f, v interface{}) interface{} {
        fn := reflect.ValueOf(f)
        fnType := fn.Type()
        if fnType.Kind() != reflect.Func || fnType.NumIn() != 1 || fnType.NumOut() != 1 {
            panic("Expected a unary function returning a single value")
        }
        res := fn.Call([]reflect.Value{reflect.ValueOf(v)})
        return res[0].Interface()
    }
    

    This will call the given function f with the argument v and return the result. Provided v is assignable to f's first argument the call will succeed without a panic. You can experiment with this example here: http://play.golang.org/p/kkBu56JYb8

    0 讨论(0)
提交回复
热议问题