(У мене з’явилося відчуття, що вищевказані відповіді все ще не викладають відмінності та відносини між ними, string
і []rune
дуже чітко, тому я спробую додати ще одну відповідь прикладом.)
Як @Strangework
сказано у відповіді, string
і []rune
тихо різні.
Відмінності - string
& []rune
:
string value
це фрагмент байта, доступний лише для читання. І, літеральний рядок кодується у utf-8. Кожен символ в string
дійсності займає 1 ~ 3 байта, в той час як кожен rune
займає 4 байта
- Для
string
, як len()
і індекс засновані на байт.
- Для отримання
[]rune
, як len()
і індекс засновані на руні (або int32).
Відносини - string
& []rune
:
- Коли ви конвертуєте
string
в []rune
, кожен знак utf-8 у цьому рядку стає а rune
.
- Аналогічно, при зворотному перетворенні, при перетворенні
[]rune
в string
, кожен rune
стає знаком utf-8 в string
.
Поради:
- Ви можете конвертувати між
string
та []rune
, але все-таки вони різні за типом та загальним розміром.
(Я б додав приклад, щоб показати це більш чітко.)
Код
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()
}
Виконати:
йти запустити string_rune_compare.go
Вихід:
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
Пояснення:
Рядок hello你好
має довжину 11, тому що перші 5 символів мають лише 1 байт, тоді як останні 2 китайські символи займають 3 байти.
- Таким чином,
total bytes = 5 * 1 + 2 * 3 = 11
- Оскільки
len()
рядок базується на байтах, таким чином друкується перший рядокlen: 11
- Оскільки індекс на рядку також базується на байтах, таким чином, наступні два рядки друкують значення типу
uint8
(оскільки byte
це псевдонім типу uint8
, в ходу).
Коли конвертувати string
в []rune
, він знайшов 7 utf8 символів, таким чином 7 рун.
- Оскільки
len()
на []rune
основі базується на руні, таким чином друкується останній рядок len: 7
.
- Якщо ви працюєте
[]rune
через індекс, він отримає доступ до бази на руні.
Оскільки кожна руна складається з знака utf8 в початковій строці, тож ви можете також сказати, що обидві len()
і операції з індексом []rune
засновані на utf8 знаках.