(У мене з’явилося відчуття, що вищевказані відповіді все ще не викладають відмінності та відносини між ними, 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 знаках.