6 điểm bởi GN⁺ 2025-09-27 | 3 bình luận | Chia sẻ qua WhatsApp
  • Về quản lý bộ nhớ, Zig cung cấp cách tiếp cận đơn giản và trực quan hơn Rust
  • Borrow checker của Rust rất mạnh, nhưng với việc phát triển các công cụ CLI nhỏ, nó lại gây ra độ phức tạp quá mức và gánh nặng cho lập trình viên
  • Quản lý bộ nhớ thủ công của Zig vẫn có thể đạt được độ an toàn bộ nhớ hiệu quả chỉ với công cụ phù hợp và một chút kỷ luật từ lập trình viên
  • Độ an toàn của chương trình không chỉ là an toàn bộ nhớ, mà còn phụ thuộc vào nhiều yếu tố như hành vi có thể dự đoán được, hiệu năng có thể kiểm soát, bảo vệ dữ liệu
  • Rust phù hợp với các hệ thống quy mô lớn, nhưng với các công cụ CLI nhỏ và thực dụng thì Zig có lợi thế hơn về năng suất phát triển và khả năng bảo trì

Tổng quan

Gần đây, khi tạo các công cụ CLI, tôi ưu tiên chọn Zig hơn là Rust

Nền tảng của quản lý bộ nhớ: stack và heap

  • Stack là vùng bộ nhớ nhanh có kích thước cố định, lưu trữ dữ liệu rất tạm thời như tham số hàm, biến cục bộ, địa chỉ trả về
  • Heap là vùng dùng cho cấp phát bộ nhớ động, được sử dụng khi dữ liệu có vòng đời dài hơn hoặc kích thước chỉ được xác định lúc chạy
  • Stack có cấu trúc đơn giản nhưng không gian hạn chế, còn heap thì cần quan tâm nhiều hơn đến tốc độ và phân mảnh

Borrow Checker của Rust

  • Borrow checker của Rust đảm bảo an toàn bộ nhớ tại thời điểm biên dịch
  • Nó áp đặt các quy tắc về tham chiếu, quyền sở hữu và vòng đời (lifetime) để ngăn chặn trước các lỗi như dereference con trỏ null hay dangling pointer
  • Tuy nhiên, an toàn bộ nhớ chỉ được kiểm tra theo tiêu chí thời điểm biên dịch, chứ không thể loại bỏ hoàn toàn sai sót của người dùng hay các vấn đề thiết kế sở hữu phức tạp

Trường hợp thực tế: Notes CLI của riêng tôi

  • Khi tôi định viết một CLI quản lý ghi chú cá nhân bằng Rust, borrow checker khiến tôi phải vất vả thiết kế lại cấu trúc
  • Ngược lại, trong Zig, chỉ cần dùng allocator là có thể tạo chỉ mục dựa trên con trỏ và tự do thay đổi/xóa dễ dàng hơn nhiều
  • Borrow checker của Rust có mục tiêu rất rõ ràng, nhưng với Zig, chỉ cần kiến thức nền tảng về quản lý bộ nhớ và một chút kỷ luật là vẫn có thể đạt được mức hiệu quả và an toàn cao

Khi an toàn bộ nhớ không phải là toàn bộ khái niệm an toàn của công cụ CLI

  • Độ an toàn thực sự của một sản phẩm còn bao gồm nhiều yếu tố như hành vi có thể dự đoán được, phản hồi có ý nghĩa khi xảy ra lỗi, bảo vệ dữ liệu nhạy cảm, khả năng chống chịu trước tấn công
  • Dù là Rust hay Zig, nếu không đáp ứng được các điều kiện ngoài an toàn bộ nhớ thì cũng khó có thể gọi là “an toàn”
  • Ví dụ, nếu CLI lặng lẽ ghi đè dữ liệu khi có lỗi hoặc thiết lập sai quyền truy cập tệp, người dùng có thể gặp vấn đề nghiêm trọng
  • Độ an toàn của công cụ CLI

    • Hành vi có thể dự đoán được: cần đảm bảo hành vi nhất quán và rõ ràng ngay cả khi đầu vào sai hoặc xuất hiện tình huống bất ngờ
    • Ngăn crash và hỏng dữ liệu: cần xử lý lỗi một cách êm ái, đồng thời tránh làm hỏng dữ liệu hoặc phát sinh crash không được thông báo
    • Quản lý hiệu năng: ngay cả khi xử lý lượng dữ liệu lớn cũng không được để xảy ra tiêu hao tài nguyên quá mức hoặc giảm độ phản hồi
    • Bảo vệ thông tin nhạy cảm: cần chú ý đến tệp tạm và thiết lập quyền truy cập
    • Khả năng chống chịu trước tấn công: cần vững vàng trước các vấn đề như kiểm tra đầu vào, tràn bộ nhớ, tấn công chèn lệnh

Điểm mạnh và giới hạn của Rust Borrow Checker

  • Điểm mạnh

    • Ngăn data race và tham chiếu trùng lặp: trình biên dịch đảm bảo quy ước một tham chiếu mutable duy nhất hoặc nhiều tham chiếu immutable
    • Bảo đảm mạnh ở thời điểm biên dịch: phần lớn lỗi liên quan đến bộ nhớ bị chặn trước khi chạy
    • Phát hiện lỗi sớm: đây là lợi thế lớn trong các dịch vụ thương mại hoặc hệ thống đồng thời
  • Giới hạn và bất tiện

    • Gánh nặng nhận thức: ngay cả với tác vụ CLI nhỏ cũng buộc phải cân nhắc quyền sở hữu/vòng đời/quản lý tham chiếu
    • Boilerplate và méo mó cấu trúc: các wrapper như Rc, RefCell, việc lạm dụng clone hay thiết kế lại cấu trúc khiến người ta tập trung vào việc “làm hài lòng trình biên dịch” thay vì “giải quyết vấn đề”
    • Bất lực trước lỗi logic/trạng thái: nó chỉ đảm bảo quy tắc bộ nhớ, chứ không đảm bảo tính dự đoán, lỗi logic hay tính toàn vẹn dữ liệu
    • Độ phức tạp ở các edge case: xung đột lifetime dễ phát sinh trong cache, trạng thái toàn cục, mutable index
  • Kết quả là, trong các dự án CLI nhỏ, borrow checker của Rust trở thành một “loại thuế tinh thần” đối với lập trình viên và có thể khiến mọi thứ phức tạp hơn mức thực sự cần thiết

Cách tiếp cận của Zig với an toàn và sự đơn giản

  • Zig dựa trên các kiểm tra an toàn có thể lựa chọn và quản lý bộ nhớ thủ công
  • Nó tích hợp sẵn khái niệm allocator, giúp hiện thực hóa việc sử dụng bộ nhớ có cấu trúc và có thể dự đoán được
  • Bạn cũng có thể tự tạo allocator tùy biến để chỉ định cách quản lý bộ nhớ phù hợp với đặc tính dự án của mình
  • Nhờ cú pháp defer của Zig, việc tự động giải phóng và dọn dẹp tài nguyên khi kết thúc phạm vi cũng trực quan hơn nhiều
  • Khác với Rust, Zig nhấn mạnh trách nhiệm của lập trình viên, nên cần có kỷ luật, nhưng nếu thiết kế cấu trúc tốt thì việc đạt được và duy trì an toàn bộ nhớ vẫn khá dễ dàng
  • Zig có mã nguồn gọn gàng hơn, và việc thay đổi cấu trúc như con trỏ, danh sách, chỉ mục cũng đơn giản hơn Rust rất nhiều
  • Không bị ràng buộc như Rust, vẫn có thể hiện thực mã an toàn và hiệu quả ở cùng một mức độ
  • Ngoài ra, tính năng comptime của Zig còn hỗ trợ rất nhiều cho việc thực thi mã, kiểm thử và tối ưu hóa tại thời điểm biên dịch

Tầm quan trọng của trải nghiệm lập trình viên (Developer Ergonomics)

  • Trải nghiệm lập trình viên (ergonomics) là yếu tố bao trùm từ cú pháp ngôn ngữ, tooling, tài liệu cho đến cộng đồng
  • Rust nhờ những quy tắc cực kỳ nghiêm ngặt mà cuối cùng có thể đảm bảo an toàn bộ nhớ, nhưng các quy tắc quá nặng và ceremony lại làm giảm năng suất
  • Zig nhấn mạnh thiết kế do lập trình viên dẫn dắt, nên việc viết/sửa/hiểu mã trở nên dễ và nhanh hơn
  • Zig với mã trực quan, vòng lặp cải tiến nhanh, gánh nặng nhận thức thấp giúp lập trình viên tập trung giải quyết vấn đề thay vì phải vật lộn với công cụ
  • Zig tin tưởng lập trình viên và trao cho họ công cụ cùng quyền lựa chọn phù hợp, trong khi Rust đôi khi có thể tạo cảm giác quá giám sát và hạn chế
  • Thay vì chỉ “bảo vệ lập trình viên khỏi sai lầm”, một môi trường thân thiện với lập trình viên là môi trường đảm bảo cơ hội để họ tự học hỏi và trưởng thành thông qua chính những sai lầm của mình

Kết luận

  • Với các lĩnh vực mà ưu thế của Rust được phát huy tối đa như hệ thống lớn, đa luồng, chạy dài hạn, thì Rust vẫn là lựa chọn tốt nhất
  • Tuy nhiên, với các công cụ CLI nhỏ nhưng thiết thực, sự gọn nhẹ, đơn giản, tốc độ triển khai và bảo trì của Zig phù hợp hơn
  • An toàn bộ nhớ chỉ là một mảnh của bức tranh an toàn; những yếu tố thiết yếu với công cụ CLI như hành vi có thể dự đoán được, khả năng bảo trì, độ vững chắc… lại dễ đạt được hơn trong Zig
  • Cuối cùng, điều quan trọng không phải là “ngôn ngữ tốt hơn”, mà là lựa chọn công cụ phù hợp với quy trình làm việc và đặc tính dự án của chính mình
  • Zig là ngôn ngữ cực kỳ phù hợp để phát triển các công cụ nhỏ, nơi hội tụ “an toàn bộ nhớ + chi phí nhận thức thấp + tính thân thiện với lập trình viên/năng suất

3 bình luận

 
shakespeares 2025-10-05

Có vẻ như hệ sinh thái của nó vẫn chưa ổn định bằng Rust.

 
bus710 2025-09-27

Vì Zig ở các phiên bản mới khá thường xuyên có breaking change... nên có vẻ dù là dự án nhỏ thì tốt nhất vẫn nên gắn CI vào để tiếp tục duy trì, quản lý.

 
GN⁺ 2025-09-27
Ý kiến Hacker News
  • Ưu điểm của Zig là cho phép tiếp tục suy nghĩ như một lập trình viên C, nhưng ở một mức độ nào đó, đây đơn giản cũng là vấn đề quen tay

    • Những lập trình viên đã đủ quen với Rust thì không còn phải "đấu" với borrow checker nữa, vì họ đã suy nghĩ theo cấu trúc mã như vậy rồi

    • Kiểu tiếp cận như “object soup” trong Rust không hoạt động tốt, nhưng thực ra tôi không nghĩ đó vốn là cách dễ hơn về bản chất, chỉ là vì chúng ta quen nên thấy nó dễ hơn thôi

    • Nếu chấp nhận tiền đề rằng ergonomics (trải nghiệm sử dụng) rất khó đo lường hay định lượng, thì những tranh luận như trên sẽ cứ mãi mơ hồ

      • Nó giống như kiểu nói: "Cứ yên tâm ngồi lên cái ghế này vì nó sẽ không sập đâu, chỉ là nó có thể kém thoải mái hơn và nặng hơn một chút, nhưng đa số mọi người rồi sẽ quen và không còn thấy bất tiện nữa"
      • Giống như câu trong bài gốc: "Rust cho trải nghiệm lập trình viên kém thoải mái hơn nhưng mang lại an toàn bộ nhớ, còn Zig có thể mang lại trải nghiệm tốt hơn cho lập trình viên và vẫn có an toàn bộ nhớ nếu cẩn thận thêm một chút", rốt cuộc đây vẫn là sự đánh đổi giữa an toàn và tính tiện dụng
      • Tôi nghĩ cộng đồng Rust nên thẳng thắn thừa nhận kiểu trade-off này, vì việc đảm bảo an toàn luôn đi kèm mức độ kém thuận tiện hơn
      • Điều này là nền tảng trong bảo mật, sinh mạng, đời sống hằng ngày và phần mềm nói chung, và phần lớn các lập luận ở đây thường khá mơ hồ hoặc chủ quan
      • Cũng có người rất dễ gạt qua vấn đề ergonomics bằng cách nói “người quen rồi thì chẳng có vấn đề gì”, điều này có thể tạo cảm giác như đang nói “nếu đến mức đó mà còn thấy khó thì là do bạn kém thông minh hơn”
    • Câu chuyện “đấu với borrow checker” bắt nguồn từ thời người ta mới chỉ hiểu lifetime theo kiểu lexical trong Rust

      • Khi tôi học Rust vào năm 2021 thì đó đã là chuyện cũ rồi
      • Trên thực tế, với những người trước giờ chỉ dùng Python, C, JavaScript... thì việc thích nghi với Rust quả thật có thể không dễ
      • Với cá nhân tôi thì nó đến khá tự nhiên, nhưng có vẻ đa số không cảm nhận như vậy
      • Tuy nhiên, cách nói “trong Rust bạn phải đọc thông báo chẩn đoán rồi sửa mã” không nghe ngầu bằng “dũng cảm chiến đấu với borrow checker”, nên tôi nghĩ cần diễn đạt thực tế theo kiểu anh hùng hơn một chút
    • Theo kinh nghiệm của tôi, các lập trình viên Rust dày dạn thường rải Arc khắp nơi và dùng nó gần như garbage collection tự động

      • Quản lý bộ nhớ tĩnh khá nghiêm ngặt nên với các cấu trúc dữ liệu phức tạp thì thực tế rất khó
      • Vì lifetime, số đường suy luận phải theo dõi vượt quá khả năng nhận thức của con người
    • Tôi cũng đã thấy nhiều dự án Rust mã nguồn mở mà ngay cả các lập trình viên Rust có kinh nghiệm cũng dùng Arc, Clone, Copy... khắp nơi

    • Điểm mạnh của Zig là vẫn có thể phát triển theo kiểu quen thuộc như C, đồng thời tận dụng được các tính năng an toàn từ ngôn ngữ và tooling

      • Ví dụ, nhờ optional của Zig mà có thể tránh lỗi nil dereference
      • Khi debug hay test, có thể tự truyền debug/custom allocator để dễ dàng kiểm tra runtime, truy cập bộ nhớ và rò rỉ tài nguyên
      • Tôi có chút không hài lòng với việc thiếu interface/trait tường minh, nhưng bù lại cách tiếp cận đơn giản nên khá thực dụng
  • Tôi hầu như không đồng ý với nội dung bài gốc

    • Rust cũng giống C hay Zig ở chỗ buộc bạn phải suy nghĩ về lifetime, ownership và borrow scope, khác biệt là có hay không có sự hỗ trợ từ compiler

    • Dù thông minh đến đâu, con người vẫn sẽ mắc lỗi khi mệt mỏi hoặc mất tập trung, và biết thừa nhận điều đó mới là khôn ngoan

    • Không gian các chương trình mà compiler Rust coi là an toàn vẫn chưa đủ rộng, nên nó khá thường xuyên từ chối cả những chương trình hoàn toàn hợp lý

    • Ví dụ: nếu trong struct Foo, barbaz đều là chuỗi, thì khi lấy tham chiếu biến đổi tới bar rồi muốn lấy tham chiếu bất biến tới baz, mã sẽ không compile, và trong tình huống như vậy ta buộc phải lách cấu trúc mã một cách gượng ép

    • Nói ngược lại, chính việc phải đổi mã sang một thiết kế tốt thứ hai hoặc thứ ba chỉ để “tránh những trường hợp thực tế vẫn ổn nhưng lại bị từ chối compile” đã là một gánh nặng lớn

      • Làm vậy có thể thay đổi thiết kế của cả codebase
      • Đây cũng được dùng để giải thích vì sao những người làm việc khó như lập trình game cảm thấy việc áp dụng Rust là một gánh nặng
      • Nếu Rust compiler có thể hoạt động hoàn toàn chính xác mà không tạo ra cảnh báo sai kiểu này, thì xét về ergonomics nó cũng sẽ ở mức cực đỉnh, chỉ là thực tế không đơn giản như vậy
    • Ví dụ trên thực sự là một trường hợp rất hay, tôi muốn hỏi liệu có thể dùng nó trong blog hay bài viết của mình không

    • Nhìn đoạn mã trên xong tôi lại càng bớt tự tin vào lập luận của mình

  • Chúng ta cần nhớ rằng không phải mọi chương trình đều nhất thiết phải “an toàn” đến mức đó

    • Nhiều người trong chúng ta lớn lên cùng những phần mềm Unsafe mà vẫn rất yêu thích, như Star Fox 64, MS Paint, FruityLoops...

    • Tôi từng đọc rằng Andrew Kelley, người tạo ra Zig, đã làm Zig vì thiếu một môi trường phù hợp để phát triển phần mềm sản xuất âm nhạc (DAW), và tôi nghĩ Zig khá hợp với kiểu phần mềm sáng tạo như vậy

    • Ai nhạy cảm với lỗi bộ nhớ thì cứ dùng Rust

    • Tôi còn tin rằng Super Mario World thú vị hơn chính vì các lỗi bộ nhớ của nó

    • “An toàn” là cách nói rút gọn của “chương trình của tôi hoạt động đúng như dự định”

      • Mã phi logic, vô nghĩa về mặt ngữ nghĩa thì bất lợi cho việc đạt mục tiêu
      • Dĩ nhiên cũng có trường hợp người ta cố ý viết mã khó hiểu theo hướng nghệ thuật như IOCCC, hacking hay code poetry, nhưng trong những trường hợp đó thì phải chế tác rất cẩn thận
      • Trong Rust cũng có thể cố ý hiện thực kiểu đó thông qua escape hatch là unsafe
      • Lập luận trong bài giống như đang nói việc vô tình viết ra mã vô nghĩa lại là một ưu điểm, và tôi rất khó đồng ý với điều đó
      • Nếu có thể khiến mọi đoạn mã đều an toàn mà không có nhược điểm nào, chẳng phải ai cũng sẽ muốn thế sao?
      • Những thứ như speedrun Super Mario World vẫn có thể làm được bằng binary patch, tôi không cho rằng niềm vui duy nhất nằm ở việc thao tác bộ nhớ thông qua đầu vào
    • Tôi hơi bối rối, không biết có phải mọi người nghĩ ý kiến của tôi tệ vì nó hàm ý rằng an toàn bộ nhớ là không quan trọng không

  • Tôi thấy tiếc vì giá trị của borrow checker đã bị đánh giá thấp

    • Borrow checker của Rust đảm bảo ở thời điểm compile rằng sẽ không có truy cập bộ nhớ không hợp lệ

    • Dĩ nhiên, cái giá là đôi khi phải đổi cấu trúc mã để phù hợp với các quy tắc của compiler

    • Khi tự dùng Rust riêng, tôi chưa từng cảm thấy các lifetime annotation là sai, chúng chỉ giống như một việc lặt vặt hơi phiền nhưng rồi cũng nhanh chóng thành quen

    • Chừng nào chưa dùng unsafe, trong Rust không thể có chuyện hai thread cùng lúc ghi vào cùng một vùng nhớ

    • Tôi không đồng cảm với ý “vì sao Zig lại thực dụng hơn trong CLI tool”, vì Rust vẫn có lợi thế rõ ràng trong việc ngăn CVE

    • Trên thực tế, phần lớn công việc của tôi vẫn làm tốt bằng ngôn ngữ GC, còn khi đóng góp cho ngôn ngữ khác thì Rust, Zig hay C/C++ tôi đều dùng được

    • CLI tool có gì đặc biệt đâu?

      • Thông thường CLI tool không quá lớn hoặc thường do cá nhân phát triển nên dễ quản hơn
      • Zig hay C có thể không hợp với codebase lớn, còn dự án phức tạp hơn thì cần một “người trông trẻ”
      • Tranh luận tương tự trước đây từng xảy ra với Java khi bị gọi là “ngôn ngữ bảo mẫu”, nhưng thực tế nhiều codebase đúng là cần như vậy
    • Câu nói rằng không dùng unsafe thì hai thread không thể cùng ghi vào cùng một vùng nhớ thật ra không hoàn toàn rạch ròi như vậy

      • Kiểu hỗ trợ từ compiler mà tôi muốn chủ yếu là giải quyết vấn đề memory ordering
      • Trong Rust, ngay cả khi có race ở phần này thì nó vẫn được xếp vào safe chứ không phải unsafe
  • Tôi đồng ý rằng việc hiện thực backlinks trong Rust quá phức tạp

    • Có thể làm được bằng Rc, Weak, RefCell, .borrow()..., nhưng không hề dễ

    • Nếu là chương trình chạy ngắn thì arena allocation cũng là một cách hay, có lẽ đây chính là kiểu CLI tool đang được nhắc tới

    • Rust thực sự phát huy sức mạnh ở các ứng dụng lớn, đa luồng, chạy thời gian dài

    • Tôi từng thực sự viết một client metaverse lớn bằng Rust, chạy hàng chục thread suốt 24 giờ mà không hề có rò rỉ bộ nhớ hay crash

    • Nếu làm điều tương tự bằng C++, sẽ cần đội QA và các công cụ như Valgrind là bắt buộc, còn ngôn ngữ scripting thì quá chậm về hiệu năng

    • Tôi cũng từng làm một máy bay mô phỏng vật lý bằng Rust, có tính cả độ cong Trái Đất và sai lệch trọng lực

      • Các bài test đường bay 5 giờ, 22 giờ đã chạy trong nhiều năm mà không gặp vấn đề gì
      • Trong 7 năm dùng Rust, tôi chỉ gặp crash vài lần, còn C/C++ thì giờ chỉ dùng khi phải sửa mã di sản cũ
  • Zig đúng là hấp dẫn, nhưng D vẫn còn đó, và cá nhân tôi thấy D mới là thứ thay thế C/C++ mà tôi muốn

    • Cú pháp Zig hơi có gì đó không hợp gu, còn Rust thì đã trở thành trung tâm của hệ sinh thái rồi

    • Go cũng chiếm thị phần lớn trong nhiều toolchain, và trong lĩnh vực AI thì được dùng nhiều chỉ sau Python

    • Trước thời Rust từng có tranh luận Go vs. D, và tôi thậm chí đã mua cả sách D rồi cuối cùng vẫn chuyển sang Go

      • Với tôi, standard library của Go thực dụng hơn nhiều, và tên kiểu dữ liệu như int64 cũng trực quan hơn
    • D tốt đấy, nhưng chưa có killer app đủ để phổ biến rộng rãi

  • Tôi không thực sự hiểu vì sao phải cố dùng Rust hay Zig để viết CLI tool

    • Nút thắt cổ chai là I/O chứ không phải GC chậm

    • Trừ khi là game, DB hay loại ứng dụng ngốn bộ nhớ, còn không thì vấn đề GC không phải trọng tâm

    • Tôi muốn nhấn mạnh rằng thay vì tranh cãi về an toàn bộ nhớ, đáng để suy nghĩ hơn là vì sao phải chọn ngôn ngữ không cần GC

    • Nếu lý do là “vì không có GC thì vui hơn”, vậy như thế đã đủ rồi, chẳng cần tranh luận gì thêm

    • Thời gian startup tức thì, gần như không có độ trễ khi chạy, là một lợi ích rất lớn

      • Khi làm tool bao bọc, có chạy hàng nghìn lần cũng không thấy nặng nề
      • Việc phân phối cũng dễ hơn vì không có độ phức tạp triển khai như môi trường Python
    • Viết CLI bằng Go là một trải nghiệm rất ổn, dù bản thân tôi không thích ngôn ngữ Go lắm

      • CLI Python nếu có nhiều dependency thì việc phân phối khá phiền, còn Rust/Zig cũng nổi tiếng vì dễ phát hành binary tĩnh giống Go
    • Tôi ưu tiên số một những ngôn ngữ có sum type, pattern matching và hỗ trợ async

      • Ngay cả ngoài Rust, tôi vẫn thích các tính năng có thể bắt lỗi ở thời điểm compile
    • Về ý cho rằng phát triển không có GC chỉ liên quan đến game

      • Thực tế nhiều game di động cũng dùng GC, như môi trường Unity + il2cpp, và hiệu năng GC cũng không phải lúc nào tốt
    • Tranh luận về GC có phần giống hiệu ứng bandwagon

      • Từ 50 năm trước đã có những workstation lớn được xây thành công bằng ngôn ngữ dựa trên GC như Interlisp, Cedar...
      • Phần cứng ngày nay mạnh hơn CLI thập niên 1970 hay ứng dụng Electron rất nhiều, nhưng chúng ta vẫn chưa tận dụng hiệu quả
  • Tôi đã làm một note tool đơn giản bằng borrow/referencing tích hợp sẵn của Rust, và nó không phức tạp như tôi tưởng

    • Nếu hình dung cấu trúc kiểu lưu chỉ số trong danh sách notes rồi nối bằng map, thì gần như không có khác biệt về tốc độ mà cũng chẳng có bất lợi về an toàn

    • Nếu có nhầm chỉ số thì cũng chỉ thành lỗi out-of-bounds, vẫn tốt hơn rất nhiều so với việc ghi đè lên bộ nhớ kernel

    • Ngay cả lúc debug bằng printf cũng dễ và trực quan hơn nhiều

    • Raw pointer hay reference thường chỉ nên dùng ở những nơi thực sự cần thiết như allocator hay async runtime, còn với logic thông thường thì cách làm dựa trên index phù hợp hơn

    • Đây cũng là lý do nổi tiếng khiến async trong Rust không dùng được self-referential struct và phát sinh các vấn đề quanh Pin

    • Con trỏ tới giá trị lưu trong vec sẽ mất hiệu lực nếu xảy ra realloc hay tình huống tương tự, và khi đó Miri sẽ báo lỗi ngay

  • Nếu tôi là một lập trình viên C++ đang tìm ngôn ngữ an toàn, tôi sẽ thấy Swift là lựa chọn phù hợp nhất

    • Một ngôn ngữ quen thuộc hoặc giống thứ mình đã biết sẽ giúp thích nghi nhanh hơn

    • Swift gần đây cũng tăng cường hỗ trợ đa nền tảng, và có nhiều người đang làm trong ủy ban chuẩn C++ tham gia

    • Tuy vậy, do gắn nhiều với Apple và thiếu framework UI native phổ biến, nên việc mở rộng sang phe ngoài Apple có vẻ vẫn chậm hơn

    • Tôi hy vọng Swift sẽ trở nên phổ biến hơn nữa

    • Nếu có tài liệu nào so sánh Swift với Zig/C thì rất mong được gợi ý

  • Có ý rằng Zig cũng có thể tạo ra phần mềm an toàn bộ nhớ nếu đủ cẩn thận, nhưng thật ra C cũng cho kết quả tương tự nếu dùng có kỷ luật ở một mức nhất định

    • Vấn đề là chính cái “một chút tiết chế/kỷ luật” ấy ngoài đời thực thường không đủ, nên lỗi mới phát sinh

    • Zig còn xử lý thêm các vấn đề dưới đây

      • Truy cập out-of-bounds (chiếm 70% tổng số CVE)
      • null pointer dereference
      • an toàn kiểu dữ liệu
      • Vượt trội hơn C rất nhiều, và cả các lỗi như use-after-free cũng dễ tránh hơn hẳn miễn là không vượt ra ngoài ranh giới
      • Hệ thống build đa nền tảng xuất sắc của Zig, tối ưu hóa comptime, và thời gian build nhanh hơn C++/Rust hàng chục lần cũng là điểm mạnh
      • Dù standard library vẫn còn thiếu sót và vẫn còn những vấn đề lặt vặt, tôi nghĩ tương lai của nó rất sáng trong các chương trình thiên về hiệu năng
    • Nếu suốt hơn 50 năm mà C vẫn thất bại với vấn đề kỷ luật này, thì đó là chuyện còn khó hơn cả “con đường của Thiếu Lâm”