Я не могу дать «истинный» результат, когда дело доходит до сравнения строк Go. Я написал следующее, чтобы объяснить проблему, и приложил снимок экрана с результатами.
// 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('\n')
if(input == "a") {
isLetterA = true
} else {
isLetterA = false
}
fmt.Println("You entered",input)
fmt.Println("Is it the letter a?",isLetterA)
}
Ответы:
==
- правильный оператор для сравнения строк в Go. Однако строки, которые вы читаете из STDINreader.ReadString
, не содержат"a"
, но"a\n"
(если вы внимательно посмотрите, вы увидите дополнительный разрыв строки в вашем примере вывода).Вы можете использовать эту
strings.TrimRight
функцию для удаления конечных пробелов из ввода:if strings.TrimRight(input, "\n") == "a" { // ... }
источник
Для пользователей, независимых от платформы или пользователей Windows, вы можете:
время выполнения импорта:
import ( "runtime" "strings" )
а затем обрежьте строку следующим образом:
if runtime.GOOS == "windows" { input = strings.TrimRight(input, "\r\n") } else { input = strings.TrimRight(input, "\n") }
теперь вы можете сравнить это так:
if strings.Compare(input, "a") == 0 { //....yourCode }
Это лучший подход, когда вы используете STDIN на нескольких платформах.
Объяснение
Это происходит из-за того, что в окнах заканчиваются строки,
"\r\n"
которые известны как CRLF, а в UNIX строки, заканчивающиеся на"\n"
которые называются LF, и поэтому мы"\n"
выполняем обрезку в операционных системах на основе Unix, в то время как обрезаем"\r\n"
окна.источник
Предполагая, что в начале / в конце отсутствуют пробельные символы, есть несколько способов подтвердить равенство строк. Некоторые из них:
strings.ToLower(..)
тогда==
strings.EqualFold(.., ..)
cases#Lower
в паре с==
cases#Fold
в паре с==
Вот некоторые базовые результаты тестов (в этих тестах они
strings.EqualFold(.., ..)
кажутся наиболее производительными):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
Поскольку вариантов довольно много, вот код для генерации тестов.
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 можно сравнить с помощью
==
оператора. Если результаты не как ожидалось могут быть некоторые скрытые символы , такие как\n
,\r
, пробелы и т.д. Так как общее правило, попробуйте удалить те , используя функции , предусмотренныеstrings
пакетом в golang.Например, пробелы можно удалить с помощью
strings.TrimSpace
функции. Вы также можете определить пользовательскую функцию для удаления любого необходимого символа.strings.TrimFunc
функция может дать вам больше мощности.источник