(ND: tiêu đề nguyên thủy: Mutability)
D là ngôn ngữ xác định kiểu tĩnh: kể từ lúc biến được khai báo, kiểu của nó không thể thay đổi sang kiểu khác. Điều này hỗ trợ trình biên dịch phát hiện sớm nhiều lỗi và thiết lập giới hạn của biến lúc biên dịch, nhờ đó các chương trình đồ sộ sẽ an toàn hơn và dễ bảo trì hơn.
Trong khi đó, giá trị của biến có thể là hằng số (const
),
bất biến (immutable
)
hoặc có thể thay đổi (mutable
).
Những tính chất này được xác định lúc khai báo biến.
bất biến
Các biến được khai báo với immutable
sẽ chỉ được gán giá trị đúng một lần,
và sau đó việc thay đổi bất kỳ sẽ phát sinh lỗi:
immutable int err = 5;
// hoặc: immutable err = 5
// vì int được nội suy từ giá trị 5.
err = 5; // lỗi biên dịch
Với thuộc tính immutable
, biến có thể được chia sẻ an toàn giữa các
luồng (thread) xử lý, và giá trị của nó có thể được lưu trữ đệm (cache)
hiệu quả.
hằng
Biến khai báo với const
cũng không thể thay đổi giá trị, nhưng điều này
chỉ áp dụng trong giới hạn của ngữ cảnh hiện tại (scope). Ví dụ, một
biến được khai báo giá trị ở một nơi, và được dùng trong một hàm
với ràng buộc rằng biến không thể thay đổi giá trị bên trong hàm đó.
Điều này thường thấy khi thiết kế các giao diện ứng dụng (API), ở đó các
hàm nhận tham số nhưng không hề / không thể thay đổi giá trị của tham số đầu vào.
Chỉ thị const
có thể áp dụng với biến đã được khai báo là immutable
hoặc mutable
.
void foo(const char[] s)
{
// bỏ đi thay đổi s như sau
// sẽ phát sinh lỗi biên dịch
// s[0] = 'x';
import std.stdio : writeln;
writeln(s);
}
// `foo` có thể dùng với hai kiểu biến
foo("abcd"); // chuỗi "abcd" là mảng bất biến
foo("abcd".dup); // .dup trả về mảng khả biến
Cả hai chỉ thị immutable
và const
đều có tính bắc cầu: chúng có tác dụng
với kiểu cùng với mọi thành phần con của kiểu đó. (Khi coi về `Struct`
bạn sẽ hiểu rõ hơn ý này.)