分享
golang中你不知道的 string
_西门吹牛 · · 1083 次点击 · · 开始浏览这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
golang中你不知道的 string
字符串对于一篇博客文章来说似乎太简单了,但是一个简单的东西想用好,其实也不容易。
遍历字符串
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
const sample = "我爱golang"
for i := 0; i < len(sample); i++ {
runeValue, _ := utf8.DecodeRuneInString(sample[i:])
fmt.Printf("position:%v, value:%c \n", i, runeValue)
}
}
复制代码position:0, value:我
position:1, value:�
position:2, value:�
position:3, value:爱
position:4, value:�
position:5, value:�
position:6, value:g
position:7, value:o
position:8, value:l
position:9, value:a
position:10, value:n
position:11, value:g
复制代码输出的是每一个字节。 如果想输出字符呢?
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
const sample = "我爱golang"
for i, s := 0, 0; i < len(sample); i = i + s {
runeValue, size := utf8.DecodeRuneInString(sample[i:])
fmt.Printf("position:%v, value:%c \n", i, runeValue)
s = size
}
}
复制代码输出
position:0, value:我
position:3, value:爱
position:6, value:g
position:7, value:o
position:8, value:l
position:9, value:a
position:10, value:n
position:11, value:g
复制代码还有更方便的吗?
package main
import (
"fmt"
)
func main() {
const sample = "我爱golang"
for key, v := range sample {
fmt.Printf("position:%v, value:%c \n", key, v)
}
}
复制代码输出
position:0, value:我
position:3, value:爱
position:6, value:g
position:7, value:o
position:8, value:l
position:9, value:a
position:10, value:n
position:11, value:g
复制代码- golang字符串是由字节构成的,因此索引它们会产生字节,而不是字符
- 通过unicode、utf-8等编码方式,从[]byte中解码字符串
字符串的长度
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "我爱golang"
fmt.Println(len(str), "len bytes")
fmt.Println(utf8.RuneCountInString(str), "len characters") // 更快
fmt.Println(len([]rune(str)), "len characters")
}
复制代码输出
12 len bytes
8 len characters
8 len characters
复制代码- golang对字符串的底层处理,采用的是[]byte,实际存储的值是一个uint8类型的;
- 采用UTF-8编码英文字符,每个字符只占用一个byte,而中文需要占用3个byte,因此长度是12;
- utf8会自动判断每个字符编码占用了几个byte,很清晰的展示了 Golang 对 string 的处理原理;
- for range string 每次迭代会解码一个 utf-8 编码的字符。
修改字符串
package main
import "fmt"
func main() {
str := "golang"
c := []byte(str)
c[0] = 'c'
s2 := string(c)
fmt.Println(s2)
}
复制代码输出
colang
复制代码拼接字符串
package main
import (
"bytes"
"fmt"
)
func main() {
str := "我爱"
str2 := "golang"
// 该方案每次合并会创建一个新的字符串
fmt.Println(str + str2)
// 该方案更更快,直接连接底层的 []byte
var buffer bytes.Buffer
buffer.WriteString(str)
buffer.WriteString(str2)
fmt.Println(buffer.String())
}
复制代码WriteString更快的原因,见源码直接底层[]byte连接
func (b *Buffer) WriteString(s string) (n int, err error) {
b.lastRead = opInvalid
m, ok := b.tryGrowByReslice(len(s))
if !ok {
m = b.grow(len(s))
}
return copy(b.buf[m:], s), nil
}
复制代码参考
更多内容,欢迎关注我的Github。
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信1083 次点击
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
golang中你不知道的 string
字符串对于一篇博客文章来说似乎太简单了,但是一个简单的东西想用好,其实也不容易。
遍历字符串
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
const sample = "我爱golang"
for i := 0; i < len(sample); i++ {
runeValue, _ := utf8.DecodeRuneInString(sample[i:])
fmt.Printf("position:%v, value:%c \n", i, runeValue)
}
}
复制代码position:0, value:我
position:1, value:�
position:2, value:�
position:3, value:爱
position:4, value:�
position:5, value:�
position:6, value:g
position:7, value:o
position:8, value:l
position:9, value:a
position:10, value:n
position:11, value:g
复制代码输出的是每一个字节。 如果想输出字符呢?
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
const sample = "我爱golang"
for i, s := 0, 0; i < len(sample); i = i + s {
runeValue, size := utf8.DecodeRuneInString(sample[i:])
fmt.Printf("position:%v, value:%c \n", i, runeValue)
s = size
}
}
复制代码输出
position:0, value:我
position:3, value:爱
position:6, value:g
position:7, value:o
position:8, value:l
position:9, value:a
position:10, value:n
position:11, value:g
复制代码还有更方便的吗?
package main
import (
"fmt"
)
func main() {
const sample = "我爱golang"
for key, v := range sample {
fmt.Printf("position:%v, value:%c \n", key, v)
}
}
复制代码输出
position:0, value:我
position:3, value:爱
position:6, value:g
position:7, value:o
position:8, value:l
position:9, value:a
position:10, value:n
position:11, value:g
复制代码- golang字符串是由字节构成的,因此索引它们会产生字节,而不是字符
- 通过unicode、utf-8等编码方式,从[]byte中解码字符串
字符串的长度
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "我爱golang"
fmt.Println(len(str), "len bytes")
fmt.Println(utf8.RuneCountInString(str), "len characters") // 更快
fmt.Println(len([]rune(str)), "len characters")
}
复制代码输出
12 len bytes
8 len characters
8 len characters
复制代码- golang对字符串的底层处理,采用的是[]byte,实际存储的值是一个uint8类型的;
- 采用UTF-8编码英文字符,每个字符只占用一个byte,而中文需要占用3个byte,因此长度是12;
- utf8会自动判断每个字符编码占用了几个byte,很清晰的展示了 Golang 对 string 的处理原理;
- for range string 每次迭代会解码一个 utf-8 编码的字符。
修改字符串
package main
import "fmt"
func main() {
str := "golang"
c := []byte(str)
c[0] = 'c'
s2 := string(c)
fmt.Println(s2)
}
复制代码输出
colang
复制代码拼接字符串
package main
import (
"bytes"
"fmt"
)
func main() {
str := "我爱"
str2 := "golang"
// 该方案每次合并会创建一个新的字符串
fmt.Println(str + str2)
// 该方案更更快,直接连接底层的 []byte
var buffer bytes.Buffer
buffer.WriteString(str)
buffer.WriteString(str2)
fmt.Println(buffer.String())
}
复制代码WriteString更快的原因,见源码直接底层[]byte连接
func (b *Buffer) WriteString(s string) (n int, err error) {
b.lastRead = opInvalid
m, ok := b.tryGrowByReslice(len(s))
if !ok {
m = b.grow(len(s))
}
return copy(b.buf[m:], s), nil
}
复制代码参考
更多内容,欢迎关注我的Github。