Golang中ContainsAny方法的常见误解解析
Golang中ContainsAny方法的常见误解解析
在 strings.ContainsAny 中,为什么
fmt.Println(strings.ContainsAny("foo", ""))
fmt.Println(strings.ContainsAny("", ""))
的结果是 false。
哦,好的
fmt.Println(strings.Contains(“seafood”, “”))
那么为什么这个结果是 true?区别是什么?
Contains 函数用于检查子字符串是否存在,而不是检查给定集合中的某个元素是否存在。并且空字符串包含在任何其他字符串中。
引号用于标识字符串的开始和结束。符文是从字符串中选取的。因此,如果你想搜索实际的引号字符,必须提供一个包含它的字符串,例如 "\""。
第一个例子:空字符串中既没有 f 也没有 o。因此返回值为 false。
第二个例子:由于左侧字符串中没有字母,第二个字符串中不可能包含其中的任何字符,因此返回值为 false。
一般来说:根据定义,空字符串不可能包含输入字符串中的任何字符,因为它是空的。
func Contains(s, substr string) bool
Contains 报告 substr 是否在 s 中。
条件是第二个元素在第一个元素中,对吧?所以问题是“”是否包含在“foo”中,对吧?在我看来,似乎是包含的。
我刚才看到“”和“”是不同类型的引号,所以也许这就是问题所在?
那么引号(我发现在《Go 程序设计语言》中它们都是智能引号)本身并不是符文吗?
有趣的是
fmt.Println(strings.Contains("seafood", ""))
返回 true,而
fmt.Println(strings.ContainsAny("foo", ""))
返回 false。
所有的引号都应该是智能引号。我可能得在电脑上重新设置一下。
我必须承认,我刚刚意识到我第一篇文章中的论点有误。
不过核心观点没有改变:在 "" 中没有任何一个符文(rune)能在其他字符串中找到,因此对于任何 chars 参数为空字符串的调用,ContainsAny() 都将返回 false。
Contains 确实会检查子字符串,如果 substr 是空字符串,那么我同样期望它在任何字符串中都能被找到。
在 strings.ContainsAny 方法中,当第二个参数(字符集)为空字符串时,无论第一个参数是什么,结果都会返回 false。这是因为该方法的功能是检查字符串中是否包含字符集中的任意一个字符,而空字符集不包含任何字符,因此不可能匹配。
示例代码:
package main
import (
"fmt"
"strings"
)
func main() {
// 空字符集无法匹配任何字符
fmt.Println(strings.ContainsAny("foo", "")) // false
fmt.Println(strings.ContainsAny("", "")) // false
// 正常字符集匹配示例
fmt.Println(strings.ContainsAny("foo", "abc")) // false,不包含a/b/c
fmt.Println(strings.ContainsAny("foo", "of")) // true,包含o
}
源码逻辑分析(Go 1.21):
// ContainsAny 内部会遍历字符集,空字符集直接返回false
func ContainsAny(s, chars string) bool {
return IndexAny(s, chars) >= 0
}
// IndexAny 对空字符集返回-1
func IndexAny(s, chars string) int {
if chars == "" {
return -1
}
// ...后续遍历逻辑
}
这种设计符合集合论原则:空集与任何集合的交集都为空。在实际编码中,建议在使用前检查字符集是否为空,避免逻辑误解。

