本文简单探索ToLower方法及SpecialCase的使用方法和实现,如果只关注SpecialCase方法的同学可以直接跳转至分割线以下
问题起因是使用strings包中的ToLower时转换小写结果与预期不相符
a := "ADASD$%^*@%3Ω"
fmt.Println(strings.ToLower(a)) //adasd$%^*@%3ω
本只想将A-Z进行大小写转换,但strings.ToLower却把Ω转换成了ω,带着这个疑问追了下源码
func ToLower(s string) string {
//isASCII是否只有ASCII
//hasUpper是否只包含ASCII小写
isASCII, hasUpper := true, false
for i := 0; i < len(s); i++ {
c := s[i]
if c >= utf8.RuneSelf {
isASCII = false
break
}
hasUpper = hasUpper || ('A' <= c && c <= 'Z')
}
if isASCII { // optimize for ASCII-only strings.
//只有ASCII且不包含小写直接返回
if !hasUpper {
return s
}
//只有ASCII且包含小写,按A-Z进行转换
var b Builder
b.Grow(len(s))
for i := 0; i < len(s); i++ {
c := s[i]
if 'A' <= c && c <= 'Z' {
c += 'a' - 'A'
}
b.WriteByte(c)
}
return b.String()
}
//包含unicode码,使用Map(unicode.ToLower, s)方法进行转换
return Map(unicode.ToLower, s)
}
func Map(mapping func(rune) rune, s string) string {
//部分代码略过......
//该方法核心在于使用参数方法mapping解析字符串s,那么现在关键就在于unicode