Строка, которую вы не знаете в голанге

Go

Строка, которую вы не знаете в голанге

Строки могут показаться слишком простыми для поста в блоге, но правильно использовать простую вещь непросто.

перебирать строку

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.