Shotnest · 资料库
比较代码文字,不假定执行等价
在 Shotnest 文字工具中比较两段代码,看看为什么 if (count > 0) 和 if (count >= 0) 仍有 0.778 的词元相同。
比较会对代码做什么
比较工具会把两个输入都转为小写,套用 Shotnest 搜索所用的同一套字符折叠(去掉重音,全角字母转为半角),把每一串连续空白合并成一个空格,然后按空格拆分。它报告的是两段文字共有的不同词元所占的比例,以及只在一边出现的词元。缩进、换行和字母大小写在这一步之前就消失了,这对散文很方便,对代码却有风险。
什么都不会被执行。页面把粘贴的代码片段当作纯文本,输出结果时不会把它变成标记,所以这些数字描述的是字符,而不是行为。
准备两段代码片段
- 每段代码都按截取时的原样粘贴,包括花括号和运算符。
- 先看“完全相同”这一行;只有这项检查会保留大小写和空格。
- 再把“规范化后相同”和重合度数值当作两个独立的事实来看。
- 打开“仅在第一段文本中”和“仅在第二段文本中”的词元列表;运算符和粘连的标点通常会出现在那里。
- 词元列表显示不出的内容,比如在缩进有意义的语言中的缩进,要回到截屏去看。
两段代码,只改了一个运算符
第一段文字:分三行写的“if (count > 0) { return count; }”。第二段文字:同一条语句写在一行里,并把 > 换成了 >=。规范化后换行消失,所以唯一不同的词元是 > 和 >=。九个不同的词元中有七个共有,结果为 7 ÷ 9。
- 完全相同
- 否
- 规范化后相同
- 否
- 词语重合度
- 0.7777777777777778
- 仅在第一段文本中
- >
- 仅在第二段文本中
- >=
第二组则显示了相反的风险:“const Total = 1;”和“const total = 1;”被报告为规范化后相同,重合度为 1,尽管许多语言把 Total 和 total 视为不同的名字。
处理代码文字时的错误
- 把接近 1 的重合度当作两个函数行为相同的证据。
- 跳过“完全相同”这一行,漏看了标识符的大小写变化。
- 比较一段用“实况文本”拷贝时丢了括号或合并了两栏的代码片段。
- 指望工具把改变的比较运算符标得比改变的词更重要。
比较止步于何处
词元重合度是一种文字度量。它忽略顺序、重复的词元和空白,所以无法告诉你代码能否编译,或是否返回相同的值。在 Shotnest 应用中,当三行或更多行以代码的方式开头(import、def、return 等)时,代码截屏会归到“代码”书架;这个书架是为了让你再次找到它,运行它则是你自己环境中的事。