(Mam wrażenie, że powyższe odpowiedzi wciąż nie określały różnic i relacji między nimi, stringi []runebardzo wyraźnie, więc spróbuję dodać inną odpowiedź z przykładem).
Jak @Strangeworkpowiedziała odpowiedź, stringi []runesą cicho inni.
Różnice - stringi []rune:
string valuejest bajtem tylko do odczytu. I literał łańcuchowy jest zakodowany w utf-8. Każdy znak w stringrzeczywistości zajmuje 1 ~ 3 bajty, podczas gdy każdy runezajmuje 4 bajty
- Dla
stringobu len()indeks i są oparte na bajtach.
- Bo
[]runezarówno len()indeks jak i oparte są na runie (lub int32).
Relacje - stringi []rune:
- Kiedy konwertujesz z
stringna []rune, każdy znak utf-8 w tym ciągu staje się rune.
- Podobnie, w konwersji odwrotnej, po konwersji z
[]runena string, każdy runestaje się znakiem utf-8 w pliku string.
Wskazówki:
- Możesz konwertować między
stringi []rune, ale nadal są one różne, zarówno pod względem typu, jak i ogólnego rozmiaru.
(Dodałbym przykład, aby pokazać to jaśniej).
Kod
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()
}
Wykonać:
idź uruchom string_rune_compare.go
Wynik:
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
Wyjaśnienie:
Ciąg hello你好ma długość 11, ponieważ każde pierwsze 5 znaków zajmuje tylko 1 bajt, a ostatnie 2 znaki chińskie - 3 bajty.
- A zatem,
total bytes = 5 * 1 + 2 * 3 = 11
- Ponieważ
len()ciąg jest oparty na bajtach, więc drukowany jest pierwszy wierszlen: 11
- Ponieważ indeks na łańcuchu jest również oparty na bajtach, dlatego następujące 2 wiersze wypisują wartości typu
uint8(ponieważ bytejest to alias typu uint8, in go).
Kiedy przekonwertować stringdo []rune, stwierdzono 7 znaków utf8, a więc 7 run.
- Ponieważ
len()on []runeopiera się na runie, więc drukowana jest ostatnia linia len: 7.
- Jeśli operujesz
[]runeza pomocą indeksu, będzie on miał dostęp do bazy na runie.
Ponieważ każda runa pochodzi z znaku utf8 w oryginalnym łańcuchu, możesz więc powiedzieć, że oba len()operacje na indeksie []runesą oparte na znakach utf8.