Go 如何进行字符串比较?
Posted
技术标签:
【中文标题】Go 如何进行字符串比较?【英文标题】:How does Go do string comparison? 【发布时间】:2013-12-12 12:49:45 【问题描述】:http://golang.org/ref/spec#Comparison_operators
Go 支持字符串比较,没有任何特殊功能。 Go 运行时是否在幕后工作以比较字符串文字?
【问题讨论】:
这种情况是因为 string 是 Go 语言的内置类型(Go 的另一个 +1)。对于字符串是附加结构的语言,需要特殊函数。 【参考方案1】:runtime/string.goc
(go1.3):
func eqstring(s1 String, s2 String) (v bool)
if(s1.len != s2.len)
v = false;
return;
if(s1.str == s2.str)
v = true;
return;
v = runtime·memeq(s1.str, s2.str, s1.len);
int32
runtime·strcmp(byte *s1, byte *s2)
uintptr i;
byte c1, c2;
for(i=0;; i++)
c1 = s1[i];
c2 = s2[i];
if(c1 < c2)
return -1;
if(c1 > c2)
return +1;
if(c1 == 0)
return 0;
注意:runtime·
分隔符是 Unicode 中点,而不是句点。
【讨论】:
【参考方案2】:正如您在以下程序集转储中所见,字符串比较在短路检查后从运行时(第 17 行)委托给 runtime.eqstring
函数,以查看两个操作数是否是相同的内存中字符串(第 17 行) 11):
$ cat foo.go
package main
func main()
a := "hello"
b := "world"
_ = a == b
$ go tool 6g -S foo.go
--- prog list "main" ---
0000 (foo.go:3) TEXT main+0(SB),$40-0
0001 (foo.go:3) LOCALS ,$0
0002 (foo.go:4) LEAQ go.string."hello"+0(SB),BX
0003 (foo.go:4) MOVQ (BX),SI
0004 (foo.go:4) MOVQ 8(BX),CX
0005 (foo.go:5) LEAQ go.string."world"+0(SB),BX
0006 (foo.go:5) MOVQ (BX),DX
0007 (foo.go:5) MOVQ 8(BX),AX
0008 (foo.go:6) JMP ,11
0009 (foo.go:6) MOVQ $1,AX
0010 (foo.go:6) JMP ,23
0011 (foo.go:6) CMPQ CX,AX
0012 (foo.go:6) JNE ,22
0013 (foo.go:6) MOVQ SI,(SP)
0014 (foo.go:6) MOVQ CX,8(SP)
0015 (foo.go:6) MOVQ DX,16(SP)
0016 (foo.go:6) MOVQ AX,24(SP)
0017 (foo.go:6) CALL ,runtime.eqstring+0(SB)
0018 (foo.go:6) MOVBQZX 32(SP),BX
0019 (foo.go:6) CMPB BX,$0
0020 (foo.go:6) JEQ ,22
0021 (foo.go:6) JMP ,9
0022 (foo.go:6) MOVQ $0,AX
0023 (foo.go:7) RET ,
--- prog list "init" ---
0024 (foo.go:7) TEXT init+0(SB),$0-0
0025 (foo.go:7) MOVBQZX initdone·+0(SB),AX
0026 (foo.go:7) LOCALS ,$0
0027 (foo.go:7) CMPB AX,$0
0028 (foo.go:7) JEQ ,34
0029 (foo.go:7) CMPB AX,$2
0030 (foo.go:7) JNE ,32
0031 (foo.go:7) RET ,
0032 (foo.go:7) CALL ,runtime.throwinit+0(SB)
0033 (foo.go:7) UNDEF ,
0034 (foo.go:7) MOVB $2,initdone·+0(SB)
0035 (foo.go:7) RET ,
除非您正在使用编译器或运行时,否则这不应该让您太担心:只需使用规范定义的运算符,并期望与字符串长度的比较为 O(n)。
【讨论】:
以上是关于Go 如何进行字符串比较?的主要内容,如果未能解决你的问题,请参考以下文章