V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
zhuoyue100
V2EX  ›  问与答

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

  •  
  •   zhuoyue100 · 192 天前 · 712 次点击
    这是一个创建于 192 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    8 条回复    2024-06-18 17:40:27 +08:00
    body007
        1
    body007  
       192 天前
    body007
        2
    body007  
       192 天前
    @body007 对了,还有接口类型也能断言。
    dcalsky
        3
    dcalsky  
       192 天前
    建议用 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
        4
    dcalsky  
       192 天前
    @body007 这样是不行的,function type 是 unique ,不能通过断言比较。
    zhuoyue100
        5
    zhuoyue100  
    OP
       192 天前
    zhuoyue100
        6
    zhuoyue100  
    OP
       192 天前
    @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
        7
    CEBBCAT  
       192 天前
    你对于 Go 的语法还需要更多学习。

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

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

    关于楼上的问题,type fn 入参是 content.Context ,test()返回的函数入参是 *gin.Context ,不是一个类型,Go 目前不支持基于 interface 实现的函数替换,更常见的做法是,基于对入参 ctx 的 _, ok := ctx.(*gin.Context) 这样的判断
    zhuoyue100
        8
    zhuoyue100  
    OP
       192 天前
    @CEBBCAT 感谢,_, ok := ctx.(*gin.Context) 这种可以实现我的需求,但是后续有其他的 content.Context 实现类型那就要在写一个判断了。 你刚才说的 ”目前不支持基于 interface 实现的函数替换” 对我很有用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1475 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 17:10 · PVG 01:10 · LAX 09:10 · JFK 12:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.