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

如何在F#中初始化Google Protocol Buffers重复字段?

在F#中使用FSharp.GrpcCodeGenerator初始化Protobuf重复字段的正确方式

问题分析

你遇到的错误源于对FSharp.GrpcCodeGenerator生成的Protobuf类型结构理解偏差,错误地嵌套了重复字段的赋值逻辑,导致编译器误判未处理所有必填字段(实际empty()方法已经初始化了_UnknownFields)。

Protobuf的repeated字段经FSharp.GrpcCodeGenerator生成后,对应类型为Google.Protobuf.Collections.RepeatedField<T>,而非直接使用F#列表,你代码中{ Words = {h}}的嵌套赋值方式不符合该类型的结构要求。

正确实现方式

方式一:通过RepeatedField构造函数直接转换列表

// 将自定义类型转换为生成的Word类型序列,再转为RepeatedField
let convertedWords = words |> Seq.map InkWordToWord |> Google.Protobuf.Collections.RepeatedField<_>

// 初始化请求并赋值Words字段
let request = { Protocol.ProtoBuf.SaveVocabularyRequest.empty() with Words = convertedWords }

方式二:逐个添加元素到RepeatedField

如果需要更灵活的元素添加逻辑,可以先创建空实例,再逐个加入元素:

let convertedWords = Google.Protobuf.Collections.RepeatedField<Protocol.ProtoBuf.Word>()
words |> Seq.map InkWordToWord |> Seq.iter convertedWords.Add

let request = { Protocol.ProtoBuf.SaveVocabularyRequest.empty() with Words = convertedWords }

关键说明

  • SaveVocabularyRequest.empty()方法会自动初始化所有字段(包括_UnknownFields),因此只需在with表达式中覆盖需要修改的Words字段即可。
  • Protobuf重复字段在.NET生态中统一使用RepeatedField<T>类型,它兼容列表操作逻辑,同时适配Protobuf的序列化/反序列化机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:55:44