prototext format 随机空格

prototext format 随机空格

问题简述

golang 语言,在使用 prototext 进行 format 的时候,相同的代码输出结果不唯一,有的时候字段之间是两个空格,有的时候是一个空格。

代码

先上pb文件

syntax = "proto3";

package codepractice.tmp;
option go_package = "codepractice/tmp";

service manage {
    rpc Hello(HelloRequest) returns (HelloReply) {}
}

enum HelloType {
    HELLO_TYPE_UNSPECIFIED = 0;
    SHAKE_HANDS = 1;
    EMBRACE = 2;
}

message HelloRequest {
    HelloType type = 1;
    string name = 2;
}

message HelloReply {}

可以看出来pb文件定义的东西很少,只有一个Hello的rpc接口,一个HelloRequest,里面有一个type字段和name字段,一个空的HelloReply。
接下来上代码

package tmp_test

import (
	"testing"

	"test/codepractice/tmp"

	"google.golang.org/protobuf/encoding/prototext"
)

func Test_Hello(t *testing.T) {
	hello := &tmp.HelloRequest{
		Type: tmp.HelloType_EMBRACE,
		Name: "jake",
	}

	str := prototext.MarshalOptions{Multiline: false}.Format(hello)
	str2 := `type:EMBRACE name:"jake"`

	// t.Log("hahanicai")

	if str != str2 {
		t.Fatalf("not equal %s, %s\n", str, str2)
	}
	t.Log("equal")
}

代码先初始化了一个HelloRequest结构体,然后使用prototext进行format。再定义一个名为 str2 的字符串,如果两个字符串不相等输出 not equal,否则输出 equal。

复现

这段代码很简单,讲道理str和str2肯定是相等的,但是在实际运行当中str和str2是不相等的,程序输出为

=== RUN   Test_Hello
    hello_test.go:23: not equal type:EMBRACE  name:"jake", type:EMBRACE name:"jake"
--- FAIL: Test_Hello (0.00s)

FAIL

通过输出可以看到使用prototext format后的str,type字段和name字段中间有两个空格,那么是否可以将str2中也改成两个空格就可以呢。
如果我们把代码中注释了的t.Log(“hahanicai”)这句删除掉,再运行代码

=== RUN   Test_Hello
    hello_test.go:23: equal
--- PASS: Test_Hello (0.00s)
PASS

可以看到是成功了的结果,也就是字段之间是一个空格,那为什么一句注释会影响代码执行结果呢。

解密

通过翻阅prototext的源码可以看到,在format的时候会有一个bool变量的判断,来决定是否要添加一个多余的空格
在这里插入图片描述
从注释中也可以看出来,这个bool值是随机生成的,detrand.Bool 里面使用的 hash 计算逻辑和二进制文件的大小以及开头的内容有关
在这里插入图片描述
在这里插入图片描述
所以才会出现一句注释会影响代码执行结果的离谱情况。

结论

prototext 就是只想让你用这个 text 去给人看,而不是给机器存或者进行对比才会有随机空格的加入
程序编译好后,代码执行结果是稳定的,但是增加某一行重新编译后,代码结果就可能会变

总结

不要使用 prototext 进行数据的存储或者对比,但是可以用来打印log输出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值