- Zig dựa trên cú pháp dùng dấu ngoặc nhọn tương tự Rust, nhưng được cải tiến với ngữ nghĩa ngôn ngữ đơn giản hơn và các lựa chọn cú pháp tinh gọn hơn
- Literal số nguyên bắt đầu với kiểu
comptime_int cho mọi giá trị và được chuyển đổi tường minh khi gán, còn literal chuỗi dùng ký pháp chuỗi thô ngắn gọn dựa trên \\
- Literal bản ghi dạng
.x = 1 giúp việc tìm kiếm chỗ ghi vào trường dễ hơn, và mọi kiểu đều được biểu diễn nhất quán bằng ký pháp tiền tố
- Dùng
and·or làm từ khóa điều khiển luồng, còn các câu lệnh if·loop có thể tùy chọn lược bỏ dấu ngoặc nhọn, với formatter đảm bảo tính an toàn
- Không có namespace và mọi thứ đều là biểu thức, qua đó hợp nhất cú pháp kiểu·giá trị·mẫu, đồng thời dùng gọn gàng generics·literal bản ghi·hàm dựng sẵn (
@import, @as v.v.)
Tổng quan
- Zig có bề ngoài giống Rust nhưng chọn cấu trúc ngôn ngữ đơn giản hơn
- Thiết kế cú pháp tập trung vào thân thiện với grep, nhất quán cú pháp, và giảm nhiễu thị giác không cần thiết
Literal số nguyên
const an_integer = 92;
assert(@TypeOf(an_integer) == comptime_int);
const x: i32 = 92;
const y = @as(i32, 92);
- Mọi literal số nguyên đều có kiểu
comptime_int
- Khi gán vào biến, cần chỉ định kiểu tường minh hoặc dùng
@as để chuyển đổi
- Dạng
var x = 92; không hoạt động, cần có kiểu tường minh
Literal chuỗi
const raw =
\\Roses are red
\\ Violets are blue,
\\Sugar is sweet
\\ And so are you.
\\
;
- Mỗi dòng là một token riêng nên không có vấn đề về thụt lề
- Không cần escape chính
\\
Literal bản ghi
const p: Point = .{
.x = 1,
.y = 2,
};
- Dạng
.x = 1 thuận lợi cho việc phân biệt đọc/ghi
- Ký pháp
.{} tự tách biệt với block và tự động chuyển sang kiểu kết quả
Ký pháp kiểu
u32 // số nguyên
[3]u32 // mảng độ dài 3
?[3]u32 // mảng có thể null
*const ?[3]u32 // con trỏ hằng
- Mọi kiểu đều dùng ký pháp tiền tố (prefix)
- Giải tham chiếu dùng ký pháp hậu tố (
ptr.*)
Định danh
const @"a name with space" = 42;
- Có thể tránh xung đột với từ khóa hoặc đặt tên đặc biệt
Khai báo hàm
pub fn main() void {}
fn add(x: i32, y: i32) i32 {
return x + y;
}
- Từ khóa
fn đi liền với tên hàm nên dễ tìm kiếm
- Không dùng
-> để ghi kiểu trả về
Khai báo biến
const mid = lo + @divFloor(hi - lo, 2);
var count: u32 = 0;
- Dùng
const và var
- Ghi kiểu theo thứ tự
tên: kiểu
Điều khiển luồng: and/or
while (count > 0 and ascii.isWhitespace(buffer[count - 1])) {
count -= 1;
}
and, or là từ khóa điều khiển luồng
- Phép toán bit dùng
&, |
Câu lệnh if
.direction = if (prng.boolean()) .ascending else .descending;
- Bắt buộc có ngoặc đơn, ngoặc nhọn là tùy chọn
zig fmt đảm bảo định dạng an toàn
Vòng lặp
for (0..10) |i| {
print("{d}\n", .{i});
} else @panic("loop safety counter exceeded");
- Cả
for và while đều hỗ trợ mệnh đề else
- Bộ lặp và tên phần tử được sắp xếp trực quan
Namespace và phân giải tên
const std = @import("std");
const ArrayList = std.ArrayList;
- Cấm shadowing biến
- Không có namespace và cũng không có glob import
Mọi thứ đều là biểu thức
const E = enum { a, b };
const e: if (true) E else void = .a;
- Hợp nhất cú pháp kiểu·giá trị·mẫu
- Có thể đặt biểu thức điều kiện ở vị trí kiểu
Generics
fn ArrayListType(comptime T: type) type {
return struct {
fn init() void {}
};
}
var xs: ArrayListType(u32) = .init();
- Generics được biểu diễn bằng cú pháp gọi hàm (
Type(T))
- Tham số kiểu luôn được ghi tường minh
Hàm dựng sẵn
const foo = @import("./foo.zig");
const num = @as(i32, 92);
- Dùng tiền tố
@ để gọi các tính năng do compiler cung cấp
@import hiển thị rõ đường dẫn tệp
- Đối số bắt buộc phải là literal chuỗi
Kết luận
- Cú pháp Zig là một ví dụ cho thấy tập hợp các lựa chọn nhỏ có thể tạo nên một ngôn ngữ dễ đọc
- Khi giảm số lượng tính năng, lượng cú pháp cần thiết cũng giảm theo, và khả năng xung đột giữa các cú pháp cũng giảm
- Mượn những ý tưởng hay từ các ngôn ngữ hiện có, nhưng khi cần thì vẫn mạnh dạn đưa vào cú pháp mới
Chưa có bình luận nào.