/*
strings/compare.go
*/
// Compare returns an integer comparing two strings lexicographically.
// The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
//
// Use Compare when you need to perform a three-way comparison (with
// [slices.SortFunc], for example). It is usually clearer and always faster
// to use the built-in string comparison operators ==, <, >, and so on.
// Compare 按字典序比较两个字符串,并返回一个整数。
// 若 a == b,返回 0;若 a < b,返回 -1;若 a > b,返回 1。
//
// 当你需要执行三元比较时使用该函数(例如配合 [slices.SortFunc] 切片排序函数使用)。
// 通常情况下,使用 Go 内置的字符串比较运算符 ==、<、> 等,代码更清晰、执行速度也更快。
func Compare(a, b string) int {
return bytealg.CompareString(a, b)
}
/*
internal/bytealg/compare_native.go
*/
func CompareString(a, b string) int {
return abigen_runtime_cmpstring(a, b)
}
// The declaration below generates ABI wrappers for functions
// implemented in assembly in this package but declared in another package.
// 下方的声明为函数生成 ABI 包装器,
// 这些函数在本包中用汇编实现,但在另一个包中声明。
//go:linkname abigen_runtime_cmpstring runtime.cmpstring
func abigen_runtime_cmpstring(a, b string) int
/*
如amd64
https://go.dev/src/internal/bytealg/compare_amd64.s
*/
// EqualFold reports whether s and t, interpreted as UTF-8 strings,
// are equal under simple Unicode case-folding, which is a more general
// form of case-insensitivity.
//EqualFold 用于判断将 s 和 t 解释为 UTF-8 字符串时,在简单 Unicode 大小写折叠规则下是否相等 ------ 这是一种更通用的不区分大小写的形式。
func EqualFold(s, t string) bool {
// ASCII fast path
i := 0
for n := min(len(s), len(t)); i < n; i++ {
sr := s[i]
tr := t[i]
if sr|tr >= utf8.RuneSelf {
goto hasUnicode
}
// Easy case.
if tr == sr {
continue
}
// Make sr < tr to simplify what follows.
if tr < sr {
tr, sr = sr, tr
}
// ASCII only, sr/tr must be upper/lower case
if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
continue
}
return false
}
// Check if we've exhausted both strings.
return len(s) == len(t)
hasUnicode:
s = s[i:]
t = t[i:]
for _, sr := range s {
// If t is exhausted the strings are not equal.
if len(t) == 0 {
return false
}
// Extract first rune from second string.
tr, size := utf8.DecodeRuneInString(t)
t = t[size:]
// If they match, keep going; if not, return false.
// Easy case.
if tr == sr {
continue
}
// Make sr < tr to simplify what follows.
if tr < sr {
tr, sr = sr, tr
}
// Fast check for ASCII.
if tr < utf8.RuneSelf {
// ASCII only, sr/tr must be upper/lower case
if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
continue
}
return false
}
// General case. SimpleFold(x) returns the next equivalent rune > x
// or wraps around to smaller values.
r := unicode.SimpleFold(sr)
for r != sr && r < tr {
r = unicode.SimpleFold(r)
}
if r == tr {
continue
}
return false
}
// First string is empty, so check if the second one is also empty.
return len(t) == 0
}