[Go]字符串 比较

比较方式

  1. == 区分大小写,效率最高
  2. strings.Compare (a, b string) int 区分大小写,按字典序比较两个字符串(a == b 则 0;a < b 则 -1;a > b 则 +1)
  3. strings.EqualFold (s, t string) bool不区分大小写

示例

golang 复制代码
//比较的字符串及其结果

fmt.Println("go" == "go") // true
fmt.Println("go" == "Go") // false

fmt.Println(strings.Compare("go", "go")) // 0
fmt.Println(strings.Compare("go", "golang")) //-1

fmt.Println(strings.EqualFold("go", "Go")) // true

源码

strings.Compare

golang 复制代码
/*
    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
    
*/

go.dev/src/interna...

strings.EqualFold

golang 复制代码
// 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
}
相关推荐
UIUV17 小时前
Go语言入门到精通学习笔记
后端·go·编程语言
littleschemer21 小时前
Go异步持久化如何防止炸服
go·map并发崩溃
不会敲代码11 天前
从零开始学 Go:协程并发与 Web 开发初探
go
扉页的墨1 天前
Wails v2 实战:用 Go 写桌面应用,从 0 到 1 构建一个本地笔记工具
go
我叫黑大帅1 天前
从零实现一个完整 RAG 系统:基于 Eino 框架的检索增强生成实战
后端·面试·go
不会写DN2 天前
通过eino-ext如何正常indexer RAG?
网络·面试·go
donecoding2 天前
遗嘱、水管与抢救室:TS 切入 Go 的流程控制、接口与并发
javascript·typescript·go
扉页的墨2 天前
Go 协程泄漏排查实战:我是如何把线上内存从 500MB 压到 20MB 的
go
donecoding2 天前
对象模型与内存的“钥匙理论”:TS 切入的 Go 的结构体与指针
javascript·typescript·go