热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

增强序列化与谷歌协议缓冲区?-boostserializationvsgoogleprotocolbuffers?

Doesanyonewithexperiencewiththeselibrarieshaveanycommentonwhichonetheypreferred?Were

Does anyone with experience with these libraries have any comment on which one they preferred? Were there any performance differences or difficulties in using?

对这些图书馆有经验的人有什么意见吗?使用时是否存在性能差异或困难?

11 个解决方案

#1


29  

I've played around a little with both systems, nothing serious, just some simple hackish stuff, but I felt that there's a real difference in how you're supposed to use the libraries.

我对这两种系统都做了一些尝试,没有什么严重的,只是一些简单的陈腐的东西,但是我觉得你应该如何使用这些库是有区别的。

With boost::serialization, you write your own structs/classes first, and then add the archiving methods, but you're still left with some pretty "slim" classes, that can be used as data members, inherited, whatever.

使用boost:::序列化,首先编写自己的结构/类,然后添加归档方法,但仍然保留一些非常“瘦”的类,这些类可以作为数据成员,继承,等等。

With protocol buffers, the amount of code generated for even a simple structure is pretty substantial, and the structs and code that's generated is more meant for operating on, and that you use protocol buffers' functionality to transport data to and from your own internal structures.

使用协议缓冲区,为一个简单结构生成的代码量是相当大的,生成的结构和代码更适合操作,您可以使用协议缓冲区的功能将数据传输到您自己的内部结构。

#2


42  

I've been using Boost Serialization for a long time and just dug into protocol buffers, and I think they don't have the exact same purpose. BS (didn't see that coming) saves your C++ objects to a stream, whereas PB is an interchange format that you read to/from.

我使用Boost串行化已经有很长一段时间了,我只研究了协议缓冲区,我认为它们没有相同的目的。BS(没有看到这一点)将您的c++对象保存到流中,而PB是您读取/读取的交换格式。

PB's datamodel is way simpler: you get all kinds of ints and floats, strings, arrays, basic structure and that's pretty much it. BS allows you to directly save all of your objects in one step.

PB的数据模型要简单得多:你有各种各样的ints和float,字符串,数组,基本结构,差不多就是这样。BS允许您直接将所有对象保存在一个步骤中。

That means with BS you get more data on the wire but you don't have to rebuild all of your objects structure, whereas protocol buffers is more compact but there is more work to be done after reading the archive. As the name says, one is for protocols (language-agnostic, space efficient data passing), the other is for serialization (no-brainer objects saving).

这意味着,对于BS,你可以在连接上获得更多的数据,但是你不必重新构建所有的对象结构,而协议缓冲区更紧凑,但是在读取归档之后还有很多工作要做。顾名思义,一个是用于协议(语言无关的,空间有效的数据传递),另一个是用于序列化(无需大脑的对象保存)。

So what is more important to you: speed/space efficiency or clean code?

那么,什么对您更重要:速度/空间效率还是干净代码?

#3


24  

There are a couple of additional concerns with boost.serialization that I'll add to the mix. Caveat: I don't have any direct experience with protocol buffers beyond skimming the docs.

boost还存在一些其他问题。我将添加到混合的序列化。注意:除了浏览文档之外,我没有任何使用协议缓冲区的直接经验。

Note that while I think boost, and boost.serialization, is great at what it does, I have come to the conclusion that the default archive formats it comes with are not a great choice for a wire format.

请注意,虽然我认为是boost和boost。序列化,对于它所做的很好,我得出的结论是,它附带的默认归档格式对于有线格式不是一个很好的选择。

It's important to distinguish between versions of your class (as mentioned in other answers, boost.serialization has some support for data versioning) and compatibility between different versions of the serialization library.

区分类的不同版本是很重要的(如其他答案中提到的,boost)。序列化对数据版本控制有一定的支持,并且在序列化库的不同版本之间具有兼容性。

Newer versions of boost.serialization may not generate archives that older versions can deserialize. (the reverse is not true: newer versions are always intended to deserialize archives made by older versions). This has led to the following problems for us:

新版本的提振。序列化可能不会生成旧版本可以反序列化的存档。(反过来说就不对了:新版本总是用来反序列化旧版本的存档)。这给我们带来了以下问题:

  • Both our client & server software create serialized objects that the other consumes, so we can only move to a newer boost.serialization if we upgrade both client and server in lockstep. (This is quite a challenge in an environment where you don't have full control of your clients).
  • 我们的客户端和服务器软件都创建了被另一个用户使用的序列化对象,因此我们只能转移到更新的boost。串行化如果我们同步升级客户端和服务器。(在你没有完全控制客户的环境中,这是一个相当大的挑战)。
  • Boost comes bundled as one big library with shared parts, and both the serialization code and the other parts of the boost library (e.g. shared_ptr) may be in use in the same file, I can't upgrade any parts of boost because I can't upgrade boost.serialization. I'm not sure if it's possible/safe/sane to attempt to link multiple versions of boost into a single executable, or if we have the budget/energy to refactor out bits that need to remain on an older version of boost into a separate executable (DLL in our case).
  • Boost作为一个具有共享部分的大型库捆绑在一起,而Boost库的序列化代码和其他部分(例如shared_ptr)可能在同一个文件中使用,我不能升级Boost的任何部分,因为我不能升级boot .serialization。我不确定是否有可能/安全/明智地尝试将多个版本的boost链接到一个可执行文件中,或者如果我们有预算/精力来重构那些需要在一个更老版本的boost中保留的部分,并将其添加到一个单独的可执行文件中(在我们的例子中是DLL)。
  • The old version of boost we're stuck on doesn't support the latest version of the compiler we use, so we're stuck on an old version of the compiler too.
  • 我们所使用的boost的旧版本不支持我们使用的最新版本,因此我们也不得不使用旧版本的编译器。

Google seem to actually publish the protocol buffers wire format, and Wikipedia describes them as forwards-compatible, backwards-compatible (although I think Wikipedia is referring to data versioning rather than protocol buffer library versioning). Whilst neither of these is a guarantee of forwards-compatibility, it seems like a stronger indication to me.

谷歌似乎实际上发布了协议缓冲线格式,维基百科将它们描述为向前兼容、向后兼容(尽管我认为维基百科指的是数据版本控制,而不是协议缓冲库版本控制)。虽然这两种方法都不能保证它们的兼容性,但对我来说,这似乎是一个更强烈的暗示。

In summary, I would prefer a well-known, published wire format like protocol buffers when I don't have the ability to upgrade client & server in lockstep.

总之,当我没有能力升级客户端和服务器时,我更倾向于一个众所周知的、发布的有线格式,比如协议缓冲区。

Footnote: shameless plug for a related answer by me.

脚注:无耻的插头为一个相关的答案由我。

#4


16  

Boost Serialisation

提高连载

  • is a library for writing data into a stream.
  • 是将数据写入流的库。
  • does not compress data.
  • 不压缩的数据。
  • does not support data versioning automatically.
  • 不支持数据自动版本控制。
  • supports STL containers.
  • 支持STL容器。
  • properties of data written depend on streams chosen (e.g. endian, compressed).
  • 写入数据的属性取决于所选择的流(例如endian,压缩)。

Protocol Buffers

协议缓冲区

  • generates code from interface description (supports C++, Python and Java by default. C, C# and others by 3rd party).
  • 根据接口描述生成代码(默认支持c++、Python和Java)。C, c#和其他第三方)。
  • optionally compresses data.
  • 选择压缩数据。
  • handles data versioning automatically.
  • 自动处理数据版本控制。
  • handles endian swapping between platforms.
  • 处理平台间的endian交换。
  • does not support STL containers.
  • 不支持STL容器。

Boost serialisation is a library for converting an object into a serialised stream of data. Protocol Buffers do the same thing, but also do other work for you (like versioning and endian swapping). Boost serialisation is simpler for "small simple tasks". Protocol Buffers are probably better for "larger infrastructure".

Boost序列化是一个将对象转换为序列化数据流的库。协议缓冲区做同样的事情,但也为您做其他工作(比如版本控制和endian交换)。对于“小而简单的任务”,Boost序列化更简单。协议缓冲区对于“更大的基础设施”来说可能更好。

EDIT:24-11-10: Added "automatically" to BS versioning.

编辑:24-11-10:“自动”添加到BS版本。

#5


14  

I have no experience with boost serialization, but I have used protocol buffers. I like protocol buffers a lot. Keep the following in mind (I say this with no knowledge of boost).

我没有boost序列化的经验,但是我使用了协议缓冲区。我非常喜欢协议缓冲区。请记住以下内容(我在不了解boost的情况下这样说)。

  • Protocol buffers are very efficient so I don't imagine that being a serious issue vs. boost.
  • 协议缓冲区是非常有效的,所以我不认为这是一个严重的问题与提高。
  • Protocol buffers provide an intermediate representation that works with other languages (Python and Java... and more in the works). If you know you're only using C++, maybe boost is better, but the option to use other languages is nice.
  • 协议缓冲区提供了与其他语言(Python和Java)一起工作的中间表示。还有更多的作品。如果您知道您只使用c++,那么boost可能更好,但是使用其他语言的选项是很好的。
  • Protocol buffers are more like data containers... there is no object oriented nature, such as inheritance. Think about the structure of what you want to serialize.
  • 协议缓冲区更像是数据容器……没有面向对象的本质,比如继承。考虑一下您想要序列化的结构。
  • Protocol buffers are flexible because you can add "optional" fields. This basically means you can change the structure of protocol buffer without breaking compatibility.
  • 协议缓冲区是灵活的,因为您可以添加“可选”字段。这基本上意味着您可以在不破坏兼容性的情况下更改协议缓冲区的结构。

Hope this helps.

希望这个有帮助。

#6


11  

boost.serialization just needs the C++ compiler and gives you some syntax sugar like

提振。序列化只需要c++编译器,并提供一些语法糖

serialize_obj >> archive;
// ...
unserialize_obj <

for saving and loading. If C++ is the only language you use you should give boost.serialization a serious shot.

保存和加载。如果c++是您使用的惟一语言,那么应该使用boost。序列化一个严重。

I took a fast look at google protocol buffers. From what I see I'd say its not directly comparable to boost.serialization. You have to add a compiler for the .proto files to your toolchain and maintain the .proto files itself. The API doesn't integrate into C++ as boost.serialization does.

我快速查看了谷歌协议缓冲区。在我看来,它与boost.serialization没有直接可比性。您必须为.proto文件添加一个编译器到工具链中,并维护.proto文件本身。API没有作为boost集成到c++中。序列化。

boost.serialization does the job its designed for very well: to serialize C++ objects :) OTOH an query-API like google protocol buffers has gives you more flexibility.

提振。序列化很好地完成了它设计的工作:序列化c++对象:)OTOH像谷歌协议缓冲区这样的查询api使您具有更大的灵活性。

Since I only used boost.serialization so far I cannot comment on performance comparison.

因为我只使用boost。到目前为止,我无法评论性能比较。

#7


7  

Correction to above (guess this is that answer) about Boost Serialization :

更正(猜测这是答案)关于Boost序列化:

It DOES allow supporting data versioning.

它确实支持数据版本控制。

If you need compression - use a compressed stream.

如果你需要压缩-使用压缩流。

Can handle endian swapping between platforms as encoding can be text, binary or XML.

可以处理平台之间的endian交换,因为编码可以是文本、二进制或XML。

#8


5  

I never implemented anything using boost's library, but I found Google protobuff's to be more thought-out, and the code is much cleaner and easier to read. I would suggest having a look at the various languages you want to use it with and have a read through the code and the documentation and make up your mind.

我从来没有使用boost的库实现过任何东西,但我发现谷歌protobuff的代码更经过深思熟虑,而且代码更简洁、更容易阅读。我建议您看一下您想要使用的各种语言,并阅读一下代码和文档,然后做出决定。

The one difficulty I had with protobufs was they named a very commonly used function in their generated code GetMessage(), which of course conflicts with the Win32 GetMessage macro.

我在protobufs上遇到的一个困难是,他们在生成的代码GetMessage()中指定了一个非常常用的函数,当然,这与Win32 GetMessage宏冲突。

I would still highly recommend protobufs. They're very useful.

我仍然强烈推荐神族。他们是非常有用的。

#9


2  

As with almost everything in engineering, my answer is... "it depends."

就像工程学里几乎所有的东西一样,我的答案是……“这要看情况了。”

Both are well tested, vetted technologies. Both will take your data and turn it into something friendly for sending someplace. Both will probably be fast enough, and if you're really counting a byte here or there, you're probably not going to be happy with either (let's face it both created packets will be a small fraction of XML or JSON).

这两种技术都经过了充分的测试和审查。两者都将把你的数据转换成友好的发送到某个地方。两者都可能足够快,而且如果你真的在这里或那里计算一个字节,你可能不会对两者都满意(让我们面对现实吧,两个创建的包都只是XML或JSON的一小部分)。

For me, it really comes down to workflow and whether or not you need something other than C++ on the other end.

对我来说,真正的问题在于工作流,以及在另一端是否需要c++之外的东西。

If you want to figure out your message contents first and you're building a system from scratch, use Protocol Buffers. You can think of the message in an abstract way and then auto-generate the code in whatever language you want (3rd party plugins are available for just about everything). Also, I find collaboration simplified with Protocol Buffers. I just send over a .proto file and then the other team has a clear idea of what data is being transfered. I also don't impose anything on them. If they want to use Java, go ahead!

如果您想先弄清楚您的消息内容,并且您正在从头构建一个系统,那么使用协议缓冲区。您可以以一种抽象的方式来考虑消息,然后用您想要的任何语言自动生成代码(几乎所有东西都可以使用第三方插件)。此外,我发现与协议缓冲区的协作被简化了。我只是发送了一个。proto文件,然后另一个团队很清楚什么数据被转移了。我也不把任何东西强加给他们。如果他们想使用Java,请继续!

If I already have built a class in C++ (and this has happened more often than not) and I want to send that data over the wire now, Boost Serialization obviously makes a ton of sense (especially where I already have a Boost dependency somewhere else).

如果我已经在c++中构建了一个类(这种情况经常发生),并且我现在想通过网络发送数据,那么Boost序列化显然很有意义(特别是在我已经在其他地方有了Boost依赖性的情况下)。

#10


0  

You can use boost serialization in tight conjunction with your "real" domain objects, and serialize the complete object hierarchy (inheritance). Protobuf does not support inheritance, so you will have to use aggregation. People argue that Protobuf should be used for DTOs (data transfer objects), and not for core domain objects themselves. I have used both boost::serialization and protobuf. The Performance of boost::serialization should be taken into account, cereal might be an alternative.

您可以与“真实”域对象紧密结合使用boost序列化,并序列化完整的对象层次结构(继承)。Protobuf不支持继承,因此必须使用聚合。人们认为,原buf应该用于dto(数据传输对象),而不是用于核心域对象本身。我使用了boost::序列化和protobuf。boost的性能::应该考虑序列化,谷物可能是一种替代方法。

#11


0  

I know that this is an older question now, but I thought I'd throw my 2 pence in!

我知道这是一个老问题了,但我想我还是算了!

With boost you get the opportunity to I'm write some data validation in your classes; this is good because the data definition and the checks for validity are all in one place.

有了boost,你就有机会在你的类中编写一些数据验证;这很好,因为数据定义和有效性检查都在一个地方。

With GPB the best you can do is to put comments in the .proto file and hope against all hope that whoever is using it reads it, pays attention to it, and implements the validity checks themselves.

使用GPB,您所能做的最好的事情就是在.proto文件中添加注释,并希望不管使用它的是谁,都能阅读它,关注它,并实现有效性检查。

Needless to say this is unlikely and unreliable if your relying on someone else at the other end of a network stream to do this with the same vigour as oneself. Plus if the constraints on validity change, multiple code changes need to be planned, coordinated and done.

不用说,如果您依赖于网络流的另一端的其他人以与自己同样的精力来完成这项工作,那么这是不可能的、不可靠的。另外,如果有效性约束发生变化,则需要计划、协调和完成多个代码更改。

Thus I consider GPB to be inappropriate for developments where there is little opportunity to regularly meet and talk with all team members.

因此,我认为GPB不适用于开发,在开发中几乎没有机会定期与所有团队成员见面和交谈。

==EDIT==

= = = =进行编辑

The kind of thing I mean is this:

我的意思是

message Foo
{
    int32 bearing = 1;
}

Now who's to say what the valid range of bearing is? We can have

现在谁说有效的轴承范围是多少?我们可以

message Foo
{
    int32 bearing = 1;  // Valid between 0 and 359
}

But that depends on someone else reading this and writing code for it. For example, if you edit it and the constraint becomes:

但这取决于其他人阅读并为它编写代码。例如,如果你编辑它,约束变成:

message Foo
{
    int32 bearing = 1;  // Valid between -180 and +180
}

you are completely dependent on everyone who has used this .proto updating their code. That is unreliable and expensive.

您完全依赖于使用这个.proto更新代码的每个人。这是不可靠和昂贵的。

At least with Boost serialisation you're distributing a single C++ class, and that can have data validity checks built right into it. If those constraints change, then no one else need do any work other than making sure they're using the same version of the source code as you.

至少有了Boost序列化,您将分发单个c++类,并且可以在其中内置数据有效性检查。如果这些约束发生变化,那么除了确保使用与您相同的源代码版本之外,其他人不需要做任何工作。

Alternative

替代

There is an alternative: ASN.1. This is ancient, but has some really, really, handy things:

还有一种选择:ASN.1。这是古老的,但有一些非常,非常,便利的东西:

Foo ::= SEQUENCE
{
   bearing INTEGER (0..359)
}

Note the constraint. So whenever anyone consumes this .asn file, generates code, they end up with code that will automatically check that bearing is somewhere between 0 and 359. If you update the .asn file,

注意约束。因此,每当有人使用这个。asn文件,生成代码时,他们就会使用自动检查该方位的代码在0到359之间。如果更新。asn文件,

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180)
}

all they need to do is recompile. No other code changes are required.

他们需要做的就是重新编译。不需要其他代码更改。

You can also do:

你也可以做的事:

bearingMin INTEGER ::= 0
bearingMax INTEGER ::= 360

Foo ::= SEQUENCE
{
   bearing INTEGER (bearingMin..

Note the <. And also in most tools the bearingMin and bearingMax can appear as constants in the generated code. That's extremely useful.

请注意<。在大多数工具中,bearingMin和bearingMax可以作为常量出现在生成的代码中。这是非常有用的。

Constraints can be quite elaborate:

约束条件可以非常详细:

Garr ::= INTEGER (0..10 | 25..32)

Look at Chapter 13 in this PDF; it's amazing what you can do;

请看本PDF中的第13章;你所能做的令人惊叹;

Arrays can be constrained too:

数组也可以受到约束:

Bar ::= SEQUENCE (SIZE(1..5)) OF Foo
Sna ::= SEQUENCE (SIZE(5)) OF Foo
Fee ::= SEQUENCE 
{
    boo SEQUENCE (SIZE(1..<6)) OF INTEGER (-180<..<180)
}

ASN.1 is old fashioned, but still actively developed, widely used (your mobile phone uses it a lot), and far more flexible than most other serialisation technologies. About the only deficiency that I can see is that there is no decent code generator for Python. If you're using C/C++, C#, Java, ADA then you are well served by a mixture of free (C/C++, ADA) and commercial (C/C++, C#, JAVA) tools.

ASN.1是老式的,但仍在积极开发、广泛使用(你的手机经常使用它),而且比大多数其他序列化技术灵活得多。我能看到的唯一不足是Python没有像样的代码生成器。如果您正在使用C/ c++、c#、Java、ADA,那么您将得到免费(C/ c++、ADA)和商业(C/ c++、c#、Java)工具的混合服务。

I especially like the wide choice of binary and text based wireformats. This makes it extremely convenient in some projects. The wireformat list currently includes:

我特别喜欢广泛选择基于二进制和文本的线格式。这在某些项目中非常方便。目前的线格式列表包括:

  • BER (binary)
  • BER(二进制)
  • PER (binary, aligned and unaligned. This is ultra bit efficient. For example, and INTEGER constrained between 0 and 15 will take up only 4 bits on the wire)
  • 每(二进制,对齐和不结盟)。这是超位效率。例如,在0到15之间的整数将只占用网络上的4位元。
  • OER
  • OER
  • DER (another binary)
  • DER(另一个二进制)
  • XML (also XER)
  • XML(也x分子)
  • JSON (brand new, tool support is still developing)
  • JSON(全新,工具支持仍在开发中)

plus others.

加别人。

Note the last two? Yes, you can define data structures in ASN.1, generate code, and emit / consume messages in XML and JSON. Not bad for a technology that started off back in the 1980s.

注意最后两个吗?是的,您可以在ASN.1中定义数据结构,生成代码,并以XML和JSON格式发出/使用消息。对于一项始于上世纪80年代的技术来说,这并不坏。

Versioning is done differently to GPB. You can allow for extensions:

版本控制与GPB不同。你可以考虑延期:

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180),
   ...
}

This means that at a later date I can add to Foo, and older systems that have this version can still work (but can only access the bearing field).

这意味着以后我可以添加到Foo中,而具有这个版本的旧系统仍然可以工作(但是只能访问轴承字段)。

I rate ASN.1 very highly. It can be a pain to deal with (tools might cost money, the generated code isn't necessarily beautiful, etc). But the constraints are a truly fantastic feature that has saved me a whole ton of heart ache time and time again. Makes developers whinge a lot when the encoders / decoders report that they've generated duff data.

我对ASN.1评价很高。处理它可能会很痛苦(工具可能需要花钱,生成的代码不一定很漂亮,等等)。但是约束是一个非常奇妙的特性,它一次又一次地为我省去了大量的心痛。当编码器/解码器报告说他们生成了错误的数据时,开发人员会抱怨不已。

Other links:

其他链接:

  • Good intro
  • 好介绍
  • Open source C/C++ compiler
  • 开源的C / c++编译器
  • Open source compiler, does ADA too AFAIK
  • 开源编译器,ADA也是如此
  • Commercial, good
  • 商业,很好
  • Commercial, good
  • 商业,很好
  • Try it yourself online
  • 自己试试在线

Observations

观察

To share data:

共享数据:

  • Code first approaches (e.g. Boost serialisation) restrict you to the original language (e.g. C++), or force you to do a lot of extra work in another language
  • 代码优先方法(例如,增强序列化)限制您使用原始语言(如c++),或者强迫您使用另一种语言做大量额外的工作
  • Schema first is better, but
    • A lot of these leave big gaps in the sharing contract (i.e. no constraints). GPB is annoying in this regard, because it is otherwise very good.
    • 其中很多都在共享契约中留下了很大的空白(即没有约束)。GPB在这方面很烦人,因为它在其他方面非常好。
    • Some have constraints (e.g. XSD, JSON), but suffer patchy tool support.
    • 有些具有约束(如XSD、JSON),但缺少对工具的支持。
    • For example, Microsoft's xsd.exe actively ignores constraints in xsd files (MS's excuse is truly feeble). XSD is good (from the constraints point of view), but if you cannot trust the other guy to use a good XSD tool that enforces them for him/her then the worth of XSD is diminished
    • 例如,微软的xsd。exe会积极地忽略xsd文件中的约束(MS的借口实在是站不住脚)。XSD是好的(从约束的角度来看),但是如果您不能信任另一个家伙使用一个好的XSD工具来为他/她强制使用它们,那么XSD的价值就会降低
    • JSON validators are ok, but they do nothing to help you form the JSON in the first place, and aren't automatically called. There's no guarantee that someone sending you JSON message have run it through a validator. You have to remember to validate it yourself.
    • JSON验证器是可以的,但是它们首先不能帮助您形成JSON,并且不会自动调用。不能保证发送JSON消息的人通过验证器运行它。你必须记得自己验证它。
    • ASN.1 tools all seem to implement the constraints checking.
    • ASN.1工具似乎都实现了约束检查。
  • 模式优先是更好的,但是其中许多在共享契约(即没有约束)中留下了很大的差距。GPB在这方面很烦人,因为它在其他方面非常好。有些具有约束(如XSD、JSON),但缺少对工具的支持。例如,微软的xsd。exe会积极地忽略xsd文件中的约束(MS的借口实在是站不住脚)。XSD是好的(从约束的角度来看),但如果你不能信任另一个人使用XSD工具,加强他们对他/她好然后XSD的价值减少JSON验证器是好的,但他们为你做什么形式的JSON首先,并不是自动调用。不能保证发送JSON消息的人通过验证器运行它。你必须记得自己验证它。ASN.1工具似乎都实现了约束检查。

So for me, ASN.1 does it. It's the one that is least likely to result in someone else making a mistake, because it's the one with the right features and where the tools all seemingly endeavour to fully implement those features, and it is language neutral enough for most purposes.

对我来说,asn。1做到了。这是最不可能导致别人犯错误的原因,因为它具有正确的特性,而且工具似乎都在努力全面地实现这些特性,而且它在大多数情况下都是足够的语言。

To be honest, if GPB added a constraints mechanism that'd be the winner. XSD is close but the tools are almost universally rubbish. If there were decent code generators of other languages, JSON schema would be pretty good.

老实说,如果GPB增加了一个约束机制,那就是赢家。XSD非常接近,但是这些工具几乎都是垃圾。如果有其他语言的合适的代码生成器,JSON模式将会非常好。

If GPB had constraints added (note: this would not change any of the wire formats), that'd be the one I'd recommend to everyone for almost every purpose. Though ASN.1's uPER is very useful for radio links.

如果GPB添加了约束(注意:这不会改变任何一种有线格式),那将是我向每个人推荐的几乎所有的目标。尽管ASN.1的uPER对无线电连接非常有用。


推荐阅读
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
  • 使用freemaker生成Java代码的步骤及示例代码
    本文介绍了使用freemaker这个jar包生成Java代码的步骤,通过提前编辑好的模板,可以避免写重复代码。首先需要在springboot的pom.xml文件中加入freemaker的依赖包。然后编写模板,定义要生成的Java类的属性和方法。最后编写生成代码的类,通过加载模板文件和数据模型,生成Java代码文件。本文提供了示例代码,并展示了文件目录结构。 ... [详细]
  • 本文介绍了在实现了System.Collections.Generic.IDictionary接口的泛型字典类中如何使用foreach循环来枚举字典中的键值对。同时还讨论了非泛型字典类和泛型字典类在foreach循环中使用的不同类型,以及使用KeyValuePair类型在foreach循环中枚举泛型字典类的优势。阅读本文可以帮助您更好地理解泛型字典类的使用和性能优化。 ... [详细]
  • STM32 IO口模拟串口通讯
    转自:http:ziye334.blog.163.comblogstatic224306191201452833850647前阵子,调项目时需要用到低波 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • 本文整理了Java中java.lang.NoSuchMethodError.getMessage()方法的一些代码示例,展示了NoSuchMethodErr ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
author-avatar
Devil灬旋律
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有