• Zig ใช้ ไวยากรณ์แบบวงเล็บปีกกา คล้ายกับ Rust แต่ปรับปรุงด้วยความหมายของภาษาที่เรียบง่ายกว่าและตัวเลือกด้านไวยากรณ์ที่ประณีตกว่า
  • ลิเทอรัลจำนวนเต็ม ทุกตัวเริ่มต้นเป็น comptime_int และจะถูกแปลงแบบชัดเจนเมื่อมีการกำหนดค่า ส่วน ลิเทอรัลสตริง ใช้รูปแบบ raw string แบบย่อที่อิงกับ \\
  • record literal ในรูปแบบ .x = 1 ทำให้ค้นหาการเขียนค่าให้ฟิลด์ได้ง่าย และทุกชนิดข้อมูลถูกแสดงอย่างสม่ำเสมอด้วยรูปแบบ prefix
  • ใช้ and·or เป็นคีย์เวิร์ดควบคุมการไหล และคำสั่ง if·loop สามารถละวงเล็บปีกกาได้ตามต้องการ โดยตัว formatter จะช่วยรับประกันความปลอดภัย
  • โดยไม่มีเนมสเปซ Zig จัดการ ทุกอย่างเป็น expression เพื่อรวมไวยากรณ์ของชนิดข้อมูล·ค่า·แพตเทิร์นเข้าด้วยกัน และใช้งาน generic·record literal·ฟังก์ชันในตัว (@import, @as เป็นต้น) ได้อย่างกระชับ

ภาพรวม

  • Zig มีรูปลักษณ์คล้าย Rust แต่เลือกใช้โครงสร้างภาษาที่เรียบง่ายกว่า
  • การออกแบบไวยากรณ์มุ่งเน้นที่ ความเป็นมิตรต่อ grep, ความสม่ำเสมอของไวยากรณ์, และ การลดสิ่งรบกวนทางสายตาที่ไม่จำเป็น

ลิเทอรัลจำนวนเต็ม

const an_integer = 92;  
assert(@TypeOf(an_integer) == comptime_int);  
  
const x: i32 = 92;  
const y = @as(i32, 92);  
  • ลิเทอรัลจำนวนเต็มทั้งหมดมีชนิดเป็น comptime_int
  • เมื่อต้องกำหนดค่าให้ตัวแปร ต้องระบุชนิดอย่างชัดเจนหรือใช้ @as เพื่อแปลง
  • รูปแบบ var x = 92; ใช้งานไม่ได้ และต้องระบุชนิดอย่างชัดเจน

ลิเทอรัลสตริง

const raw =  
    \\Roses are red  
    \\  Violets are blue,  
    \\Sugar is sweet  
    \\  And so are you.  
    \\  
;  
  • แต่ละบรรทัดเป็นโทเค็นแยกกัน จึงไม่มีปัญหาเรื่องการเยื้อง
  • ไม่จำเป็นต้อง escape \\ เอง

record literal

const p: Point = .{  
    .x = 1,  
    .y = 2,  
};  
  • รูปแบบ .x = 1 ช่วยแยกความต่างระหว่างการอ่าน/เขียนได้ดี
  • สัญกรณ์ .{} แยกจาก block ได้ชัดเจน และแปลงเป็นชนิดผลลัพธ์โดยอัตโนมัติ

สัญกรณ์ชนิดข้อมูล

u32        // จำนวนเต็ม  
[3]u32     // อาร์เรย์ความยาว 3  
?[3]u32    // อาร์เรย์ที่เป็น null ได้  
*const ?[3]u32 // พอยน์เตอร์ค่าคงที่  
  • ชนิดข้อมูลทั้งหมดใช้สัญกรณ์แบบ prefix
  • การ dereference ใช้สัญกรณ์แบบ suffix (ptr.*)

identifier

const @"a name with space" = 42;  
  • ใช้หลีกเลี่ยงการชนกับคีย์เวิร์ด หรือกำหนดชื่อพิเศษได้

การประกาศฟังก์ชัน

pub fn main() void {}  
fn add(x: i32, y: i32) i32 {  
    return x + y;  
}  
  • คีย์เวิร์ด fn กับชื่อฟังก์ชันอยู่ติดกัน ทำให้ค้นหาได้ง่าย
  • การระบุชนิดคืนค่าไม่ใช้ ->

การประกาศตัวแปร

const mid = lo + @divFloor(hi - lo, 2);  
var count: u32 = 0;  
  • ใช้ const และ var
  • การระบุชนิดอยู่ในลำดับ ชื่อ: ชนิด

การควบคุมการไหล: and/or

while (count > 0 and ascii.isWhitespace(buffer[count - 1])) {  
    count -= 1;  
}  
  • and, or เป็นคีย์เวิร์ดควบคุมการไหล
  • การคำนวณแบบบิตใช้ &, |

คำสั่ง if

.direction = if (prng.boolean()) .ascending else .descending;  
  • วงเล็บจำเป็น แต่วงเล็บปีกกาเป็นทางเลือก
  • zig fmt ช่วยรับประกันการจัดรูปแบบที่ปลอดภัย

ลูป

for (0..10) |i| {  
    print("{d}\n", .{i});  
} else @panic("loop safety counter exceeded");  
  • ทั้ง for และ while รองรับส่วน else
  • จัดวาง iterator และชื่อตัวแปรองค์ประกอบได้อย่างเข้าใจง่าย

เนมสเปซและการ resolve ชื่อ

const std = @import("std");  
const ArrayList = std.ArrayList;  
  • ไม่อนุญาตให้ shadow ตัวแปร
  • ไม่มีเนมสเปซและไม่มี glob import

ทุกอย่างคือ expression

const E = enum { a, b };  
const e: if (true) E else void = .a;  
  • รวมไวยากรณ์ของชนิดข้อมูล·ค่า·แพตเทิร์นเข้าด้วยกัน
  • สามารถวาง conditional expression ในตำแหน่งของชนิดข้อมูลได้

generic

fn ArrayListType(comptime T: type) type {  
    return struct {  
        fn init() void {}  
    };  
}  
  
var xs: ArrayListType(u32) = .init();  
  • generic แสดงด้วยไวยากรณ์แบบการเรียกฟังก์ชัน (Type(T))
  • อาร์กิวเมนต์ชนิดข้อมูลต้องระบุอย่างชัดเจนเสมอ

ฟังก์ชันในตัว

const foo = @import("./foo.zig");  
const num = @as(i32, 92);  
  • เรียกใช้ความสามารถที่คอมไพเลอร์มีให้ด้วย prefix @
  • @import แสดงพาธไฟล์อย่างชัดเจน
  • อาร์กิวเมนต์ต้องเป็น string literal เท่านั้น

บทสรุป

  • ไวยากรณ์ของ Zig เป็นตัวอย่างของการที่ ตัวเลือกเล็กๆ หลายอย่าง รวมกันจนกลายเป็น ภาษาที่อ่านง่าย
  • เมื่อจำนวนฟีเจอร์ลดลง ไวยากรณ์ที่จำเป็นก็ลดลงด้วย และ โอกาสเกิดการชนกันระหว่างไวยากรณ์ก็ลดลง
  • ยืม แนวคิดที่ดีจากภาษาเดิม มาใช้ แต่เมื่อจำเป็นก็กล้านำไวยากรณ์ใหม่มาใช้

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น