golang 类型断言不用用于函数类型吗?本人新手

187 天前
 zhuoyue100

type fn func(ctx context.Context) []string

func test(ctx context.Context) []string { return []string{"1"} }

func main() { _, ok := test.(fn) // 报错了 fmt.Println(ok) }

705 次点击
所在节点    问与答
8 条回复
body007
187 天前
body007
187 天前
@body007 对了,还有接口类型也能断言。
dcalsky
187 天前
建议用 interface 的实现来判断,如果强行判断的话,那本质是比较 function signature 。拿到 test 和 fn 的 type 然后比较即可。

```go

type fn func(ctx context.Context) []string

func test(ctx context.Context) []string {
return []string{"1"}
}

func main() {
if matchFunctionSignature(reflect.TypeOf(test), reflect.TypeOf((fn)(nil))) {
fmt.Println(true)
} else {
fmt.Println(false)
}
}

func matchFunctionSignature(a, b reflect.Type) bool {
if a.Kind() != reflect.Func || b.Kind() != reflect.Func {
return false
}

if a.NumIn() != b.NumIn() || a.NumOut() != b.NumOut() {
return false
}

for i := 0; i < a.NumIn(); i++ {
if a.In(i) != b.In(i) {
return false
}
}

for i := 0; i < a.NumOut(); i++ {
if a.Out(i) != b.Out(i) {
return false
}
}
return true
}

```
dcalsky
187 天前
@body007 这样是不行的,function type 是 unique ,不能通过断言比较。
zhuoyue100
187 天前
zhuoyue100
187 天前
@body007
@dcalsky
谢谢,还有一个问题

type fn func(ctx context.Context) []string

func test() fn {
return func(ctx *gin.Context) []string { // 这里必须传接口实现 struct 为什么不行,项目中需要这么用,有没有办法?
return []string{"1"}
}
}

func main() {
t := test()
_, ok := any(t).(fn)
fmt.Println(ok)
}
CEBBCAT
187 天前
你对于 Go 的语法还需要更多学习。

正文里面的判断,在编译期就能完成,不需要在运行期完成。代码层面,也不太会有一个 map 或者 list 能够支持你做这样动态的判断,存不下。

你可以贴一下业务场景,看看是什么场景需要这样的代码设计,坛友们可以帮你看看有没有更合适的方式。以及避免 XY 问题。

关于楼上的问题,type fn 入参是 content.Context ,test()返回的函数入参是 *gin.Context ,不是一个类型,Go 目前不支持基于 interface 实现的函数替换,更常见的做法是,基于对入参 ctx 的 _, ok := ctx.(*gin.Context) 这样的判断
zhuoyue100
187 天前
@CEBBCAT 感谢,_, ok := ctx.(*gin.Context) 这种可以实现我的需求,但是后续有其他的 content.Context 实现类型那就要在写一个判断了。 你刚才说的 ”目前不支持基于 interface 实现的函数替换” 对我很有用

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1050576

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX