dp815292 2014-10-01 06:18
浏览 70

功能类型的Golang空接口{}

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)
}

We can call it by

Println(3)
Println(1.5)
Println("Hello")

But I can't achieve the same thing for function type

func Map(fn func( interface{} )) {  
  ......  
}  

I cannot call this with
Map( func( i int) {......} )
because the type func(int) is different from the type func( interface{} ).

But when I define func( interface{} ), I really mean any type of the input parameters. How can I achieve this in Golang?

  • 写回答

2条回答 默认 最新

  • duanbo1659 2014-10-01 06:48
    关注

    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

    评论

报告相同问题?

悬赏问题

  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)