Строка, которую вы не знаете в голанге
Строки могут показаться слишком простыми для поста в блоге, но правильно использовать простую вещь непросто.
перебирать строку
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 состоят из байтов, поэтому их индексация дает байты, а не символы
- Декодируйте строки из []byte с помощью методов кодирования, таких как unicode, utf-8 и т. д.
длина строки
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
- Голанг обрабатывается на нижнем слое строки, который является [] байтом, фактическое хранимое значение - это тип UINT8;
- Utf-8 кодирует английские символы, каждый символ занимает только один байт, а китайские должны занимать 3 БАЙТА, поэтому длина равна 12;
- utf8 автоматически определит, сколько байтов занимает каждая кодировка символов, что наглядно показывает, как Golang обрабатывает строки;
- для строки диапазона декодируется один символ в кодировке 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 Connection
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.