如何在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
相关产品推荐
相关产品推荐

