Trong các phần trước bạn được biết về mảng, bất biến, các kiểu cơ bản. Giờ bạn đoán xem mã sau nhắn gửi điều gì:
alias string = immutable(char)[];
Trong D
, chính xác là kiểu chuỗi (string
) chỉ là tên khác, hay tên
thân mật, của kiểu immutable(char)[]
, diễn giải ra là một bất biến
mảng các ký tự, hay cũng vậy, một lát cắt gồm các ký tự.
Vì là bất biến, một chuỗi được hình thành sẽ không thể thay đổi (bất kỳ thay đổi nào cũng làm phát sinh vùng nhớ mới là bản sao của chuỗi ban đầu.) Ứng dụng rất cụ thể của thiết kế này là các chuỗi có thể chia sẻ giữa các luồng xử lý khác nhau.
Vì thực chất chuỗi là lát cắt, bạn có thể làm việc qua các "lăng kính"
mà không phát sinh tốn kém bộ nhớ.
Ví dụ hàm std.algorithm.splitter
tách chuỗi ban đầu thành các phần, nhưng nó kết quả thực tế là nó tạo
ra các lăng kính nhỏ hơn chứ không yêu cầu cấp phát thêm bất kỳ vùng nhớ nào.
Lưu ý là kiểu string
chỉ thích hợp cho chuỗi UTF-8
.
Với các bảng mã phức tạp hơn, bạn cần wstring
hoặc dstring
:
alias wstring = immutable(wchar)[]; // UTF-16
alias dstring = immutable(dchar)[]; // UTF-32
Việc chuyển đổi giữa các kiểu chuỗi này được thực hiện qua hàm to
:
import std.conv: to;
dstring myDstring = to!dstring(myString);
string myString = to!string(myDstring);
Kiểu chuỗi string
có thể xem như là mảng gồm các phần tử 8 bit
code unit. Các hàm tác động trên
chuỗi như thế cũng có tác dụng đối với chuỗi, nhưng ở mức tối thiểu
là code unit
chứ không phải ở mức ký tự. Ồ, phân biệt ký tự
và code unit là việc khó mà bạn cần đọc kỹ hơn nhé.
Cũng vậy, các thuật toán tiêu chuẩn trong D xem string
như dải các
code point,
hoặc grapheme
(xem thư viện std.uni.byGrapheme
.)
Ví dụ minh họa cho các cách nhìn khác nhau này:
string s = "\u0041\u0308"; // Ä
writeln(s.length); // 3
import std.range : walkLength;
writeln(s.walkLength); // 2
import std.uni : byGrapheme;
writeln(s.byGrapheme.walkLength); // 1
Mảng s
có chiều dài thật sự là 3, và gồm 3 code unit
0x41
, 0x03
và 0x08
.
Hai code unit
cuối có thể gộp là thành code point
(bạn có nhớ ký tự unicode tổ hợp?),
và hàm
walkLength
(thuộc bộ thư viện tiêu chuẩn xử lý các dải) hiểu được điều này, nên
gộp chúng thành 1 và nhìn mảng s
có chiều dài 2.
Cùng lúc đó, byGrapheme
lại hiểu hai code point
như thành phần một ký tự
nên chỉ trả về kết quả 1.
Xử lý hợp lý đầu vào Unicode là việc phức tạp, nhưng hầu hết trường hợp
bạn chỉ cần quan tâm tới kiểu chuỗi string
. Nếu cần quan tâm chi tiết
tới từng code unit
, bạn có thể xem
byCodeUnit
.
Việc xử lý các kiểu Unicode khác nhau được mô tả trong Unicode gems chapter.
Một chuỗi có thể gồm nhiều dòng
string multiline = "
This
may be a
long document
";
Khi cần phải thể hiện dấu nháy ("
), bạn để ý tới chuỗi Wysiwyg
và heredoc.
Tốt nhất phần này được hiểu qua các minh họa:
string raw = `raw "string"`; // chuỗi "string"
string raw2 = r"raw `string`"; // chuỗi `string`
Còn nhiều cách khác để biểu diễn chuỗi bạn có thể xem ở đây.