在GO中编写的Hyperledger链代码中使用泛型类型的实例作为返回值类型



在我的项目中,我使用了一个包装器结构,其定义类似于:

type Wrapper[T any] struct {
Foo  int
Data T
}

此外,我的链代码提供了一种具有以下签名的方法

func(contract *MyContract) DoSomething() *Wrapper[mypkg.Bar]

其中Bar是一个简单的结构,定义如下:

package mypkg
struct Bar {
Foo string
Bar string
}

无论如何,如果我试图部署我的链代码,我会得到以下错误:

Error compiling schema for MyContract[DoSomething]. Return schema invalid. Object has no key 'Wrapper[[]<part of module name>'

奇怪的是,带有Wrapper[[]<part of module name>的部分被裁剪了。所以只显示了模块名称的一部分,正如你所看到的,括号是错误的:第二个右括号不见了(所以这不是我犯的错误(。我的模块的名称是指向GitHub存储库的链接。

我尝试通过创建结构,用Bar手动替换Wrapper中的泛型类型T

type WrapperBar struct {
Foo int
Data Bar
}

如果我现在将函数签名调整为

func(contract *MyContract) DoSomething() *WrapperBar

它工作得很好。不幸的是,我多次使用结构Wrapper类型实例化。因此,尽管手动创建所有类型是一种变通方法,但它显然不是一种非常优雅的方法。

是否有其他变通方法,使我仍然可以使用我的通用Wrapper结构?我目前在1.18版本中使用go,在v1.1.1版本中使用fabric-contract-api-go

Go contract-api目前不支持Go Generics,我唯一可以建议的解决方法是您在这个问题中尝试注意的解决方法,或者在不使用合约api的情况下编写链代码,这里有一个示例https://github.com/hyperledger/fabric-samples/tree/main/chaincode/marbles02/go的实现。您的实现将不得不在链代码中做更多的工作,例如提供您自己的方法调度、验证和解组输入数据

你可以在https://github.com/hyperledger/fabric-contract-api-go理想情况下,还可以贡献一份解决这个问题的公关,因为我无法确定何时或是否会支持这一点。

最新更新