prototext format 随机空格

news2024/11/18 6:19:22

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输出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/160135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【寒假每日一题】洛谷 P6414 [COCI2014-2015#1] PROSJEK

题目链接:P6414 [COCI2014-2015#1] PROSJEK - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 有一个数列 a,现在按照下列公式求出一个数列 b: 给你数列 b,请求出数列 a。 输入格式 第一行一个整数 n ,表示…

bugku-reverse-入门逆向 Easy_vb re 游戏过关 逆向入门

入门逆向下载文件 解压后 拖入IDA中Easy_vb同样方法 解压后 拖入IDAEasy_re下载解压后 打开似乎有点逗查下壳先拖入IDA 选中这两行字符 转译单击a 得到flag游戏过关下载文件 解压打开 发现要把8个都点亮 每次输入会把输入的数本身和他上一个下一个都改变状态,当…

Jenkin权限控制——基于角色授权策略

开启授权策略 Jenkins的项目权限控制通过【授权策略】实现,【授权策略】需要plugins提供,首先需要安装Role-based Authorization Strategy 安装Role-based Authorization Strategy 管理Jenkins——》插件管理——》搜素——》Role-based Authorizatio…

企微机器人使用及内容配置文档

如何使用群机器人 在终端某个群组添加机器人之后,创建者可以在机器人详情页看的该机器人特有的webhookurl。开发者可以按以下说明a向这个地址发起HTTP POST 请求,即可实现给该群组发送消息。下面举个简单的例子. 假设webhook是:https://qyapi…

【Git 从入门到精通】Git中常用的指令(含使用Git维护一个项目的完整操作)

文章目录一、使用git维护一个项目完整操作1.设置用户名与邮箱2.初始化项目中的Git3.使用Git追踪项目中的文件4.提交一次代码5.后期项目的更新与维护附录、常用命令一览表一、使用git维护一个项目完整操作 1.设置用户名与邮箱 注意:这个设置的并不是将代码提交到github或者gite…

CAD动态块操作实例:绘制剖面符号

CAD动态块与普通的CAD图块相比,其图形夹点更多,设计师可以利用动态块的夹点对图形进行快速调整,自由拉伸长度、随心切换隐藏形态等。本节,给大家分享一下浩辰CAD软件中利用CAD动态块的极轴拉伸功能来绘制剖面符号的具体操作步骤。…

[杂记]算法: 并查集

0. 引言 我们考虑如何计算一个图连通分量的个数. 假定简单无向图GGG有两个连通分量(子图)G1,G2G_1, G_2G1​,G2​, 如下图所示: 一个很自然的想法是, 要想求连通分量个数, 我们可以使用Full-DFS算法, 也就是我们从某个点开始深度优先搜索, 并标记访问过的元素. 随后挨个顶点…

高等数学(第七版)同济大学 总习题十一 个人解答

高等数学(第七版)同济大学 总习题十一 函数作图软件:Mathematica 1.填空:\begin{aligned}&1. \ 填空:&\end{aligned}​1. 填空:​​ (1)第二类曲线积分∫ΓPdxQdyRdz化成第一类曲线积分是_____&am…

Yarn 下载安装及常用配置和命令总结

title: Yarn 下载安装及常用配置和命令总结 date: 2023-01-13 14:47:32 tags: 开发工具及环境 categories:开发工具及环境 cover: https://cover.png feature: false 1. Node.js 建议先安装好 Node.js,见另一篇:Node.js 多版本安装及 NPM 镜像配置_凡 …

Materials - 角色分层材质规范

之前编写的解释性文档,归档发布;在传统贴图中,以BaseColor贴图为例,我们将几乎所有纹理信息都集中到一张贴图上,比如下图中,就有金属、皮革和布料等各种质感的纹理信息:即使是4K的贴图&#xff…

在Win10下装VMware17后,[ 安装VMware Tools ]选项灰色的解决办法

一、说明 菜单【虚拟机】【安装VMware Tools】按钮为灰色,无法实现【安装VMware Tools】的功能,如何解决,使这个功能可以实现?本文介绍此过程。 二、问题发现 在Win10下安装Vmware17后,生成ubuntu18的虚拟机&#xff…

基于java(springboot+mybatis)汽车信息管理系统设计和实现以及文档

基于java(springbootmybatis)汽车信息管理系统设计和实现以及文档 博主介绍:5年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言…

行业分享:光伏行业如何利用视觉检测系统降本增效?

导语:机器视觉检测已在光伏产品生产的各个环节中,为产品产量与质量提供可靠保障。维视智造作为光伏组件视觉检测系统领先者,为企业提供专业、系统、稳定的光伏组件视觉检测解决方案,可保证0漏检,全面提升生产效率。一、…

C++:C++编译过程:看完还不懂C++编译过程来捶我

1:先看图 2:一个C源文件从文本到可执行文件经历的过程: gcc Hello.cpp 预处理阶段:gcc -E hello.c -o hello.i 对源代码文件中包含关系(头文件),预编译语句(宏定义&#xff09…

React中如何拆分组件

基于自己工作中的体会,还有在做的过程中翻阅的资料,看的资料没有收藏起来,很想指出具体的出处,但是很多都是从各个地方看到的。不过都是在掘金、公众号前端开发、还有知乎上看到的。 😫 前言 随着web业务越来越复杂&a…

Elasticsearch(一)--Elasticsearch概述

一、前言 从本章开始,我将进入elasticSearch(后面简称es)的学习,同样也是通过书籍自学,并且会通过自己归纳和拓展将我觉得比较值得记录的知识点分享出来,如果大家觉得有用的话可以和我一起学习。我打算在总…

Kotlin

目录 一、Kotlin 基础语法 1、方法函数 2、常量 val 和变量 var 3、${} 字符串模板 4、null 处理 !!. 不能为空 ?.为空不处理 ?:为空处理成 5、is 类型转换 相当于 instanceof 6、Any 相当于 Java的 Object 二、Kotlin 基本数据类型 1、基本数据类型&#xf…

AMD出招,英特尔最不想看到的对手来了

前段时间的CES上,AMD正式发布Ryzen 7000的3D缓存版,对于游戏玩家来说,Ryzen 7000 3D缓存版算是今年最期待的CPU。上一代的Ryzen7 5800X3D凭借超强的游戏性能和性价比,在德国最大的PC硬件零售商的统计中,甚至成为2022年…

高并发系统设计 -- 大文件业务

上传 分片断点秒传(判断文件哈希值) 前端不断的发送请求,如果用户暂停上传的话,那么就是前端停止发送请求就可以了。我分片了,而且记录了分片的相关信息,所以实现了断点功能。 前端把文件进行分片&#…

ftp vsftp 登录

打开windows资管管理器(文件夹)输入目标路径,如:ftp://192.168.1.1输入账号密码。 删除用户已保存的密码(仅密码,名称记录还在) 两种方法都可以试试,适用不同情况 情况-方法一&am…