在Golang中返回联合类型。

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

return union type in Golang

问题

我想尝试在Golang中实现联合类型,就像这个答案中所示。

我尝试了以下代码:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

type intOrString interface {
	int | string
}

func main() {
	fmt.Println(measure())

}
func measure[T intOrString]() T {
	rand.Seed(time.Now().UnixNano())
	min := 20
	max := 35
	temp := rand.Intn(max-min+1) + min

	switch {
	case temp < 20:
		return "low" // 'low' (类型为string) 无法表示为类型T
	case temp > 20:
		return T("high") // 无法将类型为'string'的表达式转换为类型'T'
	default:
		return T(temp)

	}
}

那么我该如何将类型为'string'或'int'的表达式转换为类型'T'呢?

英文:

I want to try the union type implementation in Golang as in this answer
I try this:

package main

import (
	&quot;fmt&quot;
	&quot;math/rand&quot;
	&quot;time&quot;
)

type intOrString interface {
	int | string
}

func main() {
	fmt.Println(measure())

}
func measure[T intOrString]() T {
	rand.Seed(time.Now().UnixNano())
	min := 20
	max := 35
	temp := rand.Intn(max-min+1) + min

	switch {
	case temp &lt; 20:
		return &quot;low&quot; //&#39;&quot;low&quot;&#39; (type string) cannot be represented by the type T
	case temp &gt; 20:
		return T(&quot;high&quot;) //Cannot convert an expression of the type &#39;string&#39; to the type &#39;T&#39;
	default:
		return T(temp)

	}
}

so how I can convert an expression of the type 'string' or 'int' to the type 'T'.

答案1

得分: 5

你误解了泛型的工作原理。对于你的函数,在调用函数时必须提供一个类型。比如 fmt.Println(measure[string]()),在这种情况下,你期望得到一个 string 类型的结果。如果你像这样调用它 measure[int](),那么你期望得到一个 int 类型的结果。但是你不能不带类型参数调用它。泛型是用于在不同类型之间共享相同逻辑的函数。

对于你想要的,你必须将结果声明为 any,然后检查它是字符串还是整数。示例代码如下:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	res := measure()
	if v, ok := res.(int); ok {
		fmt.Printf("The temp is an int with value %v", v)
	}
	if v, ok := res.(string); ok {
		fmt.Printf("The temp is a string with value %v", v)
	}
}

func measure() any {
	rand.Seed(time.Now().UnixNano())
	min := 20
	max := 35
	temp := rand.Intn(max-min+1) + min

	switch {
	case temp < 20:
		return "low"
	case temp > 20:
		return "high"
	default:
		return temp
	}
}

或者,如果你只想打印出结果(不需要知道类型),你甚至不需要检查它,只需调用 fmt.Printf("The temp is %v", res)

英文:

You misunderstand how generics work. For your function you must provide a type when you call the function. Like fmt.Println(measure[string]()), so in this case you expect to get a string from it. If you call it like measure[int]() then you expect an int as a result. But you cannot call it without a type parameter. Generics are for function which share the same logic for different types.

For what you want, you must use any as a result, then check it if it's a string or an int. Example:

package main

import (
	&quot;fmt&quot;
	&quot;math/rand&quot;
	&quot;time&quot;
)

func main() {
	res := measure()
	if v, ok := res.(int); ok {
		fmt.Printf(&quot;The temp is an int with value %v&quot;, v)
	}
	if v, ok := res.(string); ok {
		fmt.Printf(&quot;The temp is a string with value %v&quot;, v)
	}
}

func measure() any {
	rand.Seed(time.Now().UnixNano())
	min := 20
	max := 35
	temp := rand.Intn(max-min+1) + min

	switch {
	case temp &lt; 20:
		return &quot;low&quot;
	case temp &gt; 20:
		return &quot;high&quot;
	default:
		return temp
	}
}

Or if you want to just print it out (and don't need to know the type), you don't even need to check it, just call fmt.Printf(&quot;The temp is %v&quot;, res).

huangapple
  • 本文由 发表于 2022年3月31日 06:19:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/71684764.html
匿名

发表评论

匿名网友

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

确定