英文:
Using instances of generic types as return value type in a Hyperledger chain code written in GO
问题
在我的项目中,我正在使用一个类似于以下定义的包装器结构:
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存储库的链接。
我尝试手动将Wrapper
中的通用类型T
替换为Bar
,创建结构体:
type WrapperBar struct {
Foo int
Data Bar
}
如果我现在将函数签名调整为:
func(contract *MyContract) DoSomething() *WrapperBar
它可以正常工作。不幸的是,我多次使用了具有不同类型实例化的Wrapper
结构。因此,尽管手动创建所有类型可能是一种解决方法,但显然不是一种非常优雅的解决方法。
是否有另一种解决方法,以便我仍然可以使用通用的Wrapper
结构?
我目前使用的是go
版本1.18
和fabric-contract-api-go
版本v1.1.1
。
英文:
In my project, I am using a wrapper structure, that is defined similar to this:
type Wrapper[T any] struct {
Foo int
Data T
}
Additionally, my chain code offers a method with the following signature
func(contract *MyContract) DoSomething() *Wrapper[mypkg.Bar]
where Bar
is a simple structure defined - for example - like this:
package mypkg
struct Bar {
Foo string
Bar string
}
Anyhow, if I try to deploy my chaincode, I get the following error:
Error compiling schema for MyContract[DoSomething]. Return schema invalid. Object has no key 'Wrapper[[]<part of module name>'
Strangely, the part with Wrapper[[]<part of module name>
is cropped. So only part of the module name is showing, and, as you can see, the bracketing is wrong: The second closing bracket is missing (so that is not a mistake made by me). The name of my module is the link to the GitHub repository.
I have tried to manually replace the generic type T
in Wrapper
with Bar
by creating the structure
type WrapperBar struct {
Foo int
Data Bar
}
If I now adapt the function signature to
func(contract *MyContract) DoSomething() *WrapperBar
it works just fine. Unfortunately, I am using the structure Wrapper
several times with different
type instantiations. So although creating all the types manually would be a workaround, it is obviously not a very elegant one.
Is there another workaround so that I can still use my generic Wrapper
structure?
I am currently using go
in version 1.18
and fabric-contract-api-go
in version v1.1.1
.
答案1
得分: 2
这个时候的Go contract-api不支持Go泛型。我能建议的解决方法是你已经尝试过的那个,就是在这个问题中提到的,或者你可以在不使用contract API的情况下编写你的链码。这里有一个示例:https://github.com/hyperledger/fabric-samples/tree/main/chaincode/marbles02/go,它是一个不使用contract-api的实现。
你的实现将需要在链码中做更多的工作,比如提供自己的方法分派、验证和解组输入数据。
你可以在https://github.com/hyperledger/fabric-contract-api-go上提出一个问题,并最好贡献一个解决这个问题的PR,因为我不能确定是否会在将来支持这个功能。
英文:
The Go contract-api at this time doesn't support Go Generics, the only workarounds I can suggest are the one that you have tried noted in this question or to write your chaincode without using the contract API, there is an example here https://github.com/hyperledger/fabric-samples/tree/main/chaincode/marbles02/go of an implementation that doesn't use the contract-api.
Your implemention will have to do more work in your chaincode such as providing your own method dispatching, validating and unmarshalling the input data
You could raise an issue at https://github.com/hyperledger/fabric-contract-api-go and ideally also contribute a PR that addresses this issue as I can't say when or if this would ever be supported.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论