为何Cadence Activity无法传递Go结构体的私有成员?
问题:Go结构体私有成员无法通过Cadence Activity传递
在使用包含公有和私有成员的Go结构体时,发现私有成员无法被Cadence Activity复制传递。
示例代码
foo包中的结构体定义
package foo import "fmt" type Foo struct { Name string PublicList []string privateList []string } func NewFoo() *Foo { return &Foo{ Name: "Test", PublicList: []string{"A", "B", "C"}, privateList: []string{"one", "two"}, } } func (f *Foo) ShowLists() { fmt.Println("PublicList: ", f.PublicList, ", privateList: ", f.privateList) }
Activities包中的Activity定义
package activities import ( "context" "your-module-path/foo" ) type FooActivities struct{} func (a *FooActivities) NewFoo(ctx context.Context) (*foo.Foo, error) { return foo.NewFoo(), nil } func (a *FooActivities) ShowLists(ctx context.Context, f *foo.Foo) error { f.ShowLists() return nil }
Workflow调用代码
var f *foo.Foo workflow.ExecuteActivity(ctx, fooActivities.NewFoo).Get(ctx, &f) workflow.ExecuteActivity(ctx, fooActivities.ShowLists, f).Get(ctx, nil)
输出结果
PublicList: [A B C] , privateList: []
为何私有列表未按预期初始化?这是Bug还是特性?我未在Cadence文档中找到答案。
解答
这不是Cadence的Bug,而是Go语言包可见性规则与Cadence序列化机制共同导致的预期行为:
Go私有成员的访问限制:Go中以小写字母开头的标识符(如
privateList)属于包级私有,仅能在定义它的foo包内部访问,其他包(包括Cadence的序列化组件、activities包)无法直接读取或写入该成员。Cadence的序列化逻辑:Activity间传递数据时,Cadence需要对结构体做序列化(转成可传输格式)和反序列化(还原为对象)操作。由于序列化代码不在
foo包内,无法访问privateList,因此序列化过程不会包含该字段,反序列化后自然无法恢复其值,最终呈现为空切片。
解决思路
如果需要让结构体成员在Activity间正常传递,有两种常用方案:
- 将私有成员改为公有(比如重命名为
PrivateList),让跨包的序列化逻辑能够访问到它。 - 在
foo包内实现自定义序列化/反序列化接口(如encoding.BinaryMarshaler和encoding.BinaryUnmarshaler),手动处理私有成员的序列化流程,确保私有数据能被正确保存和恢复。
内容的提问来源于stack exchange,提问作者trivelt
相关产品推荐
相关产品推荐

