(Tenho a sensação de que as respostas acima ainda não indicam as diferenças e as relações entre string
e[]rune
muito claramente, por isso, tentaria adicionar outra resposta com exemplo.)
Como @Strangework
a resposta disse, string
e[]rune
são silenciosos diferentes.
Diferenças - string
& []rune
:
string value
é uma fatia de bytes somente leitura. E, uma string literal é codificada em utf-8. Cada char na string
verdade leva de 1 a 3 bytes, enquanto cada um rune
leva 4 bytes
- Pois
string
, both len()
e index são baseados em bytes.
- Pois
[]rune
, both len()
e index são baseados em runa (ou int32).
Relacionamentos - string
& []rune
:
- Quando você converte de
string
para []rune
, cada caractere utf-8 nessa sequência se torna a rune
.
- Da mesma forma, na conversão reversa, ao converter de
[]rune
para string
, cada rune
um se torna um caracter utf-8 no string
.
Dicas:
- Você pode converter entre
string
e []rune
, mas eles ainda são diferentes, tanto no tipo quanto no tamanho geral.
(Eu adicionaria um exemplo para mostrar isso mais claramente.)
Código
string_rune_compare.go:
// string & rune compare,
package main
import "fmt"
// string & rune compare,
func stringAndRuneCompare() {
// string,
s := "hello你好"
fmt.Printf("%s, type: %T, len: %d\n", s, s, len(s))
fmt.Printf("s[%d]: %v, type: %T\n", 0, s[0], s[0])
li := len(s) - 1 // last index,
fmt.Printf("s[%d]: %v, type: %T\n\n", li, s[li], s[li])
// []rune
rs := []rune(s)
fmt.Printf("%v, type: %T, len: %d\n", rs, rs, len(rs))
}
func main() {
stringAndRuneCompare()
}
Executar:
vá executar string_rune_compare.go
Resultado:
hello你好, type: string, len: 11
s[0]: 104, type: uint8
s[10]: 189, type: uint8
[104 101 108 108 111 20320 22909], type: []int32, len: 7
Explicação:
A cadeia hello你好
tem comprimento 11, porque os primeiros 5 caracteres cada um levam apenas 1 byte, enquanto os últimos 2 caracteres chineses levam 3 bytes.
- Portanto,
total bytes = 5 * 1 + 2 * 3 = 11
- Como
len()
a string é baseada em bytes, a primeira linha impressalen: 11
- Como o índice na string também é baseado em bytes, as duas linhas a seguir imprimem valores do tipo
uint8
(já que byte
é um tipo de alias de uint8
, em movimento).
Ao converter string
para []rune
, ele encontrou 7 utf8 chars, assim 7 runas.
- Como
len()
on []rune
é baseado em runa, a última linha é impressa len: 7
.
- Se você operar
[]rune
via índice, ele acessará a base na runa.
Como cada runa é de um utf8 char na string original, também é possível dizer que a len()
operação de ambos e o índice []rune
são baseadas em utf8 chars.