(Có cảm giác rằng các câu trả lời ở trên vẫn không nêu rõ sự khác biệt & mối quan hệ giữa stringvà []runerất rõ ràng, vì vậy tôi sẽ cố gắng thêm một câu trả lời khác bằng ví dụ.)
Như @Strangeworkcâu trả lời đã nói, stringvà []runeyên lặng khác nhau.
Sự khác biệt - string& []rune:
string valuelà một lát byte chỉ đọc. Và, một chuỗi ký tự được mã hóa trong utf-8. Mỗi char stringthực sự mất 1 ~ 3 byte, trong khi mỗi char runemất 4 byte
- Đối với
string, cả len()và chỉ mục được dựa trên byte.
- Đối với
[]rune, cả len()và chỉ mục đều dựa trên rune (hoặc int32).
Mối quan hệ - string& []rune:
- Khi bạn chuyển đổi từ
stringsang []rune, mỗi char utf-8 trong chuỗi đó sẽ trở thành a rune.
- Tương tự, trong chuyển đổi ngược lại, khi chuyển đổi từ
[]runesang string, mỗi cái runesẽ trở thành một char utf-8 trong string.
Lời khuyên:
- Bạn có thể chuyển đổi giữa
stringvà []rune, nhưng chúng vẫn khác nhau, ở cả loại & kích thước tổng thể.
(Tôi sẽ thêm một ví dụ để cho thấy rõ hơn.)
Mã
chuỗi_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()
}
Hành hình:
chạy chuỗi_rune_compare.go
Đầu ra:
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
Giải trình:
Chuỗi hello你好có độ dài 11, bởi vì 5 ký tự đầu tiên, mỗi ký tự chỉ mất 1 byte, trong khi 2 ký tự Trung Quốc cuối cùng chỉ có 3 byte.
- Như vậy
total bytes = 5 * 1 + 2 * 3 = 11
- Vì
len()trên chuỗi dựa trên byte, do đó, dòng đầu tiên được inlen: 11
- Vì chỉ mục trên chuỗi cũng dựa trên byte, do đó, 2 dòng sau sẽ in các giá trị loại
uint8(vì bytelà loại bí danh của uint8, trong go).
Khi chuyển đổi stringthành []rune, nó tìm thấy 7 ký tự utf8, do đó 7 rune.
- Từ
len()trên []runeđược dựa trên rune, do đó dòng cuối cùng in len: 7.
- Nếu bạn hoạt động
[]runethông qua chỉ mục, nó sẽ truy cập cơ sở trên rune.
Vì mỗi rune là từ một char utf8 trong chuỗi ban đầu, do đó bạn cũng có thể nói cả hai len()và hoạt động chỉ mục []runedựa trên các ký tự utf8.