(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 string
và []rune
rấ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ư @Strangework
câu trả lời đã nói, string
và []rune
yên lặng khác nhau.
Sự khác biệt - string
& []rune
:
string value
là một lát byte chỉ đọc. Và, một chuỗi ký tự được mã hóa trong utf-8. Mỗi char string
thực sự mất 1 ~ 3 byte, trong khi mỗi char rune
mấ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ừ
string
sang []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ừ
[]rune
sang string
, mỗi cái rune
sẽ trở thành một char utf-8 trong string
.
Lời khuyên:
- Bạn có thể chuyển đổi giữa
string
và []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ì byte
là loại bí danh của uint8
, trong go).
Khi chuyển đổi string
thà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
[]rune
thô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 []rune
dựa trên các ký tự utf8.