协议缓冲区是否可与F#一起使用?

4

我有一个疑问 - protocol buffers 是否可以与 F# 一起使用?有什么需要注意的地方吗?


你指的是这个吗:http://code.google.com/p/protobuf-net/?我预计会有与序列化类似的API的“通常”问题 - 你可能需要编写可变类(在F#中有点丑陋),并且它可能无法与F#记录一起使用...(但我没有使用过这个库)。 - Tomas Petricek
作为protobuf-net的作者Tomas,我理解这个问题是关于一般情况下的protobuf(协议缓冲区实现的更广泛家族)。 - Marc Gravell
1
刚刚发现这个,但看起来已经被遗弃了:http://code.google.com/p/froto/ - Marc Gravell
我用大约200行F#代码编写了一个Google协议缓冲区实现。 - J D
2
@Jon 一个完整的实现?看到那将会很有趣...并且更有趣的是进行性能分析。 - Marc Gravell
@Marc:我认为这是完整的实现,是的。@Dmitri:我宁愿卖掉它。;-) - J D
3个回答

9

我只是在试图回答这个问题。

Marc Gravell的protobuf-net项目因使用标准的.NET习语而可以直接与F#配合使用。您可以使用属性进行序列化,而无需编写.proto文件或执行任何两阶段编译,或者您可以从标准.proto文件生成必要的代码。性能对于.NET来说很好,但比OCaml内置的Marshal模块慢得多。然而,此库强制使您使每个消息类型中的每个字段都是可变的。这实际上是适得其反的,因为消息应该是不可变的。此外,文档还有很多需要改进的地方,但这毕竟是免费软件。

我还没有成功地让Jon Skeet的protobuf-csharp-port库工作。

理想情况下,您应该能够将所有内置的F#类型(元组、记录、联合、列表、集合、映射等)直接序列化到这种线格式,但现有的开源解决方案都无法做到这一点。我还担心这些解决方案的复杂性:Jon Skeet的代码和注释总共有88,000行!

顺便说一句,我很失望地看到Google协议缓冲区没有指定DateTimedecimal数字的标准格式。

我还没有看过Proto#,甚至找不到Froto的下载链接。还有ProtoParser,但它只解析.proto文件,无法实际序列化任何内容。


2
作为更新,我想说,CLIMutable 与 protobuf-net 更容易使用了,但似乎仍不能开箱即用地与 F# 内置类型(如列表)兼容。Froto 似乎仍然活跃,但需要两个阶段。 - Anthony

4
我期望我的翻译Marc Gravell的翻译都可以很好地与F#一起使用,就像其他.NET库一样。换句话说,这两个翻译并没有以可能产生惯用F#代码的方式编写,但它们应该能够正常工作。
我的翻译将生成C#代码,因此您需要将其构建为独立的项目,用于序列化模型 - 但是这应该可以与F#互操作而不会出现任何问题。生成的类型是不可变的(带有可变构建器),因此在F#上下文中应该有所帮助。
当然,您也可以始终获取任一项目的核心部分,并提供惯用的F#解决方案 - 无论是将整个项目移植到F#中,还是使用现有库与F#代码生成器和辅助函数等进行处理,或者类似的方法。

谢谢!你能详细讲解一下你和马克版本的区别吗?只是好奇为什么你们不一起合作完成这个项目... - Dmitri Nesteruk
@Dmitri:Marc的版本更符合.NET的惯例,从头开始构建。它与WCF等非常好地集成在一起。我的版本是Java版本的移植,更适合使用其他语言并希望有一个一致的API的人。 - Jon Skeet

4

这里没有一个特定于F#的解释,但有一个OCaml的解释,或者有一个.NET“通用”的解释(protobuf-net)。

老实说,我只是还没尝试过使用protobuf-net处理F#对象,部分原因是我不太了解F#,但如果您可以创建POCO,则应该可以正常工作。它们需要具有某种可变性(甚至可能只是私有可变性),才能与protobuf-net一起使用。

如果您愿意生成C# DTO并从F#中消耗它,则protobuf-net或Jon's port应该可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接