如何创建一个具有推断的可空可比较泛型的函数?

huangapple go评论75阅读模式
英文:

How to make a function with inferred nillable comparable generics?

问题

考虑以下函数:

func NilCompare[T comparable](a *T, b *T) bool {
	if a == nil && b == nil {
		// 如果都是nil,我们认为它们相等
		return true
	}
	if a == nil || b == nil {
		// 如果其中一个是nil,则它们显然不相等
		return false
	}
	return *a == *b
}

这个函数是有效的。然而,当我调用它时,我必须提供类型,因为Go无法推断出它(cannot infer T),例如NilCompare[string](a, b),其中ab*string

如果我将T修改为*comparable,并将ab修改为T,我会得到以下错误:
cannot use type comparable outside a type constraint: interface is (or embeds) comparable

我正在使用Go 1.19.2。

$ go version
go version go1.19.2 linux/amd64

具有讽刺意味的是,我的IDE(GoLand 2022.2.3)认为上述函数应该是可推断的。

有没有办法使接受可为空的comparable的函数可推断?或者我是否做得正确,但需要帮助go函数?

英文:

Consider the following function:

func NilCompare[T comparable](a *T, b *T) bool {
	if a == nil && b == nil {
		// if both nil, we consider them equal
		return true
	}
	if a == nil || b == nil {
		// if either is nil, then they are clearly not equal
		return false
	}
	return *a == *b
}

This function works. However, when I call it, I must supply the type, as Go cannot infer (cannot infer T) it, e.g. NilCompare[string](a, b), where a and b are *string.

If I modify T to be *comparable and a and b to be T, I get this error instead:
cannot use type comparable outside a type constraint: interface is (or embeds) comparable

I am using Go 1.19.2.

$ go version
go version go1.19.2 linux/amd64

Ironically, my IDE (GoLand 2022.2.3) believes that the above function should be inferrable.

Is there a way to make a function that take nillable comparable and make it inferrable? Or am I doing it correct, but I need to help the go function along?

答案1

得分: 1

类型推断在这种情况下是有效的。你不能仅仅使用字面量nil,比如NilCompare(nil, nil)来推断T,因为它并不真正携带类型信息。

要测试带有nil的函数,可以这样做:

package main

import "fmt"

func main() {
	var a *string = nil
	var b *string = nil
    // a和b是显式类型
    res := NilCompare(a, b) // 推断出T的类型
	fmt.Println(res) // true
}

这样也可以:

func main() {
    // 字面量nil转换为*string类型
    res := NilCompare((*string)(nil), (*string)(nil)) // 推断出T的类型
	fmt.Println(res) // true
}
英文:

Type inference just works, in this case. You simply can't infer T using literal nil, as NilCompare(nil, nil) because that doesn't really carry type information.

To test your function with nils do this:

package main

import "fmt"

func main() {
	var a *string = nil
	var b *string = nil
    // a and b are explicitly typed
    res := NilCompare(a, b) // T inferred
	fmt.Println(res) // true
}

this also would work:

func main() {
    // literal nil converted to *string
    res := NilCompare((*string)(nil), (*string)(nil)) // T inferred
	fmt.Println(res) // true
}

huangapple
  • 本文由 发表于 2022年10月7日 19:33:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/73986549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定