我只是好奇这些方法中的哪一种更好(或者如果有一种更好的方法,那我就错过了)。我试图确定一个单词的第一个字母和最后一个字母是否相同,并且有两个明显的解决方案。
if word[:1] == word[len(word)-1:]
或
if word[0] == word[len(word)-1]
根据我的理解,第一个是拉动字符串的片段并进行字符串比较,而第二个是从任一端拉出字符并比较为字节。
我很好奇两者之间是否有性能差异,以及是否有任何"更好的"这样做的方法?
答案 0 :(得分:8)
在Go中,string
是UTF-8编码的。 UTF-8是一种可变长度编码。
package main
import "fmt"
func main() {
word := "世界世"
fmt.Println(word[:1] == word[len(word)-1:])
fmt.Println(word[0] == word[len(word)-1])
}
输出:
false
false
如果你真的想要比较一个字节而不是一个字符,那么编译器应该尽可能精确。显然,比较一个字节,而不是一个切片。
BenchmarkSlice-4 200000000 7.55 ns/op
BenchmarkByte-4 2000000000 1.08 ns/op
package main
import "testing"
var word = "word"
func BenchmarkSlice(b *testing.B) {
for i := 0; i < b.N; i++ {
if word[:1] == word[len(word)-1:] {
}
}
}
func BenchmarkByte(b *testing.B) {
for i := 0; i < b.N; i++ {
if word[0] == word[len(word)-1] {
}
}
}
答案 1 :(得分:3)
如果您的意思是rune,请使用:
func eqRune(s string) bool {
if s == "" {
return false // or true if that makes more sense for the app
}
f, _ := utf8.DecodeRuneInString(s) // 2nd return value is rune size. ignore it.
l, _ := utf8.DecodeLastRuneInString(s) // 2nd return value is rune size. ignore it.
if f != l {
return false
}
if f == unicode.ReplacementChar {
// First and last are invalid UTF-8. Fallback to
// comparing bytes.
return s[0] == s[len(s)-1]
}
return true
}
如果您的意思是字节,请使用:
func eqByte(s string) bool {
if s == "" {
return false // or true if that makes more sense for the app
}
return s[0] == s[len(s)-1]
}
比较单个字节比比较字符串切片要快,如另一个答案中的基准测试所示。
答案 2 :(得分:0)
字符串是一个字节序列。如果您知道字符串仅包含ASCII字符,则您的方法有效。否则,您应该使用处理多字节字符而不是字符串索引的方法。您可以将其转换为符文切片以处理代码点或字符,如下所示:
r := []rune(s)
return r[0] == r[len(r) - 1]
您可以在the official Go Blog post on the subject中阅读有关字符串,字节切片,符文和代码点的更多信息。
要回答您的问题,您发布的两个索引表达式之间没有明显的性能差异。
这是一个可运行的例子:
package main
import "fmt"
func EndsMatch(s string) bool {
r := []rune(s)
return r[0] == r[len(r) - 1]
}
func main() {
tests := []struct{
s string
e bool
}{
{"foo", false},
{"eve", true},
{"世界世", true},
}
for _, t := range tests {
r := EndsMatch(t.s)
if r != t.e {
fmt.Printf("EndsMatch(%s) failed: expected %t, got %t\n", t.s, t.e, r)
}
}
}
什么都不打印。