首先展示一下代码:
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 1
一定要传的话只能这样写
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
|