当涉及Go字符串比较时,我无法产生" true"结果。 我写了以下内容来解释这个问题,并附上了输出的屏幕截图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// string comparison in Go
package main
import"fmt"
import"bufio"
import"os"

func main() {
    var isLetterA bool

    fmt.Println("Enter the letter a")
    reader := bufio.NewReader(os.Stdin)
    input, _ := reader.ReadString('\
')

    if(input =="a") {
        isLetterA = true
    } else {
        isLetterA = false
    }

    fmt.Println("You entered",input)
    fmt.Println("Is it the letter a?",isLetterA)

}

example

  • Windows用户检查我的答案:)

==是在Go中比较字符串的正确运算符。但是,使用reader.ReadString从STDIN中读取的字符串不包含"a",而是包含"a\
"
(如果仔细观察,您将在示例输出中看到额外的换行符)。

您可以使用strings.TrimRight函数从输入中删除尾随空格:

1
2
3
4
if strings.TrimRight(input,"\
") =="a" {
    // ...
}

对于平台独立用户或Windows用户,您可以执行以下操作:

导入运行时:

1
2
3
4
import (
   "runtime"
   "strings"
)

然后像这样修剪字符串:

1
2
3
4
5
6
7
8
if runtime.GOOS =="windows" {
  input = strings.TrimRight(input,"\
\
")
} else {
  input = strings.TrimRight(input,"\
")
}

现在您可以像这样比较它:

1
2
3
if strings.Compare(input,"a") == 0 {
  //....yourCode
}

在多个平台上使用STDIN时,这是一种更好的方法。

说明

发生这种情况的原因是,在Windows上以"\
\
"
结尾的行(称为CRLF),而在UNIX上以"\
"
结尾的行(称为LF),这就是为什么我们在修整"\
\
"
的同时在基于unix的操作系统上修行"\
"
的原因在Windows上。

  • 无需区分。 第二个参数是剪切集,而不是后缀,并且剪切集中的任何字符都会以任何顺序/组合进行修剪。 修剪" \ r \ n"就足够了。

假设没有前置/后继空格字符,仍然有几种断言字符串相等的方法。其中一些是:

  • strings.ToLower(..)然后==
  • strings.EqualFold(.., ..)
  • cases#Lower==配对
  • cases#Fold==配对

以下是一些基本的基准测试结果(在这些测试中,strings.EqualFold(.., ..)似乎是性能最高的选择):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
goos: darwin
goarch: amd64
BenchmarkStringOps/both_strings_equal::equality_op-4               10000        182944 ns/op
BenchmarkStringOps/both_strings_equal::strings_equal_fold-4        10000        114371 ns/op
BenchmarkStringOps/both_strings_equal::fold_caser-4                10000       2599013 ns/op
BenchmarkStringOps/both_strings_equal::lower_caser-4               10000       3592486 ns/op

BenchmarkStringOps/one_string_in_caps::equality_op-4               10000        417780 ns/op
BenchmarkStringOps/one_string_in_caps::strings_equal_fold-4        10000        153509 ns/op
BenchmarkStringOps/one_string_in_caps::fold_caser-4                10000       3039782 ns/op
BenchmarkStringOps/one_string_in_caps::lower_caser-4               10000       3861189 ns/op

BenchmarkStringOps/weird_casing_situation::equality_op-4           10000        619104 ns/op
BenchmarkStringOps/weird_casing_situation::strings_equal_fold-4    10000        148489 ns/op
BenchmarkStringOps/weird_casing_situation::fold_caser-4            10000       3603943 ns/op
BenchmarkStringOps/weird_casing_situation::lower_caser-4           10000       3637832 ns/op

由于有很多选择,因此这里是生成基准的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package main

import (
   "fmt"
   "strings"
   "testing"

   "golang.org/x/text/cases"
   "golang.org/x/text/language"
)

func BenchmarkStringOps(b *testing.B) {
    foldCaser := cases.Fold()
    lowerCaser := cases.Lower(language.English)

    tests := []struct{
        description string
        first, second string
    }{
        {
            description:"both strings equal",
            first:"aaaa",
            second:"aaaa",
        },
        {
            description:"one string in caps",
            first:"aaaa",
            second:"AAAA",
        },
        {
            description:"weird casing situation",
            first:"aAaA",
            second:"AaAa",
        },
    }

    for _, tt := range tests {
        b.Run(fmt.Sprintf("%s::equality op", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringEqualsOperation(tt.first, tt.second, b)
            }
        })

        b.Run(fmt.Sprintf("%s::strings equal fold", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsEqualFold(tt.first, tt.second, b)
            }
        })

        b.Run(fmt.Sprintf("%s::fold caser", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsFoldCaser(tt.first, tt.second, foldCaser, b)
            }
        })

        b.Run(fmt.Sprintf("%s::lower caser", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsLowerCaser(tt.first, tt.second, lowerCaser, b)
            }
        })
    }
}

func benchmarkStringEqualsOperation(first, second string, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = strings.ToLower(first) == strings.ToLower(second)
    }
}

func benchmarkStringsEqualFold(first, second string, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = strings.EqualFold(first, second)
    }
}

func benchmarkStringsFoldCaser(first, second string, caser cases.Caser, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = caser.String(first) == caser.String(second)
    }
}

func benchmarkStringsLowerCaser(first, second string, caser cases.Caser, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = caser.String(first) == caser.String(second)
    }
}

可以使用==运算符比较Golang中字符串内的内容。如果结果与预期不符,则可能存在一些隐藏字符,例如\
\
,空格等。因此,作为一般经验法则,请尝试使用golang中strings包提供的功能删除这些字符。

对于实例,可以使用strings.TrimSpace函数删除空格。您还可以定义一个自定义函数以删除所需的任何字符。 strings.TrimFunc功能可以为您提供更多功能。