在我的项目中,我使用了一个包装器结构,其定义类似于:
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理想情况下,还可以贡献一份解决这个问题的公关,因为我无法确定何时或是否会支持这一点。