impl.MessageState仅嵌入具体消息中,而不嵌入生成的实现原始消息的结构中。
它专门嵌入了三个pragmas:)({});
/** added this: */
if ( typeof define === "function" && define.amd ) {
define( "idb",[],function() {
return { openDB:idb.openDB,deleteDB:idb.deleteDB,wrap:idb.wrap,unwrap:idb.unwrap}
});
}
,NoUnkeyedLiterals
和DoNotCompare
。
最后一个DoNotCopy是DoNotCopy
的零大小数组。唯一的目的是让sync.Mutex
大声抱怨浅拷贝,如评论中所述:
DoNotCopy可以嵌入到结构中,以防止浅拷贝。
这不依赖于Go语言功能,而是一种特殊情况
在兽医检查器中。
所有摘要:go vet
不应被复制,并且互斥锁仅用于复制。如果这样做,是因为您使用了错误的方式。
,
据我所知,Go protobuf API 包含 DoNotCopy 互斥锁的原因有以下三个:
- 维护者可能希望在未来以一种不适用于浅拷贝的方式更改内部表示。
- 将原子访问和非原子访问混合到同一内存理论上是不安全的。 protobuf 结构包含一个内部字段,通常使用原子访问读取和写入。对消息调用
msg.Marshal()
,然后用 *msg = MyMessage{...}
覆盖它会混合原子访问和非原子访问。即使这适用于今天在 x86 上的实现,也不能保证这将适用于未来的其他系统。 (见a long Go issue about this)。
- 如果您对消息调用
ProtoReflect()
,然后覆盖该消息,它将崩溃,因为 ProtoReflect() 结果依赖于内部反射指针 (original issue):
d := &durationpb.Duration{Seconds: 1}
protoreflectMessage := d.ProtoReflect()
fmt.Printf("protoreflectMessage.Interface()=%v\n",protoreflectMessage.Interface())
*d = durationpb.Duration{Seconds: 2}
fmt.Printf("protoreflectMessage.Interface()=%v\n",protoreflectMessage.Interface())
这会崩溃:
protoreflectMessage.Interface()=seconds:1
panic: invalid nil message info; this suggests memory corruption due to a race or shallow copy on the message struct
本文链接:https://www.f2er.com/1459855.html