登录
首页 >  Golang >  Go问答

类型参数中下划线标识符的作用是什么?

来源:stackoverflow

时间:2024-02-18 18:21:22 203浏览 收藏

积累知识,胜过积蓄金银!毕竟在Golang开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《类型参数中下划线标识符的作用是什么?》,就带大家讲解一下知识点,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~

问题内容

这两个函数有什么区别?

func f[_ string, p string](s ...p) {
    fmt.println(s)
}
func f[p string](s ...p) {
    fmt.Println(s)
}

为什么首先要在类型参数中放置一个空白标识符?


正确答案


使用下划线 _ 代替类型参数名称只是表明该类型参数未在函数作用域内使用。

在您的示例代码中,它实际上并没有什么区别; f 的两个版本都可以称为 f("blah"),而无需提供显式类型参数。但这是可能的,因为约束 string 限制为精确类型。它只能是 string,因此类型推断仍然有效。

如果将其更改为近似类型,则必须显式实例化它:

// can't infer first type param from anywhere
func f[_ ~string, p ~string](s ...p) {
    fmt.println(s)
}

func main() {
    // must supply first type param, may omit second one
    f[string]("blah")
}

在约束不是精确类型的现实场景中,下划线可能会强制调用者指定类型参数:这实际上会破坏向后兼容性,因为客户端代码确实必须更新才能工作。

需要明确的是,这适用于彼此独立的类型参数。如果带下划线的类型参数可以从另一个类型参数推断出来,那么它仍然可以在没有显式实例化的情况下进行编译:

// called as foo("blah")
func foo[t ~string, p *t](t t) {
    var p p = &t
    fmt.println(t, p)
}

// still called as foo("blah")
func foo[t ~string, _ *t](t t) {
    fmt.println(t)
}

但是值得注意的是,如果一个函数有两个可以从参数推断出来的独立类型参数:

func f[t any, u any](t t, u u) {
    fmt.println(t, u)
}

...使 u 不可推断意味着也删除 u u 参数,因此您已经有了向后不兼容的更改。

// one less argument, requires major version upgrade anyway
func foo[t any, _ any](t t) {
    fmt.println(t, u)
}

如果使用方法,情况就不同了。由于方法无法指定未在接收器类型上声明的类型参数,因此使用下划线的情况更为频繁。可能只是某些方法不需要所有类型参数。那么下划线恰当地反映了这一点:

type Foo[T,U any] struct {
    ID  T
    Val U
}

// we do not need to reference U here
func (f *Foo[T,_]) SetID(t T) {
    f.ID = t
}

// we do not need to reference T here
func (f *Foo[_,U]) SetVal(v U) {
    f.Val = v
}

终于介绍完啦!小伙伴们,这篇关于《类型参数中下划线标识符的作用是什么?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>