Golang Go语言如何使用 struct 泛型?
Golang Go语言如何使用 struct 泛型?
代码:
type A struct {
AID string
}
type B struct {
BID string
}
type AB interface {
A | B
}
func Get[val AB]() val {
return A{
AID: "AID",
}
}
定义了两个 struct ,A 和 B ,并用定义了一个 constraint 包含了 A ,B 两个 struct ,那么 Get 函数返回 A ,为什么会提示"cannot use (A literal) (value of type A) as val value in return"?
刚刚接触 go 的泛型,还不是特别理解,网上也没搜到相关问题,请教一下大家,这里是哪里的错误?
更多关于Golang Go语言如何使用 struct 泛型?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
楼主代码确定没问题吗,为什么我报错了
大道至简 /go 头
interface 相当于虚基类,配合切面使用基本就能达到其他语言 class 的效果:
gist.github.com/lesismal/e2203edd06a17fa5043bbfdbf6cbbaf7
因为这里泛型不能这么用…
定义 A|B 的时候不是或关系,而是需要 AB 都满足相同约束,你这个地方是不满足的。甚至你把 B 改成
type B struct {
AID string
BID string
}
都是不行的… 原因是 A 不满足 BID 约束
type A struct {
AID string
BID string
}
type B struct {
AID string
BID string
}
这样也是不行的
func Show[val AB](v val) {
fmt.Println(v)
}
func main() {
a := A{AID: “aid”}
b := B{BID: “bid”}
Show(a)
Show(b)
}
----
约束应该是可以这么用的
还没认真看过 go 的范型,所以不是很了解
大概逻辑是,范型展开的时候,需要根据具体的 代码(及 调用 Get/Show 的代码)中的类型信息( concrete type )进行约束检查,并展开成 concrete type 的代码, 不能用具体返回值来推断 函数返回类型 不然如下代码应该怎么办呢
----
func FuncA[val AB](yes bool) val {
if yes {
return A{
AID: “aid”
}
} else {
return B{
BID: “bid”
}
}
}
----
你想用的是多态吧。。。
type A struct {
AID string
}
type B struct {
BID string
}
type AB interface {
}
func Get() AB {
return A{
AID: “AID”,
}
}
// -------------------
type AX struct {
AID string
}
type BX struct {
AID string
}
type ABX interface {
AX | BX
}
func GetXval ABX val {
return val{
AID: “AID”,
}
}
// -------------------
func main() {
fmt.Println(Get())
fmt.Println(GetXAX, GetXBX)
}
union 不支持 struct ,只支持基本类型
测试了下,应该是支持的,只不过很鸡肋,貌似没啥卵用。<br>package main<br><br>import (<br> "fmt"<br> "runtime"<br>)<br><br>type A struct {<br> AID string<br>}<br><br>type B struct {<br> BID string<br>}<br><br>type AB interface {<br> A | B<br>}<br><br>func Show[val AB](v val) {<br> pc := make([]uintptr, 10) // at least 1 entry needed<br> runtime.Callers(0, pc)<br> f := runtime.FuncForPC(pc[0])<br> fmt.Printf("%s => %x\n", <a target="_blank" href="http://f.Name" rel="nofollow noopener">f.Name</a>(), f.Entry())<br> fmt.Println(v)<br>}<br><br>func main() {<br> a := A{AID: "aid"}<br> b := B{BID: "bid"}<br> Show(a)<br> Show(b)<br> Show(A{AID: "test"})<br><br>}<br><br>
=====
main.Show[…] => 108b0a0
{aid}
main.Show[…] => 108b280
{bid}
main.Show[…] => 108b0a0
{test}
=====
如上, A, B 两个类型,展开成了两个,Show 函数, 不过 貌似 v val 在 Show 里面什么都做不了,如果要转型成 A 或者 B 需要用 反射,要这范型何用。
请哪位大佬解惑
因为你这个地方的约束是用的 fmt.Stringer
上面的程序中直接 return 一个 var v val 就会成功,但是你直接 return 了特定类型,相当于缩小了这个约定。
抱歉这个地方忘记指明一个地方要调整了,就是上面说的那个原因。这种你这个具体例子中的情况可以使用下面的返回:
return val{
AID: “AID”,
}
具体应该不是这个约束…记不太清具体是那个了
不是的,不是实例化 Stringer 类型
那个 binary 的符号表如下(过滤了下)
Show 对 A B 两个类型有两个实例
[![HvvkV0.jpg]( https://s4.ax1x.com/2022/02/21/HvvkV0.jpg)]( https://imgtu.com/i/HvvkV0)
你这是编译完成后展开之后的情况,编译成功之后就会被展开。我说的是编译期间约束检查。
换句话说,对于#6 中的例子中,你使用 fmt.Println(v.AID)是可以编译成功的,但是对顶楼和#7 例子结合的情况,编译是无法通过的。
go 的泛型还没发布吧,要拉对应分支自己编译 go
go 官网提供的泛型教程感觉就不太行
https://taoshu.in/go/generics/design.html?utm_source=wechat_session&utm_medium=social&utm_oi=643495174752309248
不知道这个能不能解决你的问题
刚刚看到一篇文章 《 Go 泛型简明入门教程》,感觉应该这样写:(我没验证)
type A struct {
AID string
}
type B struct {
BID string
}
func Getval A | B val {
return A{
AID: “AID”,
}
}
在Go语言中,泛型是Go 1.18版本引入的一个重要特性,它允许你编写更加通用和可复用的代码。虽然Go的泛型实现相对简单,但它为处理类型参数提供了强大的支持,特别是在使用struct时。
要使用struct泛型,你需要定义一个带有类型参数的泛型类型。例如:
package main
import "fmt"
// 定义一个泛型struct,T是一个类型参数
type Pair[T any] struct {
First T
Second T
}
func main() {
// 使用int类型实例化Pair
intPair := Pair[int]{First: 1, Second: 2}
fmt.Println(intPair)
// 使用string类型实例化Pair
stringPair := Pair[string]{First: "Hello", Second: "World"}
fmt.Println(stringPair)
}
在这个例子中,Pair
是一个泛型struct,它有一个类型参数T
,这个参数可以是任何类型(由any
约束表示)。然后,我们分别用int
和string
类型实例化了Pair
。
值得注意的是,Go的泛型实现采用了类型参数列表的语法(例如[T any]
),这与一些其他编程语言(如C++或Java)的泛型语法有所不同。此外,Go的泛型约束相对简单,目前只支持接口作为约束条件,这有助于保持Go语言的简洁性和易用性。
希望这个解释能帮助你理解如何在Go语言中使用struct泛型。