
首先展示一下代码:
package main import "fmt" type Obj1 struct { } type Callback1 func(interface{}) type Callback2 func(*Obj1) func handle1(a int,fn Callback1) { //do nothing } func handle2(a int,fn Callback2) { //do nothing } func logic(o *Obj1) { fmt.Println(o) } func main() { handle1(1,logic) handle2(2,logic) } 为什么 handle1 函数会编译不通过,interface{}不是可以代表任意类型吗?
1 egen 2021-09-18 17:34:10 +08:00 cb1 cb2 的函数签名不一致 |
2 Trim21 2021-09-18 17:43:08 +08:00 就跟[]int 不能赋值[]interface{}一样... |
3 AlbertGuo 2021-09-18 17:51:56 +08:00 interface{}我理解成一种类型,Callback1 和 logic 的参数是不同类型 |
4 MoYi123 2021-09-18 17:52:53 +08:00 一定要传的话只能这样写 type Callback1 interface{} func handle1(a int, fn Callback1) { o := reflect.ValueOf(&Obj1{}) reflect.ValueOf(fn).Call([]reflect.Value{o}) } |
5 anyxchachapoly 2021-09-18 18:05:59 +08:00 建议再去好好读下 golang 官方指导,这明显你误解了 interface & type 的概念 |
6 iyear 2021-09-18 18:18:07 +08:00 未曾设想的道路 |
7 yuanchao 2021-09-18 18:26:34 +08:00 interface{} 也是一种类型 |
9 mcfog 2021-09-18 19:15:25 +08:00 go 语言厉害就厉害在朴素 1. 方法调用实参和形参类型要求是 assignable https://golang.org/ref/spec#:~:text=arguments%20must%20be%20single-valued%20expressions%20assignable%20to%20the%20parameter%20types%20of%20F 2. assignable 规则 https://golang.org/ref/spec#Assignability 对于两边都是 func 来说这啊那啊的都不适用,就是要求 identical 3. type identical 规则 3.1 func 要 identical 必须出入参对应位置 identical https://golang.org/ref/spec#:~:text=corresponding%20parameter%20and%20result%20types%20are%20identical%2C 3.2 interface 和*Obj 不 identical,因为一个是 interface type 另一个是 pointer type ref/spec 虽然有点拗口,但又短又精髓,查起来非常容易 |
10 iceheart 2021-09-18 19:28:55 +08:00 via Android 肯定不行啊,interface 占 16 字节,结构体指针占 8 字节,C 语言这种都不行 |
11 Nzelites 2021-09-18 21:22:36 +08:00 你需要的大概是 handle(interface{}) 然后里面再断言回来 |
12 masterclock 2021-09-18 22:28:27 +08:00 不神秘,没有“类型推导”,go 编译器只做最基础的事情,不要深入理解。 Typescript 类的语言能这么干,函数 auto variance Scala 类的定义好 variance 也能干 |
13 liuhan907 2021-09-18 23:07:33 +08:00 via Android 其实就是 go 没有协变。 |
14 thinkingbullet 2021-09-20 12:00:53 +08:00 当直接调用函数和把函数作为参数调用是两种不同的情况,前者如果参数是 interface 类型则可以传递任意类型,后者需要把函数整体作为参数考虑,需要严格的类型对比(也就是函数签名完全一致),一个是 interface type 另一个是 pointer type |