假设您的输入字符串是有效的 UTF-8,这个线程(Golang - ToUpper() 在单个字节上?)足够接近,尽管不是完美的重复。我们可以在此基础上使用以下方法得出可接受的解决方案unicode.ToUpper在第一个rune字符串的。
r := []rune(s)
r[0] = unicode.ToUpper(r[0])
s := string(r)
或者用一句“聪明的”俏皮话:
s := string(append([]rune{unicode.ToUpper(r[0])}, r[1:]...))
与字符串不同,符文切片不是不可变的,因此您可以将第一个符文替换为ToUpper
,它将处理具有大写字母(例如俄语)的非 ASCII 和/或多字节代码点,并忽略那些不具有大写字母的代码点(例如亚洲脚本)
NOTE:UPPER case 和 TITLE case 之间有区别,简单解释一下here。简而言之,像 DŽ 这样的二合字母字符将具有不同的标题大小写(Dž,仅第一个字素大写)和大写(DŽ,两个字素都大写)。如果您确实需要标题大小写,请使用unicode.ToTitle.
NOTE 2:转换为/自string
to []rune
涉及复制,因为您从不可变字符串中获取可变切片。如果您希望在性能敏感的代码中使用您的应用程序,请务必对其进行分析。
操场:https://go.dev/play/p/HpCBM7cRflZ
如果您有一个相当大的输入字符串,其中完整的符文切片转换变得太昂贵,您可以使用上限来解决这个问题strings.SplitN在某些分隔符上,本质上是提取文本的第一个单词并在转换中仅使用该单词:
sep := " "
ss := strings.SplitN(s, sep, 2)
r := []rune(ss[0])
r[0] = unicode.ToUpper(r[0])
s = string(r) + sep + ss[1])
使用 ~30K 输入字符串进行基准测试显示出显着差异:
go test -v -bench=. -benchmem
goos: darwin
goarch: arm64
pkg: example.com
BenchmarkRuneConv-10 6376 183691 ns/op 258049 B/op 3 allocs/op
BenchmarkSplitN-10 1709989 706.1 ns/op 4152 B/op 3 allocs/op
PASS
ok example.com 3.477s