You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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序列化机制共同导致的预期行为:

  1. Go私有成员的访问限制:Go中以小写字母开头的标识符(如privateList)属于包级私有,仅能在定义它的foo包内部访问,其他包(包括Cadence的序列化组件、activities包)无法直接读取或写入该成员。

  2. Cadence的序列化逻辑:Activity间传递数据时,Cadence需要对结构体做序列化(转成可传输格式)和反序列化(还原为对象)操作。由于序列化代码不在foo包内,无法访问privateList,因此序列化过程不会包含该字段,反序列化后自然无法恢复其值,最终呈现为空切片。

解决思路

如果需要让结构体成员在Activity间正常传递,有两种常用方案:

  • 将私有成员改为公有(比如重命名为PrivateList),让跨包的序列化逻辑能够访问到它。
  • 在foo包内实现自定义序列化/反序列化接口(如encoding.BinaryMarshaler和encoding.BinaryUnmarshaler),手动处理私有成员的序列化流程,确保私有数据能被正确保存和恢复。

内容的提问来源于stack exchange,提问作者trivelt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 04:09:21