Giải cấu trúc diễn ngôn Rust


최종 수정일:

Hodong Kim <hodong@nimfsoft.com>

Lời nói đầu

Cuốn sách này phân tích đồng thời các đặc tính kỹ thuật của ngôn ngữ lập trình Rust và những diễn ngôn kỹ thuật, xã hội cụ thể đã hình thành xung quanh nó. Ở đây, giải cấu trúc không có nghĩa là phủ định trước một công nghệ hay một lập luận. Thuật ngữ này chỉ việc tách biệt sự thật kỹ thuật, bảo đảm do ngôn ngữ cung cấp, chi phí kỹ thuật, cách diễn giải quan hệ nhân quả, phán đoán giá trị và lối diễn đạt tu từ, rồi xem xét căn cứ và phạm vi áp dụng của từng yếu tố. Cuốn sách khảo sát trong bối cảnh lịch sử và kỹ thuật những thiết kế Rust đã lựa chọn để đạt được tính an toàn, hiệu năng và tính đồng thời, cùng các chi phí và ràng buộc đi kèm các lựa chọn đó.

Nội dung được triển khai xoay quanh các câu hỏi sau.

  1. Safe Rust ngăn chặn những loại lỗi bộ nhớ và tranh chấp dữ liệu nào, và các bảo đảm đó còn hiệu lực đến đâu trước unsafe, giao diện hàm ngoại (FFI), lỗi logic và sự cố vận hành?
  2. So với cách tiếp cận của C++, các ngôn ngữ dùng bộ thu gom rác (GC)1, Ada và SPARK, cơ chế sở hữu, mượn, vòng đời, hệ thống kiểu và trừu tượng hóa không chi phí của Rust có những ưu điểm và đánh đổi nào?
  3. Các trường hợp áp dụng và kết quả định lượng tại doanh nghiệp và dự án nguồn mở chứng minh tác động của bản thân Rust đến mức nào, và làm sao phân biệt tác động đó với ảnh hưởng của thay đổi về kiến trúc, thuật toán, runtime, phần cứng và tổ chức?
  4. Trong những điều kiện nào cần phân biệt và kết hợp việc tái cấu trúc, hiện đại hóa từng bước, thay thế có chọn lọc các thành phần rủi ro và viết lại toàn bộ hệ thống hiện có?
  5. Những bước nhảy logic nào xuất hiện khi một lợi thế kỹ thuật có điều kiện bị chuyển thành tuyên bố về ưu thế phổ quát áp dụng cho mọi hệ thống, hoặc thành phán xét về trí tuệ và năng lực của lập trình viên?
  6. Tuyên bố rằng một ngôn ngữ cụ thể là “lựa chọn thay thế duy nhất” giả định những yêu cầu và tập hợp ứng viên nào, và những lỗi logic nào phát sinh khi các tiền đề và quá trình so sánh đó bị lược bỏ?

Để trả lời các câu hỏi này, cuốn sách ưu tiên các nguồn sơ cấp như đặc tả và tiêu chuẩn ngôn ngữ, tài liệu chính thức của dự án, báo cáo chính phủ, hồ sơ CVE, báo cáo kỹ thuật gốc của doanh nghiệp và nghiên cứu được bình duyệt. Khi xem xét một tuyên bố định lượng, sách kiểm tra đối tượng và mẫu nghiên cứu, tử số và mẫu số, đường cơ sở, khối lượng công việc, môi trường phần cứng và phần mềm, cùng khoảng thời gian so sánh. Sách phân biệt kết quả quan sát, ước lượng thống kê, quy kết nhân quả và diễn giải của tác giả, đồng thời áp dụng tiêu chuẩn chứng cứ giống nhau trong khả năng có thể cho cả trường hợp thành công lẫn thất bại. Khi tài liệu chỉ nói về một tổ chức hoặc hệ thống cụ thể, sách không khái quát vượt quá phạm vi đó và nêu rõ sự bất định cùng những cách giải thích thay thế.

Đối tượng so sánh bao gồm C++, Java, C#, Go, Ada và SPARK. Mục đích không phải là xếp một ngôn ngữ như sự thay thế đơn giản cho ngôn ngữ khác, mà là xem xét các ngôn ngữ và hệ sinh thái khác nhau lựa chọn chi phí như thế nào giữa hiệu năng, quyền kiểm soát bộ nhớ, năng suất phát triển, khả năng kiểm chứng, tính thời gian thực, công cụ và khả năng bảo trì dài hạn. Ada và SPARK là đối tượng so sánh cho một con đường lịch sử khác nhằm đạt an toàn và độ tin cậy mà không phụ thuộc vào GC. Sách cũng tách đặc tính ngôn ngữ khỏi chiến lược thay đổi, đánh giá tái cấu trúc, hiện đại hóa, thay thế một phần và viết lại như những công cụ kỹ thuật độc lập thay vì lựa chọn nhị phân giữa giữ lại và loại bỏ hệ thống hiện có.

Trong cuốn sách này, diễn ngôn Rust không có nghĩa là quan điểm chính thức của Rust Foundation, các nhóm phát triển cốt lõi hay toàn bộ cộng đồng. Các kênh chính thức của dự án Rust đã công khai thảo luận và cải thiện nhiều vấn đề như thời gian biên dịch, lập trình bất đồng bộ, công cụ và ranh giới an toàn. Đối tượng được phân tích ở đây là những kiểu lập luận cụ thể lặp lại trong một số diễn đàn kỹ thuật công khai và mạng xã hội. Các ví dụ trực tuyến này được sử dụng như tư liệu định tính để phân tích cấu trúc và chức năng diễn ngôn của lập luận, chứ không phải một mẫu thống kê chứng minh mức độ thường xuyên của chúng trong toàn cộng đồng.

Rust là một ngôn ngữ kết hợp bảo đảm an toàn bộ nhớ mạnh mà không cần GC với mức độ kiểm soát cao, và đã đạt được những kết quả quan trọng trong công nghiệp cũng như các dự án nguồn mở. Cuốn sách không được viết nhằm hạ thấp các thành tựu đó hoặc khuyến nghị một lựa chọn kỹ thuật cụ thể. Mục đích là xem xét ưu điểm và giới hạn, bảo đảm và chi phí, quan sát và diễn giải theo cùng một tiêu chuẩn. Vì vậy, kết luận của sách không phải tuyên bố cuối cùng mà là đánh giá dựa trên bằng chứng hiện có, và có thể được sửa đổi khi xuất hiện tài liệu tốt hơn hoặc phản ví dụ.


Giấy phép Creative Commons Tác phẩm này được cấp phép theo Giấy phép Creative Commons Ghi công–Phi thương mại–Không phái sinh 4.0 Quốc tế.


Mục lục


Phần 1: Sự xuất hiện của Rust và các đặc tính kỹ thuật

Phần 1 phân tích cách ngôn ngữ lập trình Rust tiếp cận các thách thức trong lĩnh vực lập trình hệ thống và những đặc tính qua đó Rust được thảo luận.

Chương 1 xem xét sự đánh đổi giữa hiệu năng và an toàn, vốn là bối cảnh ra đời của Rust, đồng thời giới thiệu các đặc tính kỹ thuật chính được đưa vào để giải quyết vấn đề này, gồm mô hình sở hữu, triết lý trừu tượng hóa không chi phí (ZCA) và hệ sinh thái tiêu biểu là Cargo.

Chương 2 phân tích các yếu tố phức hợp mà qua đó nền tảng kỹ thuật này tương tác với trải nghiệm nhà phát triển (DX), câu chuyện và sự bảo trợ của các tổ chức để tác động đến việc áp dụng.

1. Giới thiệu ngôn ngữ Rust và các đặc tính chính

Thay vì chỉ liệt kê các đặc tính của Rust, chương này xem xét hai vấn đề nhằm phân tích ranh giới của các bảo đảm an toàn bộ nhớ cũng như ưu điểm và đánh đổi trong thiết kế. Thứ nhất, Rust muốn giải quyết những loại lỗi và chi phí nào trong lập trình hệ thống? Thứ hai, các bảo đảm do sở hữu, mượn, vòng đời, hệ thống kiểu và trừu tượng hóa không chi phí cung cấp có phạm vi đến đâu, và chúng đi kèm những đánh đổi nào?

Để làm điều đó, chương phân biệt mục tiêu thiết kế của ngôn ngữ, bảo đảm ở cấp đặc tả, phần triển khai của trình biên dịch và thư viện, cùng kết quả quan sát được trong khối lượng công việc thực tế. Chương lần lượt xem xét sở hữu và mượn, trừu tượng hóa không chi phí, kiểu và đối sánh mẫu, cùng hệ sinh thái Cargo, nhưng không mở rộng một mục tiêu thiết kế cụ thể thành kết quả phổ quát về hiệu năng hoặc an toàn của mọi chương trình. Kết quả áp dụng trong công nghiệp và chiến lược thay đổi được xử lý ở các chương sau theo những tiêu chuẩn bằng chứng riêng.

1.1 Bối cảnh ra đời: Sự đánh đổi giữa hiệu năng và an toàn

Lập trình hệ thống có thể đồng thời đòi hỏi quyền kiểm soát phần cứng, quản lý tài nguyên có thể dự đoán, thông lượng và độ trễ, an toàn bộ nhớ, cùng khả năng ngăn chặn lỗi đồng thời. Tuy nhiên, mô tả điều này đơn giản như một lựa chọn nhị phân giữa hiệu năng và an toàn sẽ thu hẹp quá mức các phương án đã tồn tại trong lịch sử. C và C++ phát triển quanh quyền kiểm soát mức thấp và quản lý tài nguyên thủ công; Ada và SPARK kết hợp hệ thống kiểu mạnh, kiểm tra khi chạy, hợp đồng và xác minh hình thức; còn các ngôn ngữ dựa trên GC sử dụng thu hồi bộ nhớ tự động và runtime được quản lý. Cách tiếp cận phù hợp phụ thuộc vào mô hình lỗi, yêu cầu thời gian thực, khối lượng công việc, môi trường vận hành và yêu cầu xác minh.

Rust bắt đầu tại Mozilla Research và phát triển thành một ngôn ngữ lập trình hệ thống đồng thời theo đuổi an toàn bộ nhớ, tính đồng thời, quyền kiểm soát mức thấp và hiệu năng.2 Mô tả rằng Rust hướng tới việc cung cấp an toàn bộ nhớ không cần GC và hiệu năng có thể cạnh tranh với C++ là một mục tiêu thiết kế và đề xuất giá trị. Đây không phải là bảo đảm phổ quát rằng mọi chương trình Rust sẽ có hiệu năng giống mọi chương trình C++, hoặc rằng chi phí và lỗi khi chạy sẽ biến mất. Vì vậy, ba mục tiêu sau cũng phải được đọc bằng cách phân biệt mục tiêu thiết kế, bảo đảm của ngôn ngữ, đặc tính triển khai và kết quả quan sát được.

An toàn

Safe Rust ngăn chặn một số truy cập bộ nhớ không hợp lệ và tranh chấp dữ liệu thông qua sở hữu, mượn và các quy tắc kiểu. Bảo đảm này dựa trên giả định rằng trình biên dịch và thư viện, các trừu tượng được triển khai bằng unsafe, cùng các ranh giới FFI đều tuân thủ hợp đồng tương ứng.3 Nó không tự động bảo đảm không có panic, bế tắc, rò rỉ hoặc cạn kiệt tài nguyên, lỗi logic, mọi lỗ hổng bảo mật, hoặc gián đoạn tính liên tục của dịch vụ. Phạm vi bảo đảm chính xác sẽ được xem xét cụ thể trong các mục 1.2 và 3.2.

Hiệu năng

Rust tạo mã máy native mà không cần một bộ thu gom rác bắt buộc, đồng thời áp dụng nguyên tắc trừu tượng hóa không chi phí: thiết kế các trừu tượng cấp cao sao cho chúng không đòi hỏi chi phí runtime bổ sung có thể tránh được.4 Nguyên tắc này không có nghĩa là mọi trừu tượng luôn chạy với cùng tốc độ, hay thời gian biên dịch, kích thước tệp nhị phân, mức sử dụng bộ nhớ, độ khó khi gỡ lỗi và chi phí nhận thức của nhà phát triển đều bằng không. Hiệu năng thực tế phải được đo với khối lượng công việc, thuật toán, tối ưu hóa, cấp phát, I/O, thư viện và điều kiện phần cứng được nêu rõ.

Tính đồng thời

Hệ thống sở hữu và kiểu của Safe Rust ngăn chặn tranh chấp dữ liệu, nhưng không loại bỏ các điều kiện tranh đua nói chung, bế tắc, tình trạng đói, đảo ngược ưu tiên hoặc vấn đề nhất quán trong hệ thống phân tán.5 Vì vậy, “đồng thời không sợ hãi” nên được hiểu là một cách diễn đạt có phạm vi xác định: một số vi phạm an toàn bộ nhớ và tranh chấp dữ liệu bị chặn ở giai đoạn biên dịch, chứ không phải mọi lỗi đồng thời đều không tồn tại.

Điểm xuất phát quan trọng của chương này là phân biệt giữa việc Rust cùng theo đuổi an toàn, hiệu năng và tính đồng thời trong một thiết kế với việc những mục tiêu đó không đồng nghĩa với kết quả quan sát được trong mọi môi trường. Các mục tiếp theo lần lượt xem xét những bảo đảm cụ thể do sở hữu và mượn cung cấp, các chương trình hợp lệ bị từ chối, kiểm tra khi chạy và phụ thuộc triển khai, cùng những đánh đổi so với các thiết kế khác.

1.2 Quản lý bộ nhớ thông qua sở hữu, mượn và vòng đời

Mục này không xem sở hữu như một khẩu hiệu duy nhất mà phân tích nó thành ba tầng riêng biệt. Sở hữu biểu thị trách nhiệm dọn dẹp giá trị và tài nguyên, mượn giới hạn quyền truy cập mà không chuyển quyền sở hữu, còn vòng đời mô tả quan hệ nhằm ngăn tham chiếu được sử dụng lâu hơn giá trị mà nó trỏ tới. Ba tầng này liên quan với nhau nhưng không phải cùng một khái niệm.6

1. Sở hữu: Trách nhiệm dọn dẹp giá trị và tài nguyên

Trong Rust, mỗi giá trị có một chủ sở hữu và quyền sở hữu có thể được chuyển qua phép gán hoặc lời gọi hàm. Việc dùng lại một giá trị đã được chuyển thông qua biến ban đầu bị từ chối ở thời điểm biên dịch. Tuy nhiên, các giá trị như số nguyên có triển khai Copy được sao chép khi gán, nên biến ban đầu vẫn có thể tiếp tục được sử dụng. Vì vậy, mô tả “mọi phép gán đều là chuyển quyền sở hữu” là không chính xác.

Khi chủ sở hữu ra khỏi phạm vi hợp lệ, giá trị được dọn dẹp theo Drop. Một kiểu sở hữu vùng cấp phát heap có thể giải phóng vùng đó tại thời điểm này; tài nguyên như tệp, socket và khóa cũng có thể được gắn với quá trình hủy của kiểu. Quy tắc này là nền tảng để Safe Rust ngăn các lỗi như giải phóng hai lần và sử dụng sau giải phóng, nhưng không có nghĩa hàm hủy nhất thiết chạy trên mọi đường kết thúc. Tài nguyên có thể không được thu hồi ngay khi tiến trình bị cưỡng bức kết thúc hoặc abort, khi cố ý làm rò rỉ, hay khi tồn tại chu trình tham chiếu đếm.

2. Mượn: Quyền truy cập tách biệt với quyền sở hữu

Tham chiếu không sở hữu đối tượng mà nó trỏ tới. Tham chiếu dùng chung &T cung cấp quyền đọc trong thời gian còn hiệu lực, còn tham chiếu khả biến &mut T biểu diễn quyền truy cập độc quyền trong khoảng thời gian đó. Quy tắc thường được tóm tắt là “nhiều tham chiếu dùng chung hoặc một tham chiếu khả biến”, nhưng điểm cốt lõi là không cho phép biệt danh và thay đổi xảy ra đồng thời trong lúc tham chiếu thực sự được sử dụng.6

Các quy tắc này ngăn tranh chấp dữ liệu do đọc và ghi đồng thời không đồng bộ trong Safe Rust. Tuy nhiên, chúng không loại bỏ các điều kiện tranh đua nói chung khi kết quả phụ thuộc thứ tự thực thi, bế tắc, tình trạng đói hay đảo ngược ưu tiên. Tính khả biến nội tại dựa trên UnsafeCell, con trỏ thô và mã unsafe cũng đòi hỏi các bất biến riêng mà giao diện bên ngoài an toàn phải duy trì.

3. Vòng đời: Quan hệ chi phối hiệu lực của tham chiếu

Vòng đời không phải cơ chế runtime trực tiếp điều khiển thời điểm một giá trị bị hủy, mà là hợp đồng tĩnh biểu diễn quan hệ về thời hạn hiệu lực giữa các tham chiếu. Chú thích vòng đời không làm tham chiếu sống lâu hơn; nó chỉ mô tả các quan hệ, chẳng hạn giữa tham chiếu hàm nhận vào và trả về, để trình biên dịch có thể kiểm tra.6

Bộ kiểm tra mượn hiện tại sử dụng vòng đời phi từ vựng (NLL), xét lần sử dụng cuối cùng của tham chiếu thay vì chỉ xét cuối khối lệnh. Dù vậy, phân tích tĩnh không thể quyết định hoàn toàn ý nghĩa của mọi chương trình kết thúc nên buộc phải bảo thủ, và sẽ từ chối một số chương trình thực tế an toàn khi chạy. Một lý do dự án Rust đặt mục tiêu ổn định Polonius alpha trong năm 2026 là để chấp nhận nhiều mẫu hợp lệ hơn mà phân tích hiện tại chưa biểu diễn được, gồm mượn có điều kiện và lending iterator.7

4. Tiền đề và ranh giới của các bảo đảm Safe Rust

Bảo đảm cốt lõi của Safe Rust là tính soundness: chỉ mã an toàn thì không thể tự gây ra hành vi không xác định. Tuy nhiên, bảo đảm này dựa trên tiền đề rằng trình biên dịch, thư viện chuẩn và thư viện bên thứ ba, bộ cấp phát, các trừu tượng triển khai bằng unsafe, giao diện hệ điều hành và mã FFI đều tuân thủ hợp đồng tương ứng. unsafe không phải dấu hiệu cho phép hành vi không xác định; nó cho biết người triển khai phải tự xác minh các nghĩa vụ mà trình biên dịch không kiểm tra được.3

Vì vậy, sở hữu và mượn ngăn chặn các nhóm quan trọng gồm tham chiếu treo, biệt danh không hợp lệ, giải phóng hai lần và tranh chấp dữ liệu, nhưng không loại bỏ tình trạng hết bộ nhớ, cạn kiệt tài nguyên, panic, abort, lỗi logic, bế tắc, vi phạm hợp đồng của mã bên ngoài hay lỗi trình biên dịch. Nếu mã C ở ranh giới FFI gây ra hành vi không xác định, ảnh hưởng có thể lan sang toàn bộ chương trình, gồm cả phần Rust.

5. Các mẫu sở hữu ngoài quy tắc cơ bản và chi phí của chúng

Cấu trúc dữ liệu thực tế có thể khó biểu diễn chỉ bằng quyền sở hữu đơn nhất và mượn tĩnh. Vì vậy, Rust cung cấp các kiểu thay đổi thời điểm kiểm tra hoặc cơ chế đồng bộ trong khi vẫn duy trì một trừu tượng an toàn.8

  • Rc<T> biểu diễn nhiều chủ sở hữu trong một luồng, nhưng cần cấp phát heap và tăng giảm bộ đếm tham chiếu; chu trình tham chiếu mạnh có thể gây rò rỉ bộ nhớ.
  • RefCell<T> cung cấp tính khả biến nội tại và kiểm tra quy tắc mượn khi chạy thay vì lúc biên dịch. Vi phạm quy tắc gây panic thay cho hành vi không xác định, nhưng thêm chi phí theo dõi trạng thái và phân nhánh.
  • Arc<T> dùng bộ đếm tham chiếu nguyên tử để chia sẻ giữa các luồng. Chi phí của các phép toán nguyên tử này có thể khiến nó bất lợi hơn Rc<T> khi không cần an toàn luồng.
  • Mutex<T> chỉ cho phép mã đã lấy khóa truy cập khả biến vào giá trị bên trong. Kiểu và RAII cấu trúc hóa việc nhả khóa, nhưng chi phí lấy khóa, tranh chấp khóa và khả năng bế tắc vẫn còn.

Các kiểu này không loại bỏ quy tắc sở hữu. Chúng đóng gói sau API an toàn những mẫu khó biểu diễn bằng kiểm tra tĩnh, đồng thời lựa chọn kiểm tra runtime, cấp phát heap, đếm tham chiếu, phép toán nguyên tử và khóa làm chi phí, cùng các điều kiện thất bại mới.

Kết luận tạm thời

Xét ranh giới của bảo đảm an toàn bộ nhớ, sở hữu, mượn và vòng đời ngăn chặn mạnh một số tham chiếu treo, giải phóng hai lần, sử dụng sau giải phóng, biệt danh không hợp lệ và tranh chấp dữ liệu trong ranh giới Safe Rust sound. Tuy nhiên, bảo đảm phụ thuộc vào hợp đồng của phần triển khai unsafe và các ranh giới bên ngoài, không bao quát mọi lỗi hay sự cố vận hành.

Xét ưu điểm và chi phí thiết kế, mô hình này cung cấp bảo đảm tĩnh mạnh mà không cần bộ thu gom rác khi chạy, nhưng yêu cầu biểu lộ quan hệ sở hữu qua kiểu và giao diện, đồng thời có thể từ chối một số chương trình hợp lệ. Khi chọn sở hữu dùng chung hoặc tính khả biến nội tại, chi phí tĩnh không biến mất mà chuyển thành đếm tham chiếu, kiểm tra runtime, phép toán nguyên tử và khóa. Vì vậy, mô hình quản lý bộ nhớ của Rust nên được hiểu không phải là “an toàn không chi phí”, mà là một thiết kế chặn tĩnh một số lỗi cụ thể và, khi cần, làm rõ các chi phí thay thế thông qua kiểu.

1.3 Dòng phát triển của trừu tượng hóa không chi phí

Trừu tượng hóa không chi phí không phải là một mệnh đề thực tế cho rằng mọi chi phí trong chương trình đều bằng không, mà là nguyên tắc thiết kế ngôn ngữ và thư viện. Nguyên tắc này có nghĩa là chức năng không sử dụng không nên tạo chi phí thời gian hay không gian, còn trừu tượng được sử dụng phải được thiết kế để có thể cạnh tranh với cách triển khai cấp thấp hợp lý viết thủ công. Nguyên tắc được diễn đạt có hệ thống trong zero-overhead principle của C++, và Rust tiếp nhận nó như một trục thiết kế để đồng thời theo đuổi an toàn bộ nhớ và quyền kiểm soát cấp thấp.9

Những tính năng như struct, macro, inlinesizeof của C đã tác động đến lịch sử này bằng cách tham gia vào giai đoạn biên dịch hoặc cung cấp quyền kiểm soát cấp thấp. Tuy nhiên, gọi mọi kỹ thuật lúc biên dịch là dạng sơ khai của trừu tượng hóa không chi phí sẽ làm phạm vi khái niệm trở nên quá rộng. Mục này phân biệt kỹ thuật triển khai cấp thấp, nguyên tắc trừu tượng hóa ở cấp ngôn ngữkết quả quan sát do một trình biên dịch cụ thể tạo ra.

1. Điều phối tĩnh và đơn hình hóa

Các hàm generic được sử dụng và trait được điều phối tĩnh sẽ được đơn hình hóa (monomorphization) cho từng kiểu cụ thể. Cách này xác định đích gọi ở thời điểm biên dịch, tạo cơ hội cho gọi trực tiếp, nội tuyến và các tối ưu liên quan. Vì bộ tối ưu có thể đồng thời nhìn thấy kiểu cụ thể và phép toán, ranh giới trừu tượng đôi khi có thể biến mất khỏi mã máy cuối cùng.9

Tuy nhiên, đơn hình hóa không bảo đảm rằng “luôn tạo cùng mã máy” hay “luôn nhanh hơn mã viết thủ công”. Kết quả sinh mã có thể thay đổi theo phiên bản rustc và LLVM, mức tối ưu, ranh giới crate, LTO, đơn vị sinh mã, CPU đích và các tính năng được bật, cùng mã xung quanh. Vì vậy, cùng một mã nguồn có thể cho kết quả tối ưu rất khác giữa bản dựng phát triển và bản dựng phát hành.10

2. Điều phối động, cấp phát và kiểm tra runtime

Không phải mọi trừu tượng của Rust đều bị loại bỏ tĩnh. dyn Trait sử dụng một con trỏ dữ liệu và bảng phương thức ảo (vtable) để chọn đích gọi khi chạy. Điều này có chi phí gọi gián tiếp và thường làm giảm cơ hội nội tuyến, nhưng có thể giảm kích thước mã do không phải sao chép mã cho từng kiểu cụ thể.11

Điều phối động và cấp phát heap cũng không phải cùng một khái niệm. &dyn Trait có thể mượn một giá trị có sẵn nên bản thân nó không yêu cầu cấp phát heap, trong khi Box<dyn Trait> chọn biểu diễn sở hữu trên heap dựa trên Box. Việc cấp phát và cấp phát lại của VecString, cùng quyền sở hữu heap của Box, là hành vi của cấu trúc dữ liệu đã chọn và không biến mất chỉ vì được gọi là “trừu tượng”. Việc đánh chỉ mục an toàn cho mảng và slice cũng có ngữ nghĩa gây panic khi vượt phạm vi; kiểm tra biên có bị loại bỏ hay không là kết quả tối ưu, không phải bảo đảm phổ quát của ngôn ngữ.11

3. Những chi phí có thể phát sinh khi giảm chi phí runtime

Do đơn hình hóa sinh mã máy cho từng kiểu cụ thể, nó có thể có lợi cho hiệu năng thực thi và nội tuyến, nhưng cũng có thể tăng thời gian biên dịch và kích thước tệp nhị phân. Mã lớn hơn có thể làm tăng áp lực lên bộ nhớ đệm lệnh, dù ảnh hưởng thực tế phụ thuộc tần suất gọi, bố trí mã, bộ xử lý đích và khối lượng công việc. Ngược lại, điều phối động giữ lại lời gọi gián tiếp nhưng có thể giảm trùng lặp mã.10

Thiết lập bản dựng cũng có các đánh đổi. Mức tối ưu cao và LTO có thể tạo thêm cơ hội tối ưu nhưng làm tăng thời gian biên dịch và liên kết; mã đã tối ưu có thể khó gỡ lỗi hơn vì thứ tự nguồn và trạng thái thực thi bị sắp xếp lại. Tăng số đơn vị sinh mã có thể làm biên dịch song song nhanh hơn nhưng làm giảm hiệu năng mã sinh ra. Khả năng bảo trì cũng phải đánh giá đồng thời phần trùng lặp mã được trừu tượng loại bỏ và độ phức tạp của API generic, chẩn đoán lỗi và truy vết bản dựng. Vì vậy, thời gian biên dịch, kích thước tệp nhị phân, bộ nhớ đệm lệnh, gỡ lỗi và chi phí bảo trì là các tiêu chí riêng biệt với thông lượng runtime.10

4. Phạm vi bảo đảm của ví dụ iterator

// Tính tổng bình phương của các bội số của 3 từ 1 đến 99
let sum = (1..100).filter(|&x| x % 3 == 0).map(|x| x * x).sum::<u32>();

Đoạn mã kết hợp filter, mapsum để biểu diễn phép tính theo lối khai báo. Trong bản dựng tối ưu, các lời gọi adapter có thể được nội tuyến và trạng thái trung gian bị loại bỏ, tạo mã gần giống một vòng lặp duy nhất. Tuy nhiên, riêng ví dụ này không thể chứng minh mọi chuỗi iterator đều có cùng hiệu năng hoặc mã máy với vòng lặp viết thủ công. So sánh trong sách Rust chính thức cũng chỉ quan sát rằng vòng lặp và iterator cho kết quả tương tự trong một khối lượng công việc tìm kiếm, chứ không phải bằng chứng tương đương toàn diện trên nhiều đầu vào và điều kiện.12

5. Điều kiện để so sánh các tuyên bố về hiệu năng

Một so sánh hiệu năng về trừu tượng hóa không chi phí ít nhất phải nêu rõ các điều kiện sau.

  • phiên bản của rustc, Cargo và các crate chính;
  • target triple, CPU, các tính năng tập lệnh được bật và hệ điều hành;
  • profile phát triển, phát hành hoặc tùy chỉnh, gồm mức tối ưu, LTO, đơn vị sinh mã và chiến lược panic;
  • dữ liệu đầu vào, khối lượng công việc, số lần lặp, quá trình làm nóng và phương pháp đo;
  • thuật toán, cấp phát và điều kiện I/O của chuẩn so sánh như vòng lặp hoặc một cách triển khai khác; và
  • thời gian biên dịch, kích thước tệp nhị phân và mức dùng bộ nhớ, bên cạnh độ trễ và thông lượng.

Khi các điều kiện này khác nhau, cùng một trừu tượng cú pháp có thể tạo kết quả khác nhau. Vì vậy, không được khái quát ưu thế quan sát trong một benchmark thành thuộc tính cố định của toàn bộ ngôn ngữ hay mọi trừu tượng.

Kết luận tạm thời

Xét ưu điểm và chi phí thiết kế, điều phối tĩnh và đơn hình hóa là những cơ chế mạnh để hạ giao diện cấp cao xuống mã cụ thể có thể gọi trực tiếp và tối ưu. Tuy nhiên, nguyên tắc trừu tượng hóa không chi phí không phải bảo đảm ở cấp đặc tả rằng mọi trừu tượng tạo cùng mã máy hay hiệu năng. Điều phối động, cấp phát heap, kiểm tra biên và hành vi runtime của thư viện vẫn tồn tại tùy theo biểu diễn và cấu trúc dữ liệu được chọn.

Rust nên được hiểu là một thiết kế cho phép chọn trả loại chi phí nào và ở đâu, thay vì loại bỏ chi phí. Tránh lời gọi gián tiếp khi chạy có thể làm phát sinh chi phí thời gian biên dịch và kích thước mã do đơn hình hóa; giảm trùng lặp mã có thể đồng nghĩa với việc chọn chi phí điều phối động. Vì vậy, trừu tượng hóa không chi phí phải được đánh giá bằng khối lượng công việc cụ thể, điều kiện bản dựng, mã sinh ra và tổng chi phí vòng đời, chứ không phải bằng khẩu hiệu.

1.4 Bảo đảm an toàn thông qua hệ thống kiểu và đối sánh mẫu

Hệ thống kiểu tĩnh của Rust giới hạn cách biểu diễn giá trị và những phép toán được phép thực hiện trên chúng. Khi các trạng thái có thể có của dữ liệu được biểu diễn trong kiểu, những phép toán không phù hợp với kiểu đó có thể bị từ chối ngay khi biên dịch. Tuy nhiên, bộ kiểm tra kiểu chỉ bảo đảm những điều kiện đã được biểu diễn trong kiểu. Điều đó không có nghĩa là các quy tắc nghiệp vụ, môi trường bên ngoài và mọi kết quả thực thi đều tự động đúng.

1. OptionResult: phạm vi của việc biểu diễn trạng thái tường minh

Kiểu liệt kê của Rust là kiểu tổng (sum type), trong đó mỗi biến thể có thể mang dữ liệu khác nhau. Option<T> biểu diễn sự hiện diện hoặc vắng mặt của một giá trị bằng Some(T)None, còn Result<T, E> biểu diễn thành công và thất bại bằng Ok(T)Err(E). Khi API dùng các kiểu này, bên gọi có thể nhận biết ngay từ kiểu rằng giá trị có thể vắng mặt hoặc phép toán có thể thất bại, rồi truyền tiếp hoặc rẽ nhánh để xử lý.13

Không nên mở rộng ưu điểm này thành mệnh đề phổ quát rằng “Rust không có null hay ngoại lệ.” Các tham chiếu an toàn &T&mut T, cũng như Box<T>, đều giả định một con trỏ khác null trỏ tới giá trị hợp lệ, nhưng con trỏ thô có thể là null; FFI và giao diện hệ điều hành cũng có thể truyền con trỏ null, mã lỗi hoặc ngoại lệ từ mã bên ngoài. Option không tự động xác thực dữ liệu đi qua những ranh giới đó; nó chỉ là cách biểu diễn trong hệ thống kiểu Rust một khả năng vắng mặt đã được kiểm chứng.13

Result được đánh dấu #[must_use], nên việc bỏ qua giá trị thường phát sinh cảnh báo; tuy nhiên, mặc định đây chỉ là một lint. Có thể hạ mức lint hoặc chủ động bỏ giá trị bằng let _ =, nên trình biên dịch không cưỡng chế một chính sách phục hồi có ý nghĩa cho mọi lỗi. Toán tử ? thường cũng chỉ truyền lỗi lên hàm gọi, chứ không xử lý lỗi. Việc ghi log, thử lại, dùng giá trị thay thế hay chấm dứt vẫn là quyết định thiết kế của API và ứng dụng.13

2. Đối sánh mẫu và kiểm tra tính đầy đủ bảo đảm điều gì

match kiểm tra liệu các nhánh của nó, xét tổng thể, có bao phủ mọi giá trị hiện có thể được tạo ra của kiểu đích hay không. Xóa nhánh None khỏi mã sau sẽ làm biên dịch thất bại.

fn describe(value: Option<i32>) -> &'static str {
    match value {
        Some(number) if number > 0 => "số dương",
        Some(_) => "0 hoặc số âm",
        None => "không có giá trị",
    }
}

Bảo đảm này cũng có ranh giới.14

  • Nhánh ký tự đại diện (wildcard) _ bao phủ mọi giá trị còn lại nên vượt qua kiểm tra tính đầy đủ, nhưng không cho biết biến thể nào đã được xử lý có chủ ý. Một biến thể API mới có thể bị nhánh wildcard hiện có hấp thụ mà không phát sinh cảnh báo.
  • Điều kiện kèm theo mẫu (pattern guard) có thể cho giá trị false, nên không chứng minh rằng mọi giá trị khớp mẫu đều được xử lý. Đó là lý do ví dụ vẫn cần một nhánh Some khác sau Some(number) if number > 0.
  • if let, let ... else, while letmatches! là các công cụ chỉ tập trung vào một số mẫu quan tâm, không yêu cầu xử lý mọi trường hợp.
  • Kiểu liệt kê #[non_exhaustive] từ crate khác yêu cầu một nhánh wildcard để chừa khả năng bổ sung biến thể trong tương lai. Điều này giúp API tiến hóa, nhưng làm giảm khả năng của bên gọi trong việc liệt kê mọi biến thể hiện tại và biến sự xuất hiện của trạng thái mới thành lỗi biên dịch.

Vì vậy, kiểm tra tính đầy đủ bảo đảm rằng “không có trường hợp bị bỏ sót theo định nghĩa kiểu hiện tại và các mẫu đã viết.” Nó không chứng minh hành vi của từng nhánh là đúng, nhánh wildcard xử lý trạng thái mới phù hợp, hay trạng thái bên ngoài khớp với định nghĩa kiểu.

3. Trạng thái không hợp lệ chỉ bị chặn khi bất biến được biểu diễn trong kiểu

Kiểu liệt kê, newtype, các trường không công khai và hàm tạo có kiểm tra có thể làm cho một số trạng thái không hợp lệ khó biểu diễn. Chẳng hạn, một mã định danh đã được kiểm tra phạm vi hoặc một bước chuyển trạng thái có thể được mô hình hóa thành kiểu riêng, để mã dùng API công khai an toàn không thể bỏ qua bước xác thực.

Nhưng các quan hệ như thời điểm bắt đầu phải trước thời điểm kết thúc, tính nhất quán giữa nhiều trường, sự tồn tại thực của tệp, chính sách phân quyền hay độ tin cậy của phản hồi mạng không tự nhiên xuất hiện chỉ nhờ tên kiểu. Các điều kiện đó phải được triển khai thành bất biến của hàm tạo và phương thức, đồng thời phải kiểm soát khả năng truy cập trường và các đường dẫn chuyển đổi. Một giá trị có thể đúng kiểu về mặt cấu trúc nhưng vẫn sai về ý nghĩa nghiệp vụ.

Ranh giới này đặc biệt quan trọng tại unsafe, FFI, giải tuần tự hóa và đầu vào bên ngoài. Việc coi một enum có giá trị phân biệt (discriminant) không hợp lệ, hoặc một tham chiếu không hợp lệ, là giá trị Rust có thể dẫn đến hành vi không xác định. Dữ liệu byte từ bên ngoài, cấu trúc C, hàng cơ sở dữ liệu và thông điệp mạng phải được kiểm tra độ dài, phạm vi, mã hóa, discriminant và quan hệ giữa các trường trước khi được coi là giá trị Rust. Bảo đảm của hệ thống kiểu chỉ bắt đầu sau khi một giá trị hợp lệ của kiểu đã được tạo; chúng không thay thế trách nhiệm xác lập tiền đề đó tại ranh giới.15

4. Thất bại khi chạy và chi phí luồng điều khiển

Việc OptionResult biểu diễn thất bại dưới dạng giá trị không làm thất bại khi chạy biến mất. unwrapexpect sẽ panic khi gặp biến thể không như mong đợi; tùy chiến lược panic của bản dựng, chương trình có thể tháo cuộn ngăn xếp (stack unwinding) hoặc chấm dứt tiến trình. unwrap_unchecked bỏ phép kiểm tra, nhưng gây hành vi không xác định nếu dùng trên biến thể sai.16

Mã rẽ nhánh theo trạng thái tạo ra luồng điều khiển thực. Trình biên dịch có thể hạ một match đơn giản thành nhánh điều kiện, bảng nhảy, phép di chuyển có điều kiện hoặc mã không nhánh, nhưng kết quả cụ thể phụ thuộc vào số biến thể, bố trí dữ liệu, mức tối ưu, CPU đích và mã xung quanh. Không có bảo đảm rằng đối sánh mẫu hay các combinator tự thân là không chi phí. Trên các đường thực thi nóng (hot path), cần đo chi phí dự đoán nhánh và tạo giá trị lỗi; việc đặt trực tiếp một biến thể lỗi lớn trong enum hay gián tiếp qua Box cũng là lựa chọn giữa kích thước biểu diễn và chi phí cấp phát.

5. Biểu diễn, tiến hóa API và chi phí bảo trì

Đối với enum dùng repr(Rust) mặc định, thứ tự chính xác của các trường, vị trí discriminant và tổng kích thước thường không phải là ABI ổn định. Một số kiểu cụ thể mà tài liệu chính thức bảo đảm tối ưu hóa con trỏ null, như Option<&T>, là ngoại lệ; không thể khái quát việc tối ưu kích thước của một trường hợp cho mọi Option<T>, Result<T, E> hay enum do người dùng định nghĩa. Việc dựa vào bố trí trong FFI hoặc định dạng lưu trữ đòi hỏi một repr phù hợp và thiết kế tương thích riêng.16

Chia nhỏ trạng thái thành các kiểu chi tiết có thể biến trường hợp bỏ sót thành lỗi biên dịch và làm rõ mục tiêu rà soát mã cũng như kiểm thử. Ngược lại, khi số biến thể và kiểu lỗi tăng, số nhánh match, mã chuyển đổi, tài liệu và kiểm thử cũng tăng; các hệ phân cấp lỗi tổng quát (generic) và chuỗi combinator dài có thể làm đường gỡ lỗi phức tạp hơn. Thêm biến thể vào enum công khai có thể phá vỡ các phép đối sánh đầy đủ trong mã phía phụ thuộc; #[non_exhaustive] và nhánh wildcard tăng khả năng tương thích nhưng làm giảm khả năng tự động phát hiện trạng thái mới. Độ chính xác của kiểu, độ ổn định API, độ rõ ràng của thông báo chẩn đoán và chi phí bảo trì phải được thiết kế cùng nhau.

Kết luận tạm thời

Khi mở rộng góc nhìn ra ngoài ranh giới an toàn bộ nhớ, Option, Result và đối sánh mẫu đầy đủ có thể ngăn những trường hợp bỏ sót quan trọng ngay khi biên dịch, miễn là sự vắng mặt, thất bại và các nhánh trạng thái đã được biểu diễn bằng kiểu. Tuy nhiên, chúng không loại bỏ khả năng null của con trỏ thô và dữ liệu đi qua FFI, panic, lỗi bị bỏ qua, biến thể mới bị nhánh wildcard hấp thụ, quy tắc nghiệp vụ sai hay đầu vào bên ngoài không hợp lệ. Phạm vi các trạng thái không hợp lệ bị chặn phụ thuộc vào mức độ chính xác mà bất biến được biểu diễn trong kiểu và API an toàn, cũng như việc chúng có được duy trì tại mọi ranh giới hay không.

Xét ưu điểm và chi phí thiết kế, việc chia nhỏ trạng thái thành các kiểu là cơ chế mạnh để chuyển thất bại ngầm khi chạy sang giao diện tường minh và chẩn đoán của trình biên dịch. Đổi lại, nó có thể tạo chi phí về thiết kế API, rẽ nhánh và kích thước biểu diễn, chuyển đổi lỗi, tương thích, gỡ lỗi và bảo trì. Vì vậy, giá trị của hệ thống kiểu và đối sánh mẫu không nằm ở việc “loại bỏ mọi lỗi,” mà ở việc làm rõ trạng thái lỗi nào được biểu diễn và được xác thực tại ranh giới nào.

1.5 Hệ sinh thái: Cargo và Crates.io

Trải nghiệm sử dụng một ngôn ngữ lập trình không chỉ do cú pháp và hệ thống kiểu quyết định. Các công cụ và hệ sinh thái dùng để tạo dự án, chọn phụ thuộc, xây dựng, kiểm thử, triển khai và cập nhật trong thời gian dài cũng ảnh hưởng đến chi phí phát triển và khả năng xảy ra lỗi. Trong Rust, Cargo là trình quản lý gói kiêm công cụ xây dựng chính thức, còn crates.io là registry gói công khai mặc định. Phần này phân tích hai thành phần đó như một lớp công cụ và hệ sinh thái tách biệt với các bảo đảm an toàn ở cấp ngôn ngữ.

1. Quy trình làm việc được Cargo chuẩn hóa và phạm vi của nó

Cargo dùng Cargo.toml để khai báo metadata của gói và các phụ thuộc, đồng thời cung cấp những điểm vào chung như cargo new, cargo build, cargo check, cargo test, cargo doc, cargo packagecargo publish. Thay vì kết hợp các lệnh gọi rustc trực tiếp với lệnh shell riêng của từng dự án, một công cụ điều phối việc tải phụ thuộc, thứ tự biên dịch, cấu trúc thư mục quy ước và các build profile. Điều này có thể giảm khác biệt giữa các môi trường phát triển và giúp hình thành những thực hành chung về tự động hóa, CI và tài liệu hóa dễ dàng hơn.17

Tuy nhiên, một quy trình làm việc chung, các thuộc tính của chương trình được ngôn ngữ bảo đảm, và một bản dựng có thể tái lập tạo ra cùng sản phẩm trong mọi môi trường là những khái niệm khác nhau. Ngay cả khi Cargo chọn cùng phiên bản phụ thuộc, kết quả cuối cùng vẫn có thể chịu ảnh hưởng từ phiên bản rustc và Cargo, target triple, build profile và cờ biên dịch, biến môi trường, build script, procedural macro, thư viện native và công cụ bên ngoài. Vì vậy, chỉ riêng việc có một lệnh chung cargo build không thể bảo đảm an toàn bộ nhớ, tính đúng đắn chức năng hay khả năng tái lập ở mức từng bit.

2. Phân giải phụ thuộc, Cargo.lock, hợp nhất feature, SemVer và MSRV

Resolver của Cargo tính đồ thị phụ thuộc thỏa mãn các yêu cầu phiên bản mà từng gói khai báo và, khi dùng tệp khóa, ghi kết quả vào Cargo.lock. Khi tệp khóa tồn tại, Cargo ưu tiên các phiên bản đã ghi trong đó, nhờ vậy việc chọn phụ thuộc ổn định hơn. --locked biến trường hợp cần sửa tệp khóa thành lỗi, còn --frozen kết hợp điều đó với chế độ ngoại tuyến. Tuy nhiên, --offline chỉ có thể dùng các gói đã có sẵn cục bộ, nên kết quả phân giải phụ thuộc có thể khác với khi trực tuyến. Nói cách khác, tệp khóa cải thiện đáng kể tính xác định của việc chọn phụ thuộc, nhưng không cố định trạng thái mạng và cache hay toàn bộ môi trường xây dựng.18

Hiệu lực của tệp khóa cũng phụ thuộc vào vai trò của gói. Với ứng dụng cuối, nó hữu ích để cố định một tập phụ thuộc đã được kiểm thử. Nhưng khi một thư viện được dự án khác sử dụng, việc phân giải phụ thuộc được thực hiện lại dựa trên Cargo.toml của bên sử dụng và toàn bộ đồ thị. FAQ chính thức của Cargo cũng lưu ý rằng Cargo.lock của một thư viện không kiểm soát việc chọn phụ thuộc của các dự án sử dụng thư viện đó.18

Resolver tái sử dụng cùng một phiên bản gói khi có thể, nhưng nếu các yêu cầu phiên bản xung đột thì nhiều phiên bản của cùng một crate có thể cùng tồn tại trong một đồ thị. Điều này có thể làm tăng biên dịch trùng lặp và kích thước mã, đồng thời các kiểu cùng tên nhưng được định nghĩa ở những phiên bản khác nhau có thể không tương thích tại ranh giới nhận dạng kiểu lúc chạy hoặc API công khai. Có thể dùng cargo tree -d để tìm các phiên bản trùng như vậy.18

Feature cũng không chỉ là các công tắc độc lập. Khi nhiều gói dùng chung một phụ thuộc, nguyên tắc mặc định là dùng hợp của tất cả feature đã được kích hoạt. Từ resolver version 2, Cargo giảm việc hợp nhất feature không cần thiết trong một số trường hợp liên quan đến phụ thuộc theo target, build dependency và procedural macro, cũng như development dependency. Vì vậy, những workspace member nào được xây dựng cùng nhau, target nào và feature nào được chọn có thể làm thay đổi đồ thị biên dịch thực tế và chi phí của nó.18

Cargo chọn phiên bản dựa trên giả định tương thích SemVer, nhưng chính hướng dẫn tương thích chính thức cũng nói rõ rằng đây không phải quy tắc bắt buộc mọi dự án phải tuân theo. Một thay đổi tương thích về mặt cú pháp vẫn có thể ảnh hưởng đến hành vi khi chạy. rust-version có thể biểu diễn phiên bản Rust tối thiểu được hỗ trợ (MSRV) của một gói và cho phép resolver cân nhắc thông tin này khi chọn phiên bản, nhưng đây là metadata tùy chọn và có thể bị bỏ qua bằng --ignore-rust-version. Vì vậy, SemVer và MSRV là các hợp đồng và công cụ để quản lý rủi ro cập nhật, không phải bằng chứng rằng phiên bản mới luôn tương thích hoặc không có hồi quy.18

3. Mã được thực thi trong quá trình xây dựng và các phụ thuộc native, phụ thuộc theo target

Phụ thuộc Cargo không nhất thiết chỉ dừng ở việc chuyển tệp nguồn Rust cho rustc. build.rs của một gói được chạy ngay trước khi gói đó được xây dựng và có thể biên dịch thư viện C, tìm thư viện hệ thống, sinh mã nguồn hoặc thực hiện cấu hình theo nền tảng. Tài liệu Cargo giải thích rằng build script có thể thực hiện công việc tùy ý trong lúc chạy.19

Procedural macro cũng được thực thi như mã thật tại thời điểm biên dịch. Theo Rust Reference, procedural macro có thể dùng các tài nguyên mà trình biên dịch có, bao gồm quyền truy cập tệp, và có những vấn đề bảo mật cùng loại với build script của Cargo. Vì vậy, build script và procedural macro từ phụ thuộc không đáng tin cậy phải được xem là ranh giới thực thi mã tại thời điểm xây dựng. Bảo đảm an toàn bộ nhớ của mã ứng dụng viết bằng cú pháp Safe Rust và vấn đề tin cậy mã bên thứ ba được thực thi trong quá trình xây dựng không nằm ở cùng một lớp.19

Phụ thuộc native cũng tạo ra những tiền đề môi trường riêng. Build script có thể dùng metadata links và chỉ thị linker để liên kết với thư viện C/C++, còn phụ thuộc theo target có thể thay đổi tùy hệ điều hành và kiến trúc. Khi cross-compile, build dependency chạy trên host trong khi crate cuối có thể được biên dịch cho một target khác. Vì vậy, ngay cả khi dùng cùng Cargo.lock, khác biệt về công cụ trên host, linker, thư viện hệ thống hay target SDK vẫn có thể làm thay đổi kết quả xây dựng hoặc khiến quá trình xây dựng thành công hay thất bại.19

Do đó, nếu cần lưu giữ lâu dài hoặc bản dựng có mức bảo đảm cao, ngoài tệp khóa còn phải ghi lại và kiểm soát phiên bản toolchain, target, profile và cờ, công cụ và thư viện native, các biến môi trường cần thiết, cũng như điều kiện thực thi mã trong quá trình xây dựng.

4. Các chức năng về tính toàn vẹn và phân phối của crates.io, cùng ranh giới của bảo đảm chuỗi cung ứng

crates.io là registry công khai mặc định của Cargo, cung cấp một đường chung để tìm kiếm và phân phối gói. Chỉ mục registry ghi checksum SHA-256 của mỗi tệp .crate đã xuất bản, và Cargo kiểm tra dữ liệu tải xuống có khớp checksum đó hay không. Đây là cơ chế quan trọng về tính toàn vẹn, giúp xác nhận rằng các byte của gói đã chọn sau khi truyền hoặc lấy từ cache khớp với metadata của registry.20

Cách quản lý các phiên bản đã xuất bản cũng tính đến tính ổn định. crates.io hướng tới việc lưu giữ vĩnh viễn các phiên bản đã xuất bản; phiên bản có vấn đề có thể bị yank thay vì bị xóa. Phiên bản đã yank thường không được chọn trong lần phân giải phụ thuộc mới, nhưng vẫn có thể tiếp tục được dùng nếu đã được ghi trong Cargo.lock hiện có. Chủ sở hữu có thể quản lý quyền xuất bản phiên bản mới và yank phiên bản cũ; metadata khi xuất bản cũng yêu cầu biểu thức giấy phép hoặc tệp giấy phép, và các giấy phép chuẩn có thể được ghi bằng biểu thức SPDX.20

Không nên mở rộng những chức năng này thành bảo đảm an ninh cho toàn bộ chuỗi cung ứng. Checksum xác minh tính đồng nhất của các byte gói đã được registry ghi nhận; nó không chứng minh rằng mã được thiết kế an toàn, không chỉ ra mã tương ứng với commit cụ thể nào trong kho mã nguồn công khai hoặc đã trải qua quy trình rà soát nào, và cũng không chứng minh người bảo trì sẽ duy trì gói lâu dài. Việc có metadata giấy phép cũng không có nghĩa giấy phép của toàn bộ đồ thị phụ thuộc bắc cầu phù hợp với chính sách dự án và yêu cầu pháp lý. Yank cũng không tự động loại bỏ hay sửa chữa một phiên bản đã có trong tệp khóa.

Vì vậy, khả năng truy cập và đường phân phối tập trung của crates.io, checksum gói, quyền sở hữu và chức năng yank đều hữu ích, nhưng khả năng tìm thấy, tính toàn vẹn khi phân phối và quản lý quyền là các tiêu chí khác với xác minh nguồn gốc mã, bảo mật, chất lượng bảo trì và hỗ trợ dài hạn.

5. Chi phí vòng đời của mạng, cache, vendoring, kiểm toán và cập nhật

Cargo tải các phụ thuộc từ registry và Git rồi cache chúng ở những vị trí như $CARGO_HOME. Cache giảm chi phí mạng và xử lý cho các lần xây dựng lặp lại, nhưng trong môi trường mới hoặc khi cache trống vẫn phải truy cập mạng và tải lại. Có thể dùng cargo fetch để lấy trước các phụ thuộc rồi dùng --offline hoặc --frozen; cargo vendor có thể sao chép mã nguồn của phụ thuộc crates.io và Git vào thư mục cục bộ do dự án quản lý. Tuy nhiên, vendoring không làm biến mất phụ thuộc bên ngoài mà là lựa chọn chuyển trách nhiệm lưu giữ, đồng bộ và cập nhật vào bên trong dự án.21

Khi đồ thị phụ thuộc lớn hơn, lượng dữ liệu cần tải và dung lượng cache, khối lượng biên dịch, các phiên bản trùng và feature được bật, phạm vi thực thi của build script và procedural macro, cũng như số giấy phép, lỗ hổng và trạng thái bảo trì cần xem xét đều có thể tăng. Tài liệu Cargo cũng khuyến nghị cân nhắc thời gian biên dịch, giấy phép và ảnh hưởng đến bảo trì khi thêm build dependency. Đặc biệt trong cross-build khi host và target khác nhau, cùng một phụ thuộc có thể được biên dịch lại cho các vai trò khác nhau.19

cargo update chủ động cập nhật các phiên bản được chọn trong tệp khóa. Vì vậy, cập nhật không đơn thuần là lấy một số phiên bản mới hơn mà là công việc bảo trì cần xem xét đồng thời nhật ký thay đổi, kiểm thử, giả định SemVer, MSRV, cảnh báo bảo mật và khả năng quay lui. cargo audit của RustSec đối chiếu Cargo.lock với cơ sở dữ liệu các cảnh báo bảo mật đã biết, nhưng không chứng minh rằng không tồn tại lỗ hổng chưa được báo cáo hoặc lỗi thiết kế. Tự động hóa kiểm toán là phương tiện hỗ trợ rà soát chuỗi cung ứng, không phải bảo đảm rằng review không còn cần thiết.21

Khi so sánh với hệ sinh thái C và C++, cũng cần áp dụng tiêu chí đối xứng. Nói rằng “C/C++ không có trình quản lý gói hoặc thực hành xây dựng được chuẩn hóa” là không chính xác. Có thể sử dụng các hệ thống xây dựng như CMake và Meson, các trình quản lý gói C/C++ như vcpkg và Conan, cũng như trình quản lý gói của hệ điều hành. Khác biệt không nằm ở việc có công cụ hay không, mà ở chỗ Rust đặt Cargo và crates.io vào trung tâm của quy trình chính thức và cung cấp một lộ trình mặc định thống nhất và rõ ràng từ tạo dự án, phân giải phụ thuộc, xây dựng, kiểm thử đến xuất bản. Ngược lại, sự đa dạng công cụ lớn hơn trong C/C++ có thể làm tăng chi phí tích hợp, nhưng cũng cung cấp lựa chọn phù hợp với hệ thống xây dựng hiện có, gói hệ thống, đóng gói nhị phân và chính sách repository riêng của tổ chức.21

Kết luận tạm thời

Cargo và crates.io là những lợi thế kỹ thuật quan trọng của Rust. Manifest và hệ thống lệnh chung, resolver phụ thuộc và tệp khóa, cùng registry mặc định có checksum giúp cấu hình dự án và việc chọn phụ thuộc trở nên rõ ràng hơn và dễ tự động hóa hơn. Đặc biệt, nếu quản lý Cargo.lock đã được xác minh cùng với các điều kiện xây dựng cố định, việc tái sử dụng cùng một tập phụ thuộc qua thời gian và giữa các môi trường phát triển sẽ dễ hơn.

Tuy nhiên, những lợi thế này không đồng nghĩa với bảo đảm an toàn ở cấp ngôn ngữ. Tệp khóa không cố định toàn bộ môi trường xây dựng hay độ tin cậy của mã bên thứ ba, checksum không đánh giá chất lượng mã, còn SemVer, MSRV, yank và cảnh báo bảo mật không thay dự án đưa ra quyết định bảo trì. Sự tiện lợi của việc kết hợp các phụ thuộc nhỏ cũng có thể đi kèm chi phí từ phụ thuộc bắc cầu, thực thi mã lúc build, mạng và cache, thời gian biên dịch, kiểm toán giấy phép và lỗ hổng, cập nhật và hỗ trợ dài hạn.

Vì vậy, trong môi trường quy mô lớn, vận hành lâu dài hoặc yêu cầu bảo đảm cao, không nên đánh giá chất lượng hệ thống công cụ chỉ dựa vào việc “dùng Cargo” hay “hệ sinh thái crates.io lớn”. Cần xem xét đồng thời đồ thị phụ thuộc bắc cầu thực tế và các feature được bật và target được chọn, build script và procedural macro, phụ thuộc native, chiến lược phục hồi ngoại tuyến và vendoring, cùng quy trình kiểm toán, cập nhật và rollback. Cargo cung cấp nền tảng mạnh để thực hiện công việc này một cách nhất quán, nhưng không loại bỏ trách nhiệm đối với chuỗi cung ứng và vòng đời.

1.6 Kết luận: Ranh giới bảo đảm và chi phí thiết kế

Câu hỏi thứ nhất của chương này là Rust đã cố gắng giảm những loại lỗi và chi phí nào trong lập trình hệ thống. Điểm cốt lõi từ phân tích ở trên là Safe Rust, thông qua các quy tắc sở hữu, mượn và kiểu, chặn mạnh ở thời điểm biên dịch những nhóm lỗi quan trọng như tham chiếu treo, use-after-free, giải phóng hai lần, aliasing không hợp lệ và data race; đồng thời Option, Result và pattern matching đầy đủ có thể chuyển sự vắng mặt, thất bại và phân nhánh trạng thái vào các kiểu và luồng điều khiển tường minh. Cargo và crates.io cũng đem lại lợi thế ở lớp công cụ khi tổ chức cấu hình dự án, phân giải phụ thuộc, xây dựng, kiểm thử và xuất bản thành một quy trình chung. Tuy nhiên, tính chất và bảo đảm của ba lớp này không giống nhau.

Câu hỏi thứ hai là các thiết kế này bảo đảm đến đâu và kéo theo những đánh đổi nào. Bảo đảm an toàn bộ nhớ của Safe Rust dựa trên tiền đề rằng trình biên dịch và thư viện, các abstraction được triển khai bằng unsafe, cùng các ranh giới FFI đều tuân thủ hợp đồng của mình; nó không bảo đảm loại bỏ panic, race condition nói chung, deadlock, rò rỉ hay cạn kiệt bộ nhớ và tài nguyên, hoặc lỗi logic, cũng không bảo đảm tính liên tục của dịch vụ. Việc biểu diễn trạng thái tường minh bằng kiểu cũng chỉ chặn được các nhóm lỗi tương ứng khi invariant thực sự được thể hiện trong kiểu và API an toàn, đồng thời các tiền đề đó được kiểm tra tại những ranh giới như đầu vào bên ngoài và FFI. Mô hình hóa trạng thái càng chi tiết cũng kéo theo chi phí về tiến hóa và tương thích API, chuyển đổi lỗi, gỡ lỗi và bảo trì. Vì vậy, không nên đồng nhất an toàn bộ nhớ hay bảo đảm ở cấp kiểu với tính đúng đắn, tính khả dụng hay độ tin cậy của toàn hệ thống.

Về hiệu năng, zero-cost abstraction cũng là một nguyên tắc thiết kế nhằm giảm overhead runtime có thể tránh được, chứ không phải bảo đảm tốc độ phổ quát. Static dispatch và monomorphization có thể giảm chi phí gọi lúc runtime và tạo thêm cơ hội tối ưu hóa, nhưng có thể làm tăng thời gian biên dịch, kích thước mã và chi phí gỡ lỗi; dynamic dispatch, cấp phát heap, kiểm tra biên và hành vi runtime của thư viện vẫn có thể tồn tại tùy theo cách biểu diễn được chọn. Vì vậy, ngoài throughput và latency, cần đánh giá đồng thời thời gian biên dịch, kích thước binary, mức dùng bộ nhớ, gỡ lỗi và chi phí bảo trì trong workload và điều kiện build thực tế.

Ranh giới tương tự cũng áp dụng cho công cụ và hệ sinh thái. Quy trình chung của Cargo, Cargo.lock, checksum và chức năng phân phối của crates.io giúp cấu trúc hóa việc chọn phụ thuộc và tự động hóa, nhưng không bảo đảm tính tái lập của toàn bộ môi trường build hay chất lượng, bảo mật và khả năng bảo trì dài hạn của mã bên thứ ba. Trong môi trường quy mô lớn và vận hành lâu dài, còn phải quản lý việc cố định và cập nhật toolchain, build script và procedural macro, phụ thuộc native, mạng và cache cùng phục hồi ngoại tuyến, kiểm toán chuỗi cung ứng, giấy phép và lỗ hổng, cập nhật và rollback, cũng như chi phí tích hợp và migration với mã và hệ thống build hiện có. Vì C và C++ cũng có các công cụ xây dựng và quản lý gói thực tế, trọng tâm so sánh không phải là có hay không có công cụ, mà là đánh đổi giữa mức độ tích hợp của lộ trình mặc định chung và phạm vi lựa chọn có thể phù hợp với tài sản hiện có.

Vì vậy, Rust có thể là một lựa chọn mạnh trong những môi trường khó hoặc không muốn dùng GC runtime, cần quyền kiểm soát cấp thấp và coi trọng việc chặn càng sớm càng tốt một số lỗi liên quan đến thời gian sống bộ nhớ, aliasing và trạng thái bị bỏ sót. Ngược lại, các đánh đổi sẽ khác khi thường xuyên phải dùng sở hữu chia sẻ, kiểm tra runtime và đồng bộ để xử lý những pattern hợp lệ bị các quy tắc tĩnh từ chối, hoặc khi thời gian biên dịch, kích thước mã, FFI, phụ thuộc native, công cụ hiện có và chi phí migration trở thành yếu tố chi phối. Điều này không có nghĩa các cách tiếp cận khác luôn tốt hơn, cũng không có nghĩa Rust luôn tốt hơn.

Kết luận của Chương 1 là giá trị cốt lõi của Rust không nằm nhiều ở việc loại bỏ chi phí, mà ở việc kiểm soát mạnh hơn một số loại lỗi ngay từ thời điểm biên dịch và thông qua các kiểu cùng interface tường minh, đồng thời chuyển vị trí của một phần chi phí và trách nhiệm. Chỉ khi phân biệt bảo đảm của ngôn ngữ, hành vi của implementation và runtime, sự tiện lợi của công cụ và hệ sinh thái, cùng kết quả quan sát được trong dự án thực tế, mới có thể đánh giá chính xác những lợi thế và chi phí này. Chương tiếp theo xem mức độ các lợi thế kỹ thuật có điều kiện và đặc tính công cụ này thực sự đóng góp vào quyết định áp dụng như một câu hỏi thực nghiệm và nhân quả riêng biệt.

2. Các yếu tố thúc đẩy việc áp dụng Rust: Tương tác giữa công nghệ, hệ sinh thái và câu chuyện

Cần phân biệt quan sát rằng một ngôn ngữ thực sự được sử dụng với lời giải thích nhân quả về lý do nó được áp dụng. Việc một tổ chức hoặc dự án cụ thể sử dụng Rust cho thấy việc áp dụng là khả thi trong những điều kiện đó, nhưng không có nghĩa bản thân ngôn ngữ là nguyên nhân duy nhất của quyết định, cũng không có nghĩa hiệu quả tương tự sẽ lặp lại ở các tổ chức khác. Trong cuốn sách này, “áp dụng” cũng có thể chỉ những phạm vi khác nhau như sử dụng thử nghiệm, đưa vào thành phần mới, thay thế một phần hệ thống hiện có hoặc tiêu chuẩn hóa ở cấp tổ chức; vì vậy không nguồn nào được khái quát vượt quá mức mà nó thực sự chứng minh.

Chương này xem xét các cách giải thích về việc áp dụng Rust bằng cách tách riêng độ phù hợp kỹ thuật, trải nghiệm nhà phát triển và công cụ, điều kiện của tổ chức và hệ sinh thái, cùng câu chuyện và nhận thức công chúng. Các yếu tố này có thể ảnh hưởng lẫn nhau, nhưng sự tồn tại của một yếu tố không tự chứng minh tác động của yếu tố khác hay nguyên nhân của toàn bộ việc áp dụng. Vì vậy, lợi thế kỹ thuật, sự tiện lợi của công cụ, bảo trợ của tổ chức và tác động của diễn ngôn được xem là những vấn đề bằng chứng riêng biệt.

2.1 Nền tảng kỹ thuật: Mục tiêu an toàn bộ nhớ và hiệu năng

Một lập luận thường được nêu trong các giải thích kỹ thuật về việc áp dụng Rust là Rust cung cấp một lựa chọn mới cho phần mềm hệ thống bằng cách hướng tới tăng cường an toàn bộ nhớ mà không cần bộ thu gom rác (GC) chạy ở runtime, đồng thời kết hợp quyền kiểm soát cấp thấp với hiệu năng thực thi cao. Tài liệu chính thức của Rust giải thích rằng các quy tắc sở hữu được trình biên dịch kiểm tra và mô hình này được thiết kế để cung cấp bảo đảm an toàn bộ nhớ mà không cần GC trong phạm vi Safe Rust. Các quy tắc mượn góp phần ngăn data race ở thời điểm biên dịch bằng cách hạn chế các tham chiếu khả biến tồn tại đồng thời; Rust Reference xếp data race, truy cập thông qua con trỏ đã hết thời gian sống hoặc bị căn chỉnh sai, và việc tạo giá trị kiểu không hợp lệ vào nhóm hành vi không xác định.22

Ở đây cần phân biệt mục tiêu thiết kế với kết quả hiệu năng quan sát được. Việc các quy tắc sở hữu tự thân không đòi hỏi một GC runtime riêng biệt không bảo đảm rằng mọi chương trình Rust đều nhanh hơn hoặc có hiệu năng bằng chương trình C hay C++. Như Mục 1.3 đã phân tích, hiệu năng thực tế phụ thuộc vào thuật toán, cấp phát, kiểm tra biên, dispatch, cách triển khai thư viện và trình biên dịch, phần cứng đích và workload.

Đặc biệt, mô tả C++ hiện đại đơn giản là “ngôn ngữ quản lý bộ nhớ thủ công không có cơ chế an toàn” là không chính xác. C++ hiện đại có các thực hành ở cấp ngôn ngữ và thư viện để quản lý tài nguyên và thời gian sống an toàn hơn, gồm RAII, smart pointer, container và span; C++ Core Guidelines cũng khuyến nghị tránh raw owning pointer và việc dùng trực tiếp new/delete, thay vào đó quản lý tự động thông qua resource handle. Tuy nhiên, xét về vị trí đặt bảo đảm, việc áp dụng các thực hành và công cụ phân tích này khác với Safe Rust, nơi trình biên dịch mặc định kiểm tra các quy tắc sở hữu và mượn.23

Không nên khái quát toàn bộ các ngôn ngữ dựa trên GC như thể chúng có chung một đặc tính hiệu năng. Chẳng hạn, tài liệu HotSpot GC của Oracle phân biệt throughput và latency như các chỉ số hiệu năng chính của garbage collection, đồng thời giải thích rằng sự đánh đổi giữa thời gian tạm dừng, throughput và mức dùng bộ nhớ khác nhau theo collector và cấu hình. Vì vậy, khái quát rằng “GC có tạm dừng nên không phù hợp cho phần mềm hệ thống” là quá rộng. Độ phù hợp thực tế thay đổi theo collector và runtime, kích thước heap và đối tượng còn sống, workload, yêu cầu latency, ràng buộc bộ nhớ và môi trường đích.24

Điểm khác biệt kỹ thuật của Rust trong so sánh này không phải mệnh đề rằng “không có GC nên tự động nhanh hơn”, mà là lựa chọn thiết kế kiểm tra tĩnh một phần đáng kể quan hệ thời gian sống bộ nhớ và aliasing thông qua các quy tắc sở hữu và mượn, đồng thời tăng cường an toàn bộ nhớ mà không cần một GC runtime riêng biệt. Trong môi trường khó hoặc không muốn sử dụng bộ thu gom runtime, hoặc nơi quyền kiểm soát cấp thấp và quản lý rõ ràng vòng đời tài nguyên là quan trọng, đặc tính này có thể là lý do mạnh để áp dụng. Ngược lại, Safe Rust không loại bỏ mọi lỗi logic, race condition nói chung, rò rỉ bộ nhớ hay cạn kiệt tài nguyên; các nghĩa vụ soundness bổ sung vẫn còn tại các ranh giới liên quan đến unsafe và FFI.22

Kết luận tạm thời

Thiết kế Rust, khi xem xét đồng thời an toàn bộ nhớ và chi phí runtime, có thể mang lại độ phù hợp kỹ thuật thực chất cho một số phần mềm hệ thống. Tuy nhiên, mức độ mà sự phù hợp đó thực sự đóng góp vào quyết định áp dụng là một câu hỏi thực nghiệm riêng biệt. Nếu không có hồ sơ quyết định của tổ chức, khảo sát, báo cáo migration và dữ liệu so sánh, không thể chỉ từ sự tồn tại của lợi thế kỹ thuật mà xác định nguyên nhân duy nhất của việc áp dụng hay hiệu quả trung bình. Vì vậy, mục này xác định lý do kỹ thuật và điều kiện áp dụng mà theo đó Rust có thể được chọn; kết luận về nguyên nhân tổng thể của việc áp dụng sẽ được đánh giá cùng với các phân tích tiếp theo về công cụ, hệ sinh thái và câu chuyện.

2.2 Trải nghiệm nhà phát triển (DX): Cargo và chuỗi công cụ

Khi giải thích việc áp dụng Rust, trải nghiệm công cụ nhất quán xoay quanh Cargo thường được nêu như một lợi thế. Tuy nhiên, lập luận này có hai lớp khác nhau. Một lớp là sự thật chức năng về những quy trình mà Cargo, rustup và các công cụ liên quan thực sự chuẩn hóa; lớp còn lại là tuyên bố thực nghiệm và nhân quả về mức độ sự chuẩn hóa đó đóng góp vào năng suất nhà phát triển, onboarding và quyết định áp dụng của tổ chức. Lớp thứ nhất có thể được xác nhận bằng tài liệu chính thức, còn lớp thứ hai cần đo lường và so sánh riêng.

Cargo là trình quản lý gói kiêm công cụ xây dựng chính thức của Rust; thông qua manifest và hệ thống lệnh chung, nó chuẩn hóa các điểm vào cho việc xây dựng, kiểm tra, kiểm thử và tạo tài liệu giữa các dự án Cargo. rustup quản lý toolchain của trình biên dịch và các công cụ liên quan, còn profile cài đặt mặc định bao gồm rustfmt và Clippy. rust-analyzer cũng là một component chính thức có thể cài đặt, và dự án có thể ghi channel, component và target của toolchain vào kho mã nguồn bằng rust-toolchain.toml.25 Lộ trình mặc định chung này có thể giảm chi phí phải học lại lệnh và lựa chọn công cụ khác nhau ở từng dự án. Tuy nhiên, bản thân tài liệu về chức năng chính thức không đo mức cải thiện về thời gian onboarding hay năng suất phát triển, vì vậy không nên đồng nhất sự thật rằng các công cụ được tích hợp với kết luận rằng nhà phát triển có năng suất cao hơn.

Dữ liệu sử dụng thực tế cũng cho thấy cả hai mặt. Hơn 3.700 người đã trả lời khảo sát hiệu năng trình biên dịch năm 2025 của dự án Rust, và khoảng 60% cho biết họ dùng các lệnh Cargo trong terminal để kiểm tra kiểu, xây dựng và kiểm thử. Đây là bằng chứng trực tiếp rằng Cargo giữ vị trí trung tâm trong quy trình làm việc thực tế của những người trả lời khảo sát đó.

Tuy nhiên, trong cùng khảo sát, trong số những người trả lời dựa trên dự án gặp vấn đề thời gian xây dựng nghiêm trọng nhất, 55% cho biết họ phải chờ hơn 10 giây để xây dựng lại sau một thay đổi nhỏ; trong số những người cho biết đã ngừng dùng Rust, khoảng 45% nêu thời gian biên dịch dài là một trong các lý do. 2025 State of Rust Survey cũng tiếp tục báo cáo biên dịch chậm và mức dùng dung lượng lưu trữ là các vấn đề hạn chế năng suất, đồng thời nhóm khảo sát nói rõ rằng không nên khái quát quá mức khoảng bảy nghìn câu trả lời cho toàn bộ người dùng.26

Vì vậy, các dữ liệu này cho thấy cả việc sử dụng thực tế của quy trình xoay quanh Cargo lẫn chi phí của nó, nhưng không chứng minh Cargo làm tăng năng suất trung bình so với các hệ sinh thái khác hay là nguyên nhân khiến Rust được áp dụng.

Cũng không chính xác khi đối chiếu hệ sinh thái C và C++ như những môi trường không có công cụ xây dựng và quản lý gói. CMake cung cấp công cụ cấu hình, xây dựng, cài đặt, kiểm thử và đóng gói cùng Presets; Meson tích hợp các công việc phát triển phổ biến như xây dựng và kiểm thử. vcpkg có thể khai báo trực tiếp phụ thuộc và ràng buộc phiên bản trong manifest, còn Conan quản lý phụ thuộc C/C++ và gói nhị phân trên nhiều hệ thống xây dựng và nền tảng.27 Khác biệt không nằm nhiều ở việc công cụ có tồn tại hay không, mà ở mức độ tích hợp của lộ trình mặc định và cấu trúc lựa chọn. Trong hệ sinh thái Rust, Cargo và nhiều công cụ do dự án Rust phân phối tạo thành các quy ước chung mạnh; trong C/C++, tổ chức thường chọn các tổ hợp khác nhau theo tổ chức, nền tảng và tài sản hiện có. Cách thứ nhất có thể thuận lợi cho việc giảm chi phí phối hợp nhờ quy ước chung; cách thứ hai có thể cung cấp độ linh hoạt để phù hợp với hệ thống xây dựng, cách phân phối nhị phân và chính sách kho nội bộ hiện có. Vì vậy không thể mặc định rằng một trong hai cấu trúc luôn có tổng chi phí thấp hơn.

Một toolchain mặc định đã tích hợp cũng không xóa bỏ chi phí tích hợp ở cấp tổ chức. rustup target add cài đặt thư viện chuẩn Rust cho target biên dịch chéo nhưng không cung cấp mọi linker hay SDK bên ngoài; tài liệu cài đặt chính thức của Rust cũng giải thích rằng các bản dựng thông thường cần linker và một số crate có thể cần trình biên dịch C vì chứa mã C.28 Những tổ chức đã có monorepo, build farm nội bộ, private registry, kiểm tra bảo mật và giấy phép, hay hệ thống đóng gói và triển khai có thể phải kết nối Cargo với các hệ thống đó hoặc vận hành song song. Trong môi trường quy mô lớn và vận hành lâu dài, cần đánh giá không chỉ sự tiện lợi của lệnh chung mà cả việc cố định và cập nhật toolchain, CI cache và thời gian xây dựng, phụ thuộc native, phục hồi ngoại tuyến, kiểm toán bảo mật, migration và chi phí rollback. Các ranh giới về phụ thuộc, vendoring và chuỗi cung ứng tuân theo phân tích đã nêu ở Mục 1.5.

Kết luận tạm thời

Lộ trình công cụ chính thức gồm Cargo, rustup, rustfmt, Clippy và rust-analyzer là một trong những lợi thế kỹ thuật rõ ràng của Rust. Manifest và hệ thống lệnh chung, quản lý toolchain và sự kết hợp của các công cụ bên thứ nhất có thể làm cho quy trình làm việc giữa các dự án dễ dự đoán hơn; dữ liệu khảo sát cũng cho thấy Cargo được sử dụng rộng rãi trong quy trình phát triển thực tế của nhiều người trả lời. Tuy nhiên, ba mệnh đề được sử dụng rộng rãi, làm tăng năng suất, và gây ra việc áp dụng là khác nhau. Muốn khẳng định tác động đến năng suất hay việc áp dụng, cần thêm dữ liệu so sánh hoặc hồ sơ quyết định của tổ chức có kiểm soát quy mô dự án, kinh nghiệm của nhóm, công cụ hiện có, môi trường xây dựng và các thay đổi đồng thời. Vì vậy, điều có thể xác nhận ở mục này là đặc tính kỹ thuật của trải nghiệm công cụ tích hợp và điều kiện áp dụng của nó, chứ không phải Cargo là nguyên nhân phổ quát khiến Rust được áp dụng.

2.3 Xây dựng câu chuyện và phân tích “thiết lập chương trình nghị sự”

Trong mục này, câu chuyện (narrative) là cách giải thích trình bày việc xác định vấn đề, đề xuất giá trị và tiêu chí so sánh theo một cấu trúc nhất quán để người đọc hiểu một công nghệ muốn giải quyết vấn đề gì và vì sao nó có thể được lựa chọn. Thuật ngữ này không hàm ý rằng một chủ thể trung tâm duy nhất kiểm soát thông điệp hay đã có sự thao túng có chủ ý. Thiết lập chương trình nghị sự (agenda-setting) được dùng theo nghĩa hẹp hơn. Nghiên cứu năm 1972 của McCombs và Shaw so sánh, trong một cuộc bầu cử, địa điểm, mẫu và khoảng thời gian xác định, mức độ truyền thông nhấn mạnh các vấn đề với những vấn đề mà cử tri cho là quan trọng. Vì vậy, chỉ riêng việc một chủ đề được lặp lại trong tài liệu chính thức hoặc thảo luận trực tuyến không đủ để xác nhận hiệu ứng thiết lập chương trình nghị sự theo đó đánh giá của nhóm nhà phát triển về mức độ quan trọng đã thay đổi.29

Tài liệu chính thức của Dự án Rust cho phép xác nhận trực tiếp những giá trị nào đã được truyền đạt. Thông báo Rust 1.0 Alpha năm 2015 mô tả trọng tâm của ngôn ngữ là an toàn, hiệu năng và đồng thời; cuốn sách chính thức gọi cách tiếp cận dùng sở hữu và kiểm tra kiểu để xử lý nhiều lỗi đồng thời ở thời điểm biên dịch là “fearless concurrency”. Bài viết năm 2018 về việc thiết kế lại rust-lang.org giải thích rằng trang đầu cũ, vốn liệt kê những đặc tính như zero-cost abstraction, an toàn bộ nhớ và luồng không có data race, đã được xem xét lại; trang mới đưa “Why Rust?” ra phía trước và đồng thời sửa khẩu hiệu. Tại thời điểm sửa đổi cuốn sách này, trang đầu chính thức trình bày Performance, Reliability và Productivity như các nhóm giá trị chính.30

Điều các nguồn này trực tiếp chứng minh chỉ đến mức Dự án Rust đã trình bày an toàn, hiệu năng, đồng thời, năng suất và trải nghiệm công cụ như các đề xuất giá trị chính thức, đồng thời chủ động điều chỉnh cách trình bày chúng. Từ đó không thể lập tức kết luận rằng “toàn bộ cộng đồng Rust chia sẻ cùng một câu chuyện”, “diễn ngôn Rust đã thay đổi chương trình nghị sự đánh giá của lập trình hệ thống”, hay “các thông điệp này khiến nhà phát triển hoặc tổ chức áp dụng Rust”. Thông điệp chính thức của dự án, diễn ngôn cộng đồng không chính thức, nhận thức của người tiếp nhận về điều gì là quan trọng và quyết định áp dụng thực tế là các đơn vị quan sát khác nhau.

Đặc biệt, mệnh đề “an toàn bộ nhớ trở thành tiêu chí đánh giá trung tâm trong lập trình hệ thống vì diễn ngôn Rust” mạnh hơn quan sát rằng an toàn bộ nhớ xuất hiện lặp lại trong tài liệu chính thức. Để kiểm chứng mệnh đề đó bằng thực nghiệm cần xác định tổng thể hoặc mẫu tài liệu và bài đăng cần phân tích, tiêu chí đưa vào và loại trừ, khoảng thời gian, đối tượng so sánh, phương pháp đo mức độ nhấn mạnh theo chủ đề, cùng dữ liệu cho biết người tiếp nhận coi tiêu chí nào là quan trọng. Nếu không có thiết kế như vậy, phạm vi có thể nói trong mục này chỉ là giao tiếp chính thức của Rust đã liên tục đặt an toàn bộ nhớ và các giá trị liên quan ở vị trí nổi bật, và nhiều nhất là điều đó có thể đã cung cấp khung cho sự chú ý và diễn giải. Hiệu ứng thiết lập chương trình nghị sự trên toàn cộng đồng và mức độ của nó vẫn chưa được xác nhận.29

Diễn ngôn trực tuyến không chính thức cũng phải chịu cùng tiêu chuẩn bằng chứng. Một số bài đăng hoặc cách diễn đạt lặp lại có thể là ví dụ định tính cho thấy một cấu trúc lập luận tồn tại, nhưng kết luận rằng nó phổ biến hoặc chi phối đòi hỏi tổng thể được xác định, phương pháp lấy mẫu và khoảng thời gian. Tương tự, mệnh đề giáo dục rằng “học Rust có thể giúp hiểu một số vấn đề cụ thể” khác về tầng logic với phán xét địa vị rằng “vì là người dùng Rust nên thông minh hơn hoặc có đủ tư cách hơn”. Mức độ các cách diễn đạt thuộc loại sau thực sự tồn tại và chức năng của chúng sẽ không được khái quát từ các ví dụ được chọn; Mục 8.5 và 9.2 sẽ xem xét chúng cùng với dữ liệu diễn ngôn riêng.

Ảnh hưởng của câu chuyện đến việc áp dụng thực tế cũng là một câu hỏi nhân quả riêng. Thông điệp chính thức có thể làm một số lợi thế trở nên nổi bật hơn và cung cấp tiêu chí so sánh, nhưng để đánh giá nó làm thay đổi việc học, sở thích của nhà phát triển hay quyết định áp dụng của tổ chức đến mức nào cần bằng chứng trực tiếp nối việc tiếp xúc, nhận thức và quyết định, chẳng hạn khảo sát, thí nghiệm, dữ liệu dọc hoặc hồ sơ quyết định của tổ chức. Ảnh hưởng của sự bảo trợ từ tổ chức và doanh nghiệp đối với niềm tin hay việc áp dụng được tách khỏi vấn đề này và sẽ được xem xét riêng trong Mục 2.4.

Kết luận tạm thời

Tài liệu xác nhận rằng Dự án Rust đã chính thức trình bày an toàn, hiệu năng, đồng thời, năng suất và trải nghiệm công cụ như những giá trị quan trọng, đồng thời đã điều chỉnh cách truyền đạt các giá trị đó trên website và trong tài liệu. Tuy nhiên, sự tồn tại của đề xuất giá trị chính thức, sự lặp lại trong diễn ngôn không chính thức, thay đổi trong nhận thức của người tiếp nhận về mức độ quan trọng và hiệu ứng nhân quả đối với việc áp dụng thực tế là những mệnh đề khác nhau. Vì vậy, mục này xác nhận sự tồn tại của giao tiếp chính thức và việc xây dựng câu chuyện của Rust, nhưng không xác nhận việc thiết lập chương trình nghị sự trên toàn cộng đồng hay hiệu ứng áp dụng khi không có mẫu diễn ngôn được xác định và dữ liệu về người tiếp nhận.

2.4 Sự bảo trợ của tổ chức và văn hóa cộng đồng

Cần phân biệt sự kiện các tổ chức và doanh nghiệp hỗ trợ Rust với khẳng định về hiệu ứng rằng sự hỗ trợ đó làm tăng niềm tin, tính chính danh hoặc việc áp dụng. Rust Core Team giải thích vào năm 2020 rằng Rust bắt đầu như một dự án của Mozilla Research và sau Rust 1.0 năm 2015, định hướng cùng cơ chế quản trị của dự án trở nên độc lập với tổ chức Mozilla, trong khi Mozilla tiếp tục là một nhà hỗ trợ lớn về tài chính và pháp lý. Khi Rust Foundation ra mắt vào năm 2021, AWS, Huawei, Google, Microsoft và Mozilla tham gia với tư cách thành viên sáng lập, còn hội đồng quản trị của Foundation gồm 5 giám đốc từ phía các công ty thành viên đó và 5 giám đốc từ phía Dự án Rust.31

Trong lịch sử này cũng không nên đồng nhất sự hỗ trợ thể chế của Rust Foundation với việc ra quyết định kỹ thuật của Dự án Rust. Trong quá trình thảo luận về việc thành lập Foundation, Rust Core Team giải thích rằng Foundation sẽ cung cấp nền tảng cho hỗ trợ pháp lý, tài chính và maintainer, trong khi phạm vi công việc và quyền ra quyết định của phần lớn các nhóm Rust sẽ không thay đổi. Tại thời điểm sửa đổi cuốn sách này, cơ chế quản trị chính thức của Dự án Rust vẫn tách riêng Leadership Council và nhiều top-level team. Vì vậy, việc một công ty là thành viên Foundation không có nghĩa công ty đó trực tiếp kiểm soát các quyết định kỹ thuật về ngôn ngữ hay trình biên dịch. Ngược lại, sự tồn tại của một pháp nhân, hỗ trợ tài chính, hạ tầng và hệ thống hỗ trợ maintainer mô tả điều kiện vận hành của dự án, nhưng mức độ các điều kiện này thay đổi niềm tin hoặc quyết định áp dụng của các tổ chức bên ngoài là một câu hỏi thực nghiệm riêng.31

Thông báo ra mắt Foundation diễn giải các cam kết tài chính dài hạn của những công ty sáng lập như một tín hiệu rằng Rust đã trở thành công nghệ production-ready trong môi trường doanh nghiệp. Tuy nhiên, đó là diễn giải chính thức của chính Foundation, không phải phép đo độc lập về nhận thức hay hiệu ứng áp dụng ở các tổ chức bên ngoài. Muốn khẳng định sự bảo trợ của doanh nghiệp ảnh hưởng đến niềm tin, tính chính danh hoặc việc áp dụng, cần thêm dữ liệu khảo sát hoặc so sánh cho thấy sự bảo trợ có thực sự là yếu tố đánh giá trong hồ sơ quyết định hay không, nhận thức thay đổi ra sao trước và sau sự bảo trợ, và các yếu tố kỹ thuật hay tổ chức khác được kiểm soát như thế nào.31

Đối với văn hóa cộng đồng cũng vậy, cần tách sự tồn tại của các chuẩn mực và tài nguyên chính thức khỏi hành vi và kết quả thực tế của toàn bộ cộng đồng. Bộ quy tắc ứng xử của Rust đặt mục tiêu tạo ra một môi trường tử tế, an toàn và chào đón trong các không gian Rust chính thức, đồng thời quy định thủ tục moderation và chế tài đối với vi phạm. Trang học Rust chính thức giới thiệu The Rust Programming Language như tài liệu nhập môn, và bản thân Book cấu trúc lộ trình học ngôn ngữ gồm cài đặt, sử dụng Cargo, ownership và các chủ đề khác.32 Các nguồn này cho thấy Dự án Rust chính thức cung cấp những chuẩn mực và tài nguyên học tập nào, nhưng không phải bằng chứng rằng mọi tương tác đều đáp ứng các chuẩn mực đó hay cùng một văn hóa được quan sát trên toàn bộ các cộng đồng Rust không chính thức.

Tương tự, chỉ riêng sự tồn tại của Bộ quy tắc ứng xử và tài liệu học tập không chứng minh rằng rào cản gia nhập thực sự giảm, thời gian học rút ngắn, hoặc tỷ lệ duy trì hay tính đa dạng của người tham gia mới tăng lên. Đánh giá các hiệu ứng như vậy cần khảo sát hoặc nghiên cứu so sánh nối trải nghiệm của người dùng và người đóng góp mới với dữ liệu rời bỏ và duy trì, thời gian học và tỷ lệ thành công, cùng việc sử dụng tài liệu. Từ góc độ vận hành quy mô lớn và dài hạn, cần đánh giá không chỉ số lượng tổ chức bảo trợ mà cả tính liên tục của trách nhiệm pháp lý và tài chính, mức phụ thuộc vào các nhà bảo trợ cụ thể, sự tách biệt giữa quản trị và quyết định kỹ thuật, cũng như khả năng ứng phó khi hạ tầng hoặc hỗ trợ maintainer bị gián đoạn hay thay đổi. Việc Dự án Rust trong quá trình thành lập Foundation năm 2020 nêu rõ mục tiêu đa dạng hóa hỗ trợ hạ tầng để giảm phụ thuộc vào một nhà bảo trợ duy nhất cũng liên quan đến sự phân biệt này.31

Kết luận tạm thời

Sự hỗ trợ lâu dài của Mozilla, việc thành lập Rust Foundation độc lập, cấu trúc Foundation có cả đại diện doanh nghiệp và dự án cùng tham gia, Bộ quy tắc ứng xử của Dự án Rust và các tài nguyên học tập chính thức đều là những nền tảng thể chế và cộng đồng có thể xác nhận bằng tài liệu. Tuy nhiên, sự tồn tại của hệ thống hỗ trợ, sự tồn tại của chuẩn mực và tài nguyên chính thức, thay đổi về niềm tin, học tập hoặc hành vi cộng đồng, và hiệu ứng nhân quả đối với việc áp dụng thực tế là các mệnh đề khác nhau. Vì vậy, mục này xác nhận Rust có hỗ trợ thể chế và các thực hành cộng đồng chính thức, nhưng không xác nhận chúng là nguyên nhân phổ quát của việc áp dụng hoặc kết quả cộng đồng khi chưa có dữ liệu kết quả trực tiếp.

2.5 Tổng hợp các yếu tố áp dụng và kết luận Chương 2

Các mục trước đã xác nhận những yếu tố khác nhau có thể được xem xét khi giải thích việc áp dụng Rust. Mục 2.1 xác nhận sự phù hợp kỹ thuật trong một số môi trường đồng thời cần an toàn bộ nhớ và khả năng kiểm soát mức thấp; Mục 2.2 xác nhận quy trình làm việc chung do Cargo và toolchain chính thức cung cấp; Mục 2.3 xác nhận các giá trị và cách xây dựng câu chuyện mà Dự án Rust đã chính thức trình bày; Mục 2.4 xác nhận sự hỗ trợ của Mozilla, nền tảng thể chế của Rust Foundation, Bộ quy tắc ứng xử và các tài nguyên học tập. Tuy nhiên, chỉ riêng việc những yếu tố này cùng tồn tại không chứng minh rằng chúng tạo thành một chuỗi nhân quả gây ra việc áp dụng Rust hoặc khuếch đại hiệu ứng của nhau.

Sự phân biệt này càng quan trọng tùy theo phạm vi áp dụng được nói tới trong chương. Sử dụng thử nghiệm, đưa Rust vào một thành phần mới, thay thế một phần hệ thống hiện có, sử dụng ở cấp nhóm và chuẩn hóa ở cấp tổ chức là những quyết định khác nhau; cùng một đặc tính kỹ thuật hay công cụ có thể được đánh giá với trọng số khác nhau ở mỗi phạm vi. Vì vậy, việc Rust được sử dụng trong một trường hợp cho thấy việc áp dụng là khả thi và Rust đã được lựa chọn trong các điều kiện đó, nhưng không cho biết yếu tố nào mang tính quyết định hay hiệu ứng của nó có lặp lại ở phạm vi hoặc tổ chức khác hay không.

Các ranh giới bằng chứng của Mục 2.1-2.4 cũng phải được giữ nguyên. Sự phù hợp kỹ thuật giải thích một lý do lựa chọn có thể có nhưng không đo mức đóng góp vào quyết định thực tế; mức độ phổ biến của quy trình làm việc xoay quanh Cargo cũng là một mệnh đề khác với hiệu ứng của nó đối với năng suất hay việc áp dụng. Sự tồn tại của các đề xuất giá trị chính thức, hỗ trợ thể chế, Bộ quy tắc ứng xử và tài nguyên học tập cũng được tài liệu xác nhận, nhưng thay đổi trong nhận thức của người tiếp nhận, hành vi của toàn bộ cộng đồng, niềm tin của các tổ chức bên ngoài và hiệu ứng đối với việc áp dụng thực tế cần dữ liệu kết quả riêng. Dữ liệu trong chương này cũng không cung cấp cơ sở để xếp hạng tầm quan trọng tương đối của các yếu tố đó.

Giải thích rằng các yếu tố này tương tác với nhau là một giả thuyết có thể có, không phải tự thân là một kết quả quan sát. Để khẳng định điều đó bằng thực nghiệm cần khảo sát, hồ sơ quyết định, dữ liệu dọc hoặc một thiết kế nghiên cứu tương đương nối đánh giá kỹ thuật, trải nghiệm công cụ, mức tiếp xúc với thông điệp, điều kiện thể chế và quyết định thực tế. Đồng thời phải xem xét các cách giải thích thay thế như mã và giao diện hiện có, kinh nghiệm và cơ cấu nhân sự của nhóm, các ràng buộc kiến trúc và vận hành, chính sách bảo mật và mua sắm, lịch trình và chi phí, cũng như việc thiết kế lại hoặc thay đổi quy trình diễn ra đồng thời. Nếu không kiểm soát các điều kiện này, chỉ từ những trường hợp thành công hoặc áp dụng sẽ khó tách riêng hiệu ứng độc lập của ngôn ngữ, công cụ, sự hỗ trợ hay câu chuyện.

Kết luận Chương 2

Điều có thể xác nhận từ tài liệu và dữ liệu là Rust có các đặc tính kỹ thuật có thể phù hợp với một số môi trường phần mềm hệ thống, một lộ trình công cụ chính thức được tích hợp, các đề xuất giá trị chính thức được trình bày lặp lại, cùng hỗ trợ thể chế và các thực hành cộng đồng chính thức. Những yếu tố này cung cấp các lý do và điều kiện mà một tổ chức hay nhà phát triển cụ thể có thể cân nhắc khi đánh giá và lựa chọn Rust. Tuy nhiên, sự tồn tại của các lý do có thể dẫn tới áp dụng, mức đóng góp của chúng trong quyết định thực tế, sự tương tác giữa nhiều yếu tốhiệu ứng nhân quả trung bình có thể khái quát sang các tổ chức khác là những mệnh đề khác nhau.

Vì vậy, chương này không giải thích việc áp dụng Rust bằng một dạng ưu thế kỹ thuật duy nhất hay một hiệu ứng câu chuyện duy nhất. Các tài liệu đã xem xét hiện đủ để xác định nhiều yếu tố ứng viên và điều kiện áp dụng, nhưng chưa đủ để xác định một cách khái quát yếu tố nào mang tính quyết định đến mức nào trong từng phạm vi áp dụng. Trong các trường hợp công nghiệp và phân tích so sánh tiếp theo, cũng không nên dùng bản thân việc áp dụng làm bằng chứng cho ưu thế kỹ thuật; thay vào đó cần tách riêng hồ sơ quyết định, điều kiện hệ thống, các thay đổi diễn ra đồng thời và những lựa chọn thay thế. Phần 2 tách câu hỏi nhân quả này khỏi việc phân tích các bảo đảm, chi phí và quan hệ lịch sử của những nguyên tắc thiết kế chính của Rust như an toàn và sở hữu.


Phần 2: Phân tích kỹ thuật các nguyên tắc thiết kế chính

Phần 1 đã xem xét các đặc tính kỹ thuật và câu chuyện liên quan đến Rust. Phần 2 phân tích về kỹ thuật các nguyên tắc thiết kế chính của Rust là an toàn và sở hữu.

Phần này xem xét từ nhiều góc độ cơ sở của việc đánh giá các nguyên tắc đó là “đổi mới”, các đánh đổi kỹ thuật và mối liên hệ của chúng với tiền lệ lịch sử trong các ngôn ngữ như C++ và Ada. Đồng thời, phần này phân biệt tái cấu trúc, hiện đại hóa, thay thế một phần và viết lại toàn bộ một cơ sở mã hiện có như các chiến lược thay đổi khác nhau, thiết lập tiêu chí phân tích để không đồng nhất bảo đảm cấp ngôn ngữ với hiệu quả cải thiện cấp dự án.

3. Phân tích đa chiều câu chuyện “an toàn”

“An toàn (safety)” được bàn trong chương này không phải là một thuộc tính đơn nhất có thể xem như đồng nhất. Bảo đảm ở cấp ngôn ngữ của Rust, cách triển khai của trình biên dịch và thư viện, các chế độ thất bại khi vận hành, chiến lược thay đổi hệ thống hiện có và cách dùng từ “an toàn” trong diễn ngôn kỹ thuật là những đơn vị phân tích khác nhau. Vì vậy, chương này không mặc định các mệnh đề bao quát như “Rust an toàn” hay “các ngôn ngữ hiện có không an toàn”, mà tách riêng để xem thuộc tính nào được bảo đảm trong điều kiện nào.

Mục 3.1 trước hết xem xét quan hệ lịch sử giữa thiết kế Rust với các ngôn ngữ và kỹ thuật có trước, đồng thời phân biệt tiền lệ lịch sử, sự tương đồng về khái niệmảnh hưởng trực tiếp được tài liệu chính thức xác nhận. Mục 3.2 phân tích các bảo đảm kỹ thuật của Safe Rust cùng những ranh giới liên quan đến unsafe, panic, rò rỉ bộ nhớ, lỗi logic và các trường hợp khác. Mục 3.3 so sánh cải tiến từng bước trong C/C++, thay thế một phần và viết lại bằng Rust như các chiến lược thay đổi khác nhau. Mục 3.4–3.5 xem xét Ada/SPARK và các ngôn ngữ dựa trên GC theo cùng tiêu chí so sánh, còn Mục 3.6 tách khỏi sự thật kỹ thuật để phân tích cách “an toàn” được sử dụng trong diễn ngôn. Cuối cùng, Mục 3.7 tổng hợp các kết quả này thành những đánh đổi trong thiết kế.

Trình tự này nhằm tránh đồng nhất tiền lệ lịch sử với bảo đảm hiện tại, đồng nhất bảo đảm mạnh ở cấp ngôn ngữ với bảo đảm thành công của quá trình chuyển đổi dự án, hoặc xem sự tồn tại của một cách diễn đạt trong diễn ngôn là bằng chứng cho ưu thế kỹ thuật.

3.1 Ý nghĩa của “đổi mới” và phân tích tiền lệ lịch sử

Trong công nghệ, “đổi mới” không nhất thiết có nghĩa là “trước đó không tồn tại bất kỳ khái niệm nào liên quan”. Sự kết hợp mới, phạm vi áp dụng, vị trí mà quy tắc được cưỡng chế, tính dễ sử dụng hay cách triển khai cũng có thể là đối tượng của đổi mới. Ngược lại, chỉ vì hai công nghệ giống nhau cũng không đủ để kết luận một bên trực tiếp bắt nguồn từ bên kia. Trong mục này, chỉ khi tài liệu sơ cấp của Dự án Rust nêu rõ một ảnh hưởng thì mới gọi đó là ảnh hưởng trực tiếp; các quan hệ khác được giới hạn ở tiền lệ lịch sử hoặc tương đồng khái niệm.

RAII của C++ và ownership của Rust: ảnh hưởng được ghi nhận và vị trí cưỡng chế khác nhau

Rust Reference nêu rõ references, RAII, smart pointers và move semantics của C++ là những ảnh hưởng đối với thiết kế Rust. Rust Book chính thức cũng giải thích rằng mẫu giải phóng tài nguyên bằng drop khi vòng đời của một giá trị kết thúc được gọi là RAII trong C++. C++ Core Guidelines khuyến nghị đóng gói tài nguyên trong đối tượng để việc thu nhận và giải phóng được ghép cặp bởi quy tắc vòng đời của constructor và destructor, đồng thời coi đối tượng chịu trách nhiệm giải phóng tài nguyên là owner.33 Vì vậy, quan hệ ảnh hưởng của C++ RAII và các kỹ thuật quản lý tài nguyên liên quan đối với Rust là một liên hệ lịch sử được tài liệu chính thức xác nhận, không chỉ là sự giống nhau bề ngoài.

Tuy nhiên, điều đó không có nghĩa “khái niệm sở hữu tài nguyên nói chung được C++ phát minh đầu tiên rồi Rust chỉ mở rộng trực tiếp”. Rust kết hợp việc giải phóng tài nguyên xác định với những quy tắc riêng hạn chế việc dùng binding ban đầu sau khi ownership được move, và tĩnh hạn chế quan hệ aliasing giữa truy cập mutable và shared thông qua quy tắc borrowing. Cùng Rust Reference còn liệt kê riêng region-based memory management của ML Kit và Cyclone trong các ảnh hưởng đối với Rust.33 Vì vậy, quy toàn bộ thiết kế bộ nhớ và lifetime của Rust về một dòng C++ duy nhất cũng không chính xác. Mục này chỉ xác nhận sự tồn tại của mối quan hệ và khác biệt về vị trí cưỡng chế quy tắc; Safe Rust chính xác bảo đảm điều gì được dành cho Mục 3.2, còn so sánh chi tiết RAII với ownership của Rust được dành cho Mục 4.1.

Ada và SPARK: một dòng lịch sử sớm hơn về độ tin cậy cao và xác minh, nhưng không phải cùng dòng ownership

Chuẩn Ada 1983 có trước Rust, và Ada Reference Manual mô tả độ tin cậy và khả năng bảo trì của chương trình, hoạt động lập trình của con người và hiệu quả là những mối quan tâm chính của thiết kế ban đầu. Hệ thống type và subtype của Ada cùng các kiểm tra runtime do ngôn ngữ quy định đã hình thành truyền thống biến một số lớp lỗi thành thất bại kiểm tra rõ ràng. Ngôn ngữ SPARK ban đầu cũng dựa trên Ada 83 và phát triển một dòng high-assurance riêng, dùng phân tích tĩnh và verification condition để kiểm chứng các thuộc tính như khởi tạo, luồng thông tin, không có lỗi runtime và các contract đã nêu.34 Theo nghĩa này, Ada/SPARK là đối tượng so sánh lịch sử quan trọng khi đánh giá các tuyên bố kiểu “trước Rust không có ngôn ngữ hệ thống hay kỹ thuật xác minh nào đồng thời xử lý an toàn và hiệu quả”.

Tuy nhiên, sẽ vượt quá phạm vi bằng chứng nếu từ đó khẳng định “Ada/SPARK đã triển khai cùng mô hình an toàn bộ nhớ không GC như Rust” hoặc “Rust chịu ảnh hưởng trực tiếp từ Ada/SPARK”. Danh sách ảnh hưởng trong Rust Reference được xem xét ở đây nêu rõ C++, SML/OCaml, ML Kit, Cyclone và các nguồn khác, nhưng không liệt kê Ada hay SPARK như ảnh hưởng trực tiếp. Hơn nữa, chính sách pointer ownership hiện tại của SPARK là chức năng được bổ sung về sau, và AdaCore mô tả pointer support đó là dựa trên Rust ownership model.34 Vì vậy, mục này xem Ada/SPARK như tiền lệ lịch sử của mục tiêu độ tin cậy cao và xác minh tĩnh/hình thức, chứ không xem nó là tổ tiên trực tiếp của Rust ownership. Proof của SPARK cũng chứng minh các thuộc tính đã nêu dưới những giả định và phạm vi phân tích xác định, còn Rust borrow checker thực hiện một lớp kiểm tra tự động khác; nếu không chỉ rõ thuộc tính cần so sánh thì không có cơ sở để xếp một bên một cách bao quát là “rộng hơn” hay “mạnh hơn”.

Kiểu dữ liệu đại số và biểu diễn lỗi: thu hẹp phạm vi của ảnh hưởng trực tiếp

Rust Reference nêu rõ algebraic data types, pattern matching và type inference của SML và OCaml là những ảnh hưởng đối với thiết kế Rust. Option<T> của Rust có NoneSome(T), Result<T, E>Ok(T)Err(E), còn option chuẩn của OCaml cũng dùng NoneSome để biểu diễn việc có hay không có một giá trị trong kiểu.35 Vì vậy, cách Rust biểu diễn sự vắng mặt của giá trị hoặc thành công/thất bại bằng kiểu dữ liệu thuộc họ sum type có thể được giải thích trong mối liên hệ với truyền thống ngôn ngữ hàm.

Tuy nhiên, phạm vi mà danh sách ảnh hưởng chính thức trực tiếp xác nhận chỉ là ảnh hưởng của ADT, pattern matching và type inference từ SML/OCaml. Chỉ từ các nguồn này không thể kết luận API cụ thể của ResultOption trực tiếp bắt nguồn từ một API xử lý lỗi cụ thể của Haskell hay OCaml, cũng không thể nói Rust đã vay mượn nguyên vẹn “xử lý lỗi đơn nguyên”. match exhaustive có thể kiểm tra tĩnh việc bao phủ các variant, nhưng Rust cũng không buộc mọi mã xử lý lỗi luôn phải viết rõ mọi trường hợp. Điều được xác nhận ở đây là dòng thiết kế biểu diễn trạng thái bằng type và cách Rust thể hiện cụ thể dòng đó, không phải một nguồn gốc duy nhất cho mọi cơ chế xử lý lỗi.35

Kết luận tạm thời

Bức tranh rõ hơn khi tách các quan hệ có thể xác nhận trực tiếp về lịch sử khỏi những đối tượng dùng để so sánh. RAII, smart pointers và move semantics của C++, cùng ADT của SML/OCaml, là những yếu tố mà Rust Reference ghi nhận như ảnh hưởng trực tiếp. Ada và SPARK thời kỳ đầu là đối tượng so sánh lịch sử thuộc dòng kỹ thuật độ tin cậy cao và xác minh hình thức có trước Rust, nhưng dữ liệu trong mục này không đủ để khẳng định chúng ảnh hưởng trực tiếp tới Rust; ngược lại, pointer ownership hiện tại của SPARK được thêm về sau với tham chiếu tới mô hình Rust. Vì vậy, tính độc đáo của Rust nên được xem xét chính xác hơn ở cách nó kết hợp và cưỡng chế nhiều ý tưởng có trước trong một tập quy tắc ownership/borrowing cụ thể cùng hệ thống ngôn ngữ và công cụ, thay vì ở mệnh đề “không hề có tiền lệ”. Tổ hợp đó cung cấp bảo đảm gì và kéo theo chi phí nào là vấn đề kỹ thuật tách biệt với thứ tự lịch sử, và sẽ được phân tích theo từng thuộc tính trong các mục tiếp theo.

3.2 Định nghĩa, ranh giới và giới hạn của “an toàn” trong Rust

Câu hỏi của mục này không phải là “Rust có an toàn không?”, mà là Safe Rust bảo đảm điều gì trong những điều kiện nào, và bảo đảm đó kết thúc ở đâu. Hợp đồng an toàn ở cấp ngôn ngữ, soundness của phần hiện thực unsafe, tính đúng đắn của các hiện thực và hệ thống bên ngoài như trình biên dịch, thư viện và hệ điều hành, cùng tính sẵn sàng của dịch vụ là những đơn vị phân tích khác nhau. Gộp tất cả vào một khái niệm “an toàn” sẽ phóng đại cả ưu điểm thực tế lẫn giới hạn thực tế của Rust.

Vì vậy, Mục 3.2.1 làm rõ quan hệ giữa Safe Rust và hành vi không xác định (Undefined Behavior, UB); Mục 3.2.2 phân tích unsafe và FFI không phải như việc “từ bỏ bảo đảm”, mà như ranh giới của safety contract và proof obligation được nêu rõ. Mục 3.2.3 phân biệt chiến lược unwind và abort của panic cùng giới hạn của cô lập và phục hồi; Mục 3.2.4 giải thích vì sao rò rỉ bộ nhớ và tài nguyên nằm ngoài bảo đảm memory safety; Mục 3.2.5 phân biệt lỗi logic, race condition nói chung, bế tắc, cạn tài nguyên và lỗ hổng bảo mật với memory safety.

3.2.1 Định nghĩa “an toàn”: Ngăn hành vi không xác định

Rust Reference xem UB là tập hợp những hành vi mà chương trình không được thực hiện. Danh sách hiện tại gồm data race, truy cập bộ nhớ không hợp lệ dựa trên pointer dangling hoặc sai căn chỉnh, vi phạm quy tắc aliasing, gọi hàm với ABI sai và tạo invalid value. Reference không tuyên bố danh sách này là một ngữ nghĩa hình thức hoàn chỉnh và cũng nêu rõ ranh giới này có thể được điều chỉnh trong tương lai.36

Hợp đồng cốt lõi của Safe Rust được hiểu chính xác hơn là khi safe caller sử dụng sound safe interface, caller đó không thể gây UB thông qua các interface ấy. Điều này khác với một dự đoán thực nghiệm rằng “nếu mã nguồn không có từ unsafe, toàn bộ chương trình sẽ không thể xảy ra UB vì bất kỳ lý do nào”. Mã Safe Rust có thể gọi safe API của thư viện chuẩn hoặc thư viện bên thứ ba, trong khi phần hiện thực bên trong các API đó có thể chứa unsafe. Nếu phần hiện thực bên trong không giữ được safety contract và khiến safe caller có thể gây UB, theo thuật ngữ của Rust Reference, phần hiện thực đó là unsound.36

Các loại lỗi cụ thể cũng phải được phân biệt theo cùng tiêu chí. Giải tham chiếu một allocation không còn sống, hoặc tạo rồi sử dụng một reference không hợp lệ, có thể là UB; reference trong Rust phải được căn chỉnh đúng, non-null và không dangling. data race cũng là UB. Ngược lại, khi indexing thông thường và an toàn của array hoặc slice vượt phạm vi tại runtime, phép indexing thực hiện kiểm tra biên rồi đi vào panic; không thể vì thế mà gọi ngay đó là UB do buffer overflow. Các thao tác bỏ kiểm tra biên như get_unchecked là thao tác unsafe có safety condition bổ sung; vi phạm điều kiện đó mới đi vào ranh giới UB.37

Sự phân biệt này quan trọng để tách bảo đảm của ngôn ngữ khỏi tính đúng đắn của hiện thực. Hợp đồng mà mô hình ngôn ngữ Rust yêu cầu đối với safe interface, việc một phiên bản rustc cụ thể có hiện thực đúng ý nghĩa ấy hay không, unsafe bên trong thư viện chuẩn hoặc crate có sound hay không, và hệ điều hành, phần cứng hay foreign code có giữ hợp đồng riêng của chúng hay không là những câu hỏi khác nhau. Lỗi trình biên dịch hoặc phần hiện thực thư viện unsound có thể phá vỡ an toàn bộ nhớ trong thực thi thực tế và là rủi ro hiện thực quan trọng, nhưng không nên biến sự thật đó thành một mệnh đề khác rằng “quy tắc ngôn ngữ của Safe Rust cho phép UB”.

3.2.2 Từ khóa unsafe và ranh giới của FFI, hợp đồng bên ngoài {#322-từ-khóa-unsafe-và-sự-phụ-thuộc-vào-c-abi}

unsafe không phải công tắc tắt toàn bộ quy tắc sở hữu, kiểu, lifetime và các kiểm tra khác của Rust. Rust Reference mô tả unsafe như một dấu hiệu tạo proof obligation cho safety condition bổ sung mà trình biên dịch không kiểm tra, hoặc tuyên bố rằng một nghĩa vụ được tạo ở nơi khác đã được thực hiện. unsafe fn có thể định nghĩa điều kiện bổ sung mà caller phải thỏa mãn, còn unsafe { ... } khẳng định rằng lập trình viên đã đáp ứng điều kiện của các unsafe operation thực hiện bên trong khối. UB vẫn là hành vi chương trình không hợp lệ bên trong unsafe, và các kiểm tra kiểu hay quy tắc ngôn ngữ khác cũng không biến mất.38

Vì vậy trách nhiệm cũng không cố định ở một vị trí. Caller phải đáp ứng tiền điều kiện được ghi tài liệu của unsafe fn, nhưng với một safe abstraction giấu unsafe ở bên trong, nghĩa vụ đi theo chiều ngược lại: người hiện thực phải bảo đảm các điều kiện nội bộ được giữ với mọi safe input. Để một safe API là sound, safe caller không được phải biết một safety condition không được ghi tài liệu mới có thể tránh UB. Do đó, nói rằng “ngay khi dùng unsafe, toàn bộ trách nhiệm an toàn chuyển sang caller” là không chính xác. Cần xét theo từng API: ai định nghĩa contract nào, và ai phải thực hiện proof obligation ở ranh giới nào.38

FFI là ví dụ điển hình nơi ranh giới này hiện rõ. External block là nền tảng FFI để khai báo item được định nghĩa bên ngoài crate hiện tại, và Rust Reference xem đây là ranh giới gần với một unchecked import. Trong Rust 2024 Edition, bản thân external block phải được đánh dấu unsafe extern, và người viết khai báo chịu trách nhiệm bảo đảm signature của function và static khớp với định nghĩa bên ngoài thực tế. Foreign item nói chung cần được gọi hoặc truy cập theo cách unsafe trừ khi được khai báo rõ là safe.39

Tuy nhiên, không nên đồng nhất FFI với sự phụ thuộc cấu trúc mang tính phổ quát vào C ABI. ABI "C" là một đường tương tác rất quan trọng và cũng là mặc định khi external block bỏ qua chuỗi ABI, nhưng Rust còn định nghĩa những ABI khác như "system""C-unwind"; chức năng cấp thấp cũng có thể được hiện thực qua unsafe operation hoặc giao diện đặc thù nền tảng ngoài FFI. Một hệ thống thực tế dùng C ABI đến mức nào là thuộc tính của hệ điều hành, thư viện, phần cứng và kiến trúc tích hợp của hệ thống đó. Ranh giới ở cấp ngôn ngữ trong Rust không phải đơn giản là “có dùng C”, mà là ai bảo đảm một hợp đồng bên ngoài mà trình biên dịch không thể xác minh, và dựa trên cơ sở nào.39

Ở quy mô lớn, khác biệt này liên quan trực tiếp đến khả năng bảo trì và cô lập lỗi. Một FFI wrapper có thể cô lập rủi ro bằng cách xác minh tính hợp lệ của pointer, độ dài, ownership, lifetime, aliasing, ABI, quy ước error và unwind tại một ranh giới nội bộ hẹp, rồi chỉ cung cấp sound safe API ra bên ngoài. Ngược lại, nếu unsafe bên trong safe API, thư viện bên ngoài hoặc khai báo ABI sai, ngay cả call site chỉ viết bằng Safe Rust vẫn có thể bị ảnh hưởng. Vì vậy, điểm mạnh của Safe Rust không phải là loại bỏ mọi nghĩa vụ chưa được xác minh, mà là có thể cô lập nhiều nghĩa vụ khỏi safe caller và tập trung chúng vào các ranh giới hẹp.

3.2.3 “Thất bại an toàn” và ý nghĩa của panic

Không chính xác nếu định nghĩa panic như một mô hình “thất bại an toàn (safe failure)” phổ quát duy nhất. Khi một safe operation đã được định nghĩa phát hiện điều kiện lỗi rồi panic, như kiểm tra biên trong indexing array an toàn, bản thân panic đó không phải UB. Tuy nhiên, chương trình và dịch vụ sau đó hoạt động thế nào phụ thuộc vào panic strategy và cấu trúc cô lập.

Cargo và rustc về cơ bản phân biệt panic strategy thành unwindabort. Với unwind, panic tháo stack và có thể thực hiện dọn dẹp dọc theo đường đó; với abort, process kết thúc. Strategy thực tế có thể thay đổi theo nền tảng đích và cấu hình build, vì vậy không nên khái quát rằng “panic mặc định luôn tháo stack và chỉ kết thúc thread hiện tại”. Rộng hơn, bản thân hợp đồng an toàn của Rust cũng không bảo đảm mọi destructor nhất thiết phải được thực thi.40

std::panic::catch_unwind cũng không phải bảo đảm xử lý ngoại lệ hay phục hồi dịch vụ nói chung. Hàm này chỉ bắt unwinding panic và không thể bắt aborting panic. Tài liệu thư viện chuẩn nêu rằng Result phù hợp hơn với thất bại có thể xảy ra trong hoạt động thông thường và không khuyến nghị dùng catch_unwind như một cơ chế try/catch tổng quát. Closure của nó còn chịu ranh giới UnwindSafe; khả năng mã chạy sau quan sát trạng thái chỉ được thay đổi một phần hoặc logical invariant đã bị phá trong lúc panic cũng phải được xử lý riêng.40

Ranh giới thread cũng không đồng nghĩa với “tự động phục hồi”. Với unwind, khi child thread panic, JoinHandle::join có thể quan sát thất bại đó dưới dạng Err, nhờ vậy thread có thể được thiết kế như một đơn vị cô lập. Nhưng để biến quan sát đó thành phục hồi dịch vụ thực tế, caller vẫn phải xử lý Err, xác minh tính nhất quán của trạng thái chia sẻ, và định nghĩa chính sách retry, loại bỏ hoặc restart cho công việc thất bại. Với panic = "abort", chính process có thể kết thúc; thiết kế unwrap kết quả join hoặc truyền panic lên ranh giới cao hơn cũng có thể làm gián đoạn dịch vụ.40

Vì vậy memory safety và availability là các thuộc tính khác nhau. Việc panic là control flow đã được định nghĩa chứ không phải UB tự nó không bảo đảm cô lập request, ranh giới thread/process, supervisor và restart, phục hồi trạng thái, retry policy hay phạm vi lan truyền lỗi được giới hạn. Với server chạy dài hạn và hệ thống embedded hoặc mission-critical, cần thiết kế riêng panic strategy, execution boundary mà lỗi có thể truyền tới, và cách khôi phục dịch vụ sau đó.

3.2.4 Vấn đề rò rỉ bộ nhớ “an toàn”

Rust Reference nêu rõ rò rỉ bộ nhớ và các tài nguyên khác thuộc những hành vi không được xem là unsafe. Ở đây “safe” không có nghĩa là tốt về vận hành hay không có thất bại; nó chỉ có nghĩa là bản thân leak không phải UB vi phạm memory-safety contract của Rust.41

Ranh giới này đặc biệt rõ trong hàm std::mem::forget của thư viện chuẩn. mem::forget là hàm safe nhận ownership của một giá trị rồi quên nó mà không chạy destructor. Tài liệu giải thích hàm này không cần là unsafe vì safety guarantee của Rust không bao gồm việc destructor bắt buộc phải chạy, đồng thời nêu reference cycle của Rc<T> và việc process kết thúc như các trường hợp khác mà destructor có thể không chạy. Rust Book cũng giải thích reference cycle tạo bởi Rc<T>RefCell<T> có thể làm rò rỉ bộ nhớ trong Safe Rust.41

Đây không chỉ là vấn đề thuật ngữ. Heap memory, file descriptor, socket, lock và các tài nguyên hữu hạn liên quan bị rò rỉ có thể gây cạn tài nguyên, tăng latency, request thất bại và cuối cùng làm gián đoạn dịch vụ trong process chạy dài hạn. Vì vậy một leak memory-safe không phải một hành vi availability-safe. Ở quy mô lớn và trong vận hành dài hạn, không chỉ bộ nhớ mà cả descriptor, connection, task và queue đều cần invariant riêng cho giới hạn trên và đường thu hồi.

Phần hiện thực unsafe cũng không được để soundness phụ thuộc vào giả định rằng “caller cuối cùng sẽ chạy Drop”. Safe caller có thể dùng mem::forget, và process có thể kết thúc mà không chạy destructor. Nguyên tắc này cho thấy ranh giới an toàn của Rust rộng hơn một mô tả RAII đơn giản và resource lifecycle phải được phân biệt với memory-safety proof obligation.

3.2.5 Các vấn đề ngoài phạm vi bảo đảm: Lỗi logic, bế tắc và những vấn đề khác

Bảo đảm mạnh của Safe Rust không tự động mở rộng sang mọi thuộc tính correctness, security và availability. Rust Reference không xem deadlock và memory/resource leak là unsafe; việc safe code vi phạm một điều kiện logic bổ sung có thể dẫn đến panic, kết quả tính toán sai, abort hoặc non-termination nhưng không vì thế mà trở thành UB.42

Đặc biệt, cần phân biệt data race với race condition nói chung. data race là UB trong Rust và là một loại trung tâm mà Safe Rust ngăn chặn. Tuy nhiên borrow checker không loại bỏ mọi race condition mà kết quả phụ thuộc vào thứ tự thực thi, cũng không tự động loại bỏ TOCTOU, protocol state transition sai, livelock hay starvation. Rustonomicon cũng phân biệt bảo đảm Safe Rust không có data race với thực tế rằng nó không ngăn race condition nói chung.43

Tràn số nguyên cũng cần được xét cẩn thận theo cùng ranh giới. Rust Reference xem arithmetic overflow là lỗi của lập trình viên nhưng không trực tiếp phân loại nó là UB. Khi debug_assert! được bật, phần hiện thực phải chèn kiểm tra động và panic khi overflow; ở build khác, phần hiện thực có thể panic hoặc wrapping ngầm. Khi wrapping ngầm xảy ra, kết quả được định nghĩa theo quy tắc two’s-complement. Cargo profile điều khiển kiểm tra overflow runtime qua overflow-checks, vì vậy rút gọn hành vi thành quy tắc cố định “debug thì panic, release luôn wrapping” là không chính xác.42

Lỗ hổng bảo mật cũng rộng hơn memory safety. CVE-2024-24576 do Rust Security Response WG công bố năm 2024 liên quan đến việc escape đối số không đầy đủ khi std::process::Command thực thi batch file trên Windows; trong điều kiện kẻ tấn công kiểm soát argument không đáng tin cậy, khiếm khuyết có thể dẫn đến thực thi shell command tùy ý. API này có thể được gọi qua safe code, nhưng nguyên nhân cốt lõi không phải memory corruption mà là khiếm khuyết logic trong xử lý command argument và API contract. Vấn đề ban đầu được sửa trong Rust 1.77.2. Sau đó một vấn đề sửa chưa đầy đủ riêng biệt, CVE-2024-43402, được báo cáo: trailing whitespace và period có thể vượt qua biện pháp giảm thiểu; vấn đề được bổ sung sửa trong Rust 1.81.0.44

Kết luận có thể rút ra từ các trường hợp này là có giới hạn. Việc một số phiên bản cũ cụ thể của thư viện chuẩn từng có khiếm khuyết bảo mật logic không cho biết tần suất lỗ hổng của toàn bộ hệ sinh thái Rust hay rủi ro của phiên bản hiện tại. Ngược lại, việc memory-safety contract của Safe Rust mạnh cũng không phải bằng chứng rằng command injection, lỗi xác thực hoặc phân quyền, protocol bug, resource exhaustion, deadlock, state transition sai hay thất bại phục hồi dịch vụ tự động biến mất.

Kết luận tạm thời

Ưu điểm kỹ thuật quan trọng của Safe Rust là, bên trong ranh giới abstraction sound, nó cưỡng chế để safe caller không thể gây một số loại UB và data race xác định. Bảo đảm này không gộp compiler correctness, soundness của unsafe implementation, contract của FFI và hệ thống bên ngoài, race condition nói chung, tính đúng logic, giới hạn tài nguyên, cô lập panic và phục hồi dịch vụ thành một bảo đảm duy nhất. “memory safety”, “security”, “correctness”, “availability” và “resilience” có thể liên quan với nhau nhưng không nên được đánh giá như cùng một thuộc tính. Sự phân biệt này là tiêu chí để so sánh ngôn ngữ khác và chiến lược thay đổi ở mục kế tiếp; tự nó không chứng minh tính ưu việt của bất kỳ chiến lược di chuyển ngôn ngữ nào.

3.3 Phân tích so sánh 1: An toàn nhiều lớp trong C/C++ và chiến lược thay đổi

Câu hỏi của mục này không phải là “có nên thay C/C++ bằng Rust hay không”, mà là nên chọn hoặc kết hợp chiến lược thay đổi nào khi xét mô hình khiếm khuyết và tài sản của hệ thống hiện có, rủi ro chuyển đổi và yêu cầu bảo đảm. Các bảo đảm của Safe Rust đã xác lập ở Mục 3.2 là một đầu vào quan trọng cho lựa chọn ngôn ngữ, nhưng chỉ các bảo đảm đó không quyết định được bảo trì, hiện đại hóa, thay thế có chọn lọc, phát triển mới hay viết lại toàn bộ là chiến lược tối ưu.

Khi so sánh chiến lược thay đổi, cần tách ít nhất hai loại hiệu quả. Một là hiện thực sau thay đổi có thể phòng ngừa, phát hiện hoặc giảm nhẹ những khiếm khuyết nào. Hai là bản thân thay đổi tạo ra chi phí phục hồi đặc tả, tương thích, triển khai, quay lui, vận hành kép, nhân lực và bảo trì dài hạn nào. Loại thứ nhất là vấn đề chất lượng của trạng thái đích; loại thứ hai là rủi ro của quá trình chuyển đổi. Chỉ tính một phía có thể đánh giá quá cao giá trị của bảo đảm ngôn ngữ hoặc tài sản hiện có.

3.3.1 Phân biệt tái cấu trúc, hiện đại hóa và viết lại

Cuốn sách này phân biệt các chiến lược thay đổi như sau. Đây là các định nghĩa làm việc để làm rõ đơn vị so sánh của mục này, không phải một hệ phân loại phổ quát cho mọi phương pháp luận.

  • Bảo trì và gia cố khiếm khuyết: Sửa lỗi và tăng cường xác thực đầu vào, cô lập, hardening, kiểm thử và khả năng quan sát mà không thay hiện thực hiện có hoặc hành vi bên ngoài của nó.
  • Tái cấu trúc: Cải thiện cấu trúc bên trong trong khi giữ nguyên hành vi quan sát được từ bên ngoài. Martin Fowler cũng định nghĩa refactoring là thay đổi cấu trúc bên trong mà không làm thay đổi hành vi quan sát được.45
  • Hiện đại hóa: Hoạt động rộng hơn, cải thiện tính năng và thư viện ngôn ngữ, công cụ build và phân tích, API, ranh giới mô-đun, cấu trúc triển khai và các yếu tố liên quan. Khi cần, nó có thể chủ ý thay đổi hành vi bên ngoài hoặc cách vận hành.
  • Thay thế có chọn lọc: Thay một số thành phần có rủi ro hoặc giá trị thay đổi cao bằng hiện thực mới trong khi giữ chúng cùng tồn tại với phần còn lại của hệ thống. Có thể đổi ngôn ngữ hoặc hiện thực lại bằng cùng ngôn ngữ.
  • Áp dụng cho thành phần mới: Viết chức năng hoặc dịch vụ mới bằng ngôn ngữ khác mà không thay hiện thực hiện có.
  • Viết lại toàn bộ: Thay một phạm vi rộng của hiện thực hiện có bằng hiện thực mới. Vì di chuyển ngôn ngữ cũng có thể chỉ diễn ra một phần, “di chuyển ngôn ngữ” và “viết lại toàn bộ” cũng không phải từ đồng nghĩa.

Vì vậy, “viết lại C/C++ bằng Rust” không phải từ đồng nghĩa với tái cấu trúc. Nó có thể là thay thế có chọn lọc, viết lại toàn bộ hoặc một hình thức của di chuyển ngôn ngữ rộng hơn. Ngược lại, áp dụng Rust cũng không nhất thiết đồng nghĩa với viết lại: có thể chỉ viết thành phần mới bằng Rust, hoặc thay một mô-đun rủi ro cao có ranh giới hẹp trong khi giữ hệ thống C/C++ xung quanh.

3.3.2 Giá trị thực tiễn của tái cấu trúc và hiện đại hóa trong C/C++

Các cơ chế cải thiện của C và C++ không thể quy về một bảo đảm ngôn ngữ duy nhất tương đương Safe Rust. Quy tắc thiết kế, thành ngữ kiểu và quản lý tài nguyên, phân tích tĩnh, instrumentation thời gian chạy, kiểm thử và fuzzing, cô lập và exploit mitigation hoạt động ở các lớp khác nhau. Vì vậy cần phân biệt phòng ngừa (prevention), phát hiện (detection) và giảm nhẹ (mitigation).

C++ Core Guidelines khuyến nghị quản lý tài nguyên tự động bằng RAII và resource handle, biểu diễn ownership bằng unique_ptrshared_ptr, cùng biểu diễn phạm vi như span. Đồng thời, Guidelines được thiết kế để có thể áp dụng dần vào cơ sở mã hiện có, và ngôn ngữ không tự cưỡng chế mọi quy tắc. clang-tidy cũng cung cấp các kiểm tra có thể chọn như cppcoreguidelines-*, clang-analyzer-*bugprone-*, nhưng phạm vi bị giới hạn ở các mẫu mà phân tích đã bật có thể chẩn đoán.46

Tính chất của công cụ động còn rõ hơn. AddressSanitizer của Clang phát hiện nhiều loại lỗi bộ nhớ—gồm truy cập ngoài biên heap, stack và global, use-after-free và invalid free—trong các lần thực thi được instrumentation, còn ThreadSanitizer phát hiện data race. UndefinedBehaviorSanitizer tương tự chèn kiểm tra UB đã chọn ở thời gian chạy. Đây là công cụ mạnh để tìm khiếm khuyết C/C++, nhưng không phải chứng minh cấp ngôn ngữ rằng lỗi vắng mặt trên cả những đường chạy chưa được thực thi.

Chúng cũng có chi phí: tài liệu Clang hiện tại mô tả overhead thời gian chạy điển hình của AddressSanitizer khoảng 2 lần, còn ThreadSanitizer khoảng 5–15 lần thời gian chạy và khoảng 5–10 lần bộ nhớ. Runtime ASan và TSan cũng không được thiết kế để liên kết vào production executable, và tài liệu cảnh báo việc dùng trong production ở môi trường nhạy cảm bảo mật có thể tự tạo thêm rủi ro.

Vì vậy hệ thống quy mô lớn, tải cao và thời gian thực cần tách ranh giới triển khai theo từng công cụ: runtime phát hiện như ASan và TSan chủ yếu đặt trong CI và kiểm thử, còn canary hoặc production nên dùng instrumentation hay mitigation đã được xác minh riêng là phù hợp với môi trường đó.46

Mã C cũng có thể giảm rủi ro bằng contract allocator/free, buffer interface mang độ dài, một quy tắc ownership duy nhất, foreign interface hẹp, phân tích tĩnh và động, cùng fuzzing. Tuy nhiên, nếu các quy tắc này phụ thuộc convention của tổ chức, API discipline hoặc cấu hình toolchain cụ thể, vị trí và độ mạnh của bảo đảm sẽ khác contract cấp ngôn ngữ do sound Safe Rust interface cung cấp.

Lớp Phương tiện tiêu biểu Hiệu quả chính Giới hạn bảo đảm hoặc vận hành
Thiết kế, kiểu và quản lý tài nguyên RAII, smart pointer, span, contract ownership/length rõ ràng Thu hẹp phạm vi thao tác lifetime và buffer rủi ro raw pointer, legacy API, FFI và đường đi bỏ qua quy tắc vẫn cần quản lý riêng
Phân tích tĩnh clang-tidy, Clang Static Analyzer và công cụ tương tự Chẩn đoán sớm khiếm khuyết và vi phạm quy tắc ở nguồn mà phân tích đã bật có thể suy ra Phụ thuộc kiểm tra được bật và độ chính xác phân tích; không phải bảo đảm vắng lỗi cho toàn ngôn ngữ
Phân tích động ASan, TSan, UBSan Phát hiện khiếm khuyết memory/UB/data-race đã chọn trong lần chạy được instrumentation Phụ thuộc đường chạy và môi trường, đồng thời tốn thời gian và bộ nhớ
Kiểm thử và fuzzing Kiểm thử hồi quy, property-based test, coverage-guided fuzzing Xác minh hành vi hiện có và điều kiện biên bằng thực thi Có thể bỏ sót khi test oracle hoặc coverage không đầy đủ
Cô lập và hardening sandbox, memory tagging, hardened allocator, exploit mitigation Giảm khả năng tiếp cận, tác động hoặc khai thác khiếm khuyết Không loại bỏ mọi khiếm khuyết và có thể tăng chi phí hiệu năng, bộ nhớ hoặc vận hành

Việc cách tiếp cận nhiều lớp này không cung cấp bảo đảm giống Safe Rust là quan trọng. Nhưng bảo đảm yếu hơn hoặc nằm ở lớp khác không đồng nghĩa với hiệu quả kỹ thuật bằng không. Ngược lại, dùng nhiều sanitizer và guideline cũng không tự khiến mã C/C++ có cùng memory-safety contract như Safe Rust.

Tài liệu Android hiện tại cũng dùng phân biệt này làm chiến lược vận hành. AOSP cho biết Rust được ưu tiên cho phần lớn native project mới, đồng thời nói rõ rằng viết lại toàn bộ mã memory-unsafe hiện có bằng Rust là không thực tế và Rust bổ sung cho memory-safety tooling. C/C++ hiện có tiếp tục dùng phát hiện và hardening như HWASAN, KASAN, GWP-ASan và memory tagging.47 Trường hợp này cho thấy cải thiện C/C++ và áp dụng Rust không phải hai lựa chọn đối nghịch, mà có thể cùng tồn tại trong giai đoạn chuyển đổi quy mô lớn. Tuy nhiên, nó không chứng minh cấu trúc mã và phân bố lỗ hổng của Android có thể khái quát sang dự án khác.

3.3.3 Bảo đảm được thêm bởi việc viết lại bằng Rust và rủi ro mới phát sinh

Trong phạm vi được viết mới hoặc thay bằng Rust, memory-safety contract của Safe Rust theo Mục 3.2 có thể trở thành mặc định thiết kế. Đây là lợi thế mạnh, khác với phát hiện bằng guideline hoặc sanitizer. Phòng ngừa cấp ngôn ngữ đặc biệt có giá trị khi khiếm khuyết memory-safety có tác động lớn, ranh giới unsafe và FFI có thể giữ hẹp, và tổ chức có năng lực duy trì thành phần trong suốt vòng đời dự kiến.

Tuy nhiên, bảo đảm của trạng thái đích bằng ngôn ngữ và viết lại như một phương pháp thay đổi là hai đơn vị phân tích khác nhau. Viết lại yêu cầu hiện thực mới phải đáp ứng lại hành vi cần thiết, tính tương thích, đặc tính hiệu năng và contract vận hành của hệ thống hiện có. Như Martin Fowler chỉ ra khi thảo luận thay thế dần, hành vi thực tế của hệ thống lâu đời có thể chứa đặc tả chi tiết hơn nhiều so với điều được hình dung khi bắt đầu thay thế, còn một cut-over lớn có thể tập trung rủi ro vào một sự kiện. Strangler Fig của ông là một replacement pattern dần dần xuất phát từ các mối lo này, không phải định luật thực nghiệm rằng thay từng phần luôn tốt hơn ở mọi hệ thống.48

Thay ngôn ngữ do đó tạo ra các câu hỏi xác minh riêng.

  1. Đặc tả hành vi và test oracle: Dự án phải quyết định legacy behavior nào bắt buộc giữ và behavior nào chủ ý loại bỏ. Nếu kiểm thử hiện có không đủ, ngay cả ý nghĩa “tương đương” của hiện thực mới cũng có thể mơ hồ.
  2. Interop và safety boundary: Cùng tồn tại với C/C++, giao diện hệ điều hành, driver hoặc library hiện có đòi hỏi xác định lại contract FFI, ABI, ownership, error và unwind. Giới hạn ở Mục 3.2 vẫn còn: một ranh giới unsound có thể ảnh hưởng caller được viết hoàn toàn bằng Safe Rust.
  3. Triển khai, rollback và tương thích trạng thái: Chuyển đổi song song hoặc theo giai đoạn đòi hỏi thiết kế rõ tương thích protocol, data format, persistent state và rollback.
  4. Xác minh lại hiệu năng và độ trưởng thành vận hành: Hiện thực mới phải được xác minh lại trên workload đích không chỉ về hiệu năng trung bình mà cả tail latency, peak memory, startup, failure mode, rare input, observability và recovery behavior.
  5. Chi phí tổ chức dài hạn: Tổ chức phải đánh giá liệu có thể duy trì hai ngôn ngữ và toolchain, dependency, build, debugging, code review, tuyển dụng và đào tạo trong giai đoạn chuyển đổi hoặc thời kỳ cùng tồn tại dài hơn hay không.

Android là một trường hợp tiêu biểu xử lý vấn đề này bằng chuyển đổi dần lấy interop làm trung tâm. Nhóm Android đánh giá việc viết lại toàn bộ C++ là không thực tế và phân tích khả năng cùng tồn tại giữa mã hiện có với Rust như một điều kiện thực tiễn. Trường hợp firmware năm 2024 ưu tiên mã mới và mã hiện có có rủi ro bảo mật cao, đồng thời mô tả đường thay thế có chọn lọc qua thin Rust shim giữ nguyên C API hiện có.49 Điều này cho thấy áp dụng từng phần có thể là chiến lược thực tế trong hệ thống lớn. Tuy nhiên, phân tích interop năm 2021 đánh giá tính tương thích và tính thực tiễn bằng exported C++ API và type thực sự dùng trong Android platform; nó không phải bằng chứng phổ quát đo chi phí interface hoặc mức phù hợp của mọi cơ sở mã.

Các trường hợp này cũng không biện minh cho khái quát ngược rằng “full rewrite luôn sai”. Nhóm Android đã viết lại protected-VM firmware của Android Virtualization Framework bằng Rust để tạo memory-safe foundation cho pVM root of trust.50 Viết lại ở cấp thành phần có thể hợp lý khi ranh giới có lợi ích bảo đảm cao tương đối hẹp, yêu cầu và phạm vi xác minh có thể kiểm soát, và ít lý do phải giữ chính cấu trúc hiện có.

Vì vậy thay ngôn ngữ không chỉ đơn giản loại bỏ rủi ro mà thay đổi loại và vị trí của rủi ro. Di chuyển một phạm vi hữu hạn sang sound Safe Rust có thể giảm rủi ro memory-safety xác định, nhưng phạm vi chuyển đổi càng lớn thì càng phải đồng thời kiểm soát phục hồi đặc tả, interop, triển khai, rollback, độ trưởng thành vận hành và năng lực tổ chức. Hiệu quả ròng cần được đánh giá bằng cách so sánh hai loại rủi ro trên cùng tiêu chuẩn, không phải chỉ bằng số dòng mã.

3.3.4 Dải liên tục của chiến lược thay đổi và áp dụng có chọn lọc

Dự án thực tế không cần chọn các chiến lược sau như các phương án loại trừ lẫn nhau. Một hệ thống có thể giữ và harden mô-đun C++ trưởng thành, viết native component mới bằng Rust, chỉ thay có chọn lọc parser rủi ro cao xử lý untrusted input, và viết lại một subsystem nhỏ có cấu trúc đã hết vòng đời hữu ích.

Chiến lược thay đổi Điều kiện cần kiểm tra trước Hiệu quả chính có thể đạt Rủi ro chuyển đổi và vận hành chính
Giữ hiện thực hiện tại và gia cố khiếm khuyết Khiếm khuyết cục bộ và rủi ro thay đổi lớn hơn Phạm vi chuyển đổi nhỏ nhất, giữ tài sản hành vi hiện có Nợ cấu trúc và vùng memory-unsafe có thể còn lại
Hiện đại hóa trong C/C++ Có thể cải thiện ownership, boundary và xác minh trong khi giữ tài sản hành vi Giảm rủi ro dần và rollback nhanh Độ đầy đủ của áp dụng quy tắc và công cụ phụ thuộc toolchain và kỷ luật tổ chức
Viết thành phần mới bằng Rust Chức năng mới không cần hiện thực lại hành vi cũ Áp dụng mặc định Safe Rust cho mã mới mà không có hồi quy do viết lại Chi phí tích hợp với API, build và runtime hiện có
Thay có chọn lọc mô-đun rủi ro cao bằng Rust Rủi ro khiếm khuyết tập trung ở interface hẹp Tập trung lợi ích bảo đảm nơi rủi ro cao Chi phí FFI/ABI và dual-language lifecycle
Viết lại toàn bộ hoặc phạm vi rộng Chính architecture hiện có cản yêu cầu, đồng thời đặc tả, test oracle và tài nguyên chuyển đổi đủ Thiết kế lại cùng lúc architecture và implementation model Phạm vi lớn nhất của hồi quy, cut-over, rollback, tiến độ và rủi ro tổ chức

Trước khi chọn chiến lược, ít nhất cần làm rõ các câu hỏi sau.

  1. Mô hình khiếm khuyết: Vấn đề thực sự cần giảm là memory safety như use-after-free hoặc data race, hay lỗi logic, tính sẵn sàng, hiệu năng hoặc độ phức tạp vận hành?
  2. Phân bố khiếm khuyết: Rủi ro tập trung ở mã mới thay đổi hoặc parser, driver, protocol boundary cụ thể, hay phân bố khắp hệ thống?
  3. Tài sản đặc tả và xác minh: Đặc tả hành vi, regression test, corpus, fuzz target, benchmark và production telemetry có đủ để đánh giá hiện thực mới không?
  4. Ranh giới và khả năng cùng tồn tại: Interface mô-đun có đủ hẹp để nêu rõ contract ownership, lifetime, error và state không?
  5. Triển khai và rollback: Có thể partial rollout, shadow/canary, rollback về hiện thực cũ và duy trì data/state compatibility không?
  6. Ngân sách hiệu năng và tài nguyên: Có đáp ứng không chỉ throughput mà cả tail latency, worst-case behavior, memory, code size, startup, energy và chi phí build/test không?
  7. Yêu cầu bảo đảm: Quy định, threat model hoặc assurance case có yêu cầu prevention cấp ngôn ngữ hay formal proof mạnh hơn convention và detection không?
  8. Tổ chức và vòng đời: Có nhân lực và quy trình để rà soát, gỡ lỗi, cập nhật hai toolchain và hai ngôn ngữ trong giai đoạn chuyển đổi hoặc cùng tồn tại dài hạn không?

Câu trả lời khác nhau có thể khiến các chiến lược khác nhau đều hợp lý ngay trong cùng một cơ sở mã. Cách tiếp cận chính thức của Android kết hợp mã memory-safe mới, hardening C/C++ hiện có, interop và thay thế có chọn lọc vùng rủi ro cao là một ví dụ về chiến lược hỗn hợp như vậy.47 Đây không phải bằng chứng rằng “áp dụng dần luôn tốt nhất”, mà là bằng chứng về khả năng rằng viết lại toàn bộ không phải con đường duy nhất để cải thiện memory safety.

Chỉ số đánh giá cũng không nên dừng ở lựa chọn ngôn ngữ. Tỷ lệ tái diễn và severity của khiếm khuyết đích, hồi quy chức năng, tail latency và resource ceiling, thời gian build/test, thời gian phục hồi sự cố, thành công rollback, độ phức tạp vận hành và chi phí duy trì dependency, tooling phải được đo với cùng định nghĩa trước và sau thay đổi. Nếu không đo mà kết luận “an toàn hơn” hoặc “dễ bảo trì hơn”, ta lại trộn bảo đảm ngôn ngữ với kết quả dự án thực tế.

3.3.5 Phân tích lập luận: “Tái cấu trúc có ý nghĩa duy nhất là viết lại bằng Rust”

Câu sau không phải trích dẫn trực tiếp từ một cá nhân cụ thể hay từ Rust Project. Đây là mệnh đề phân tích tổng hợp dùng để kiểm tra cấu trúc lập luận rằng cải thiện có ý nghĩa duy nhất cho C/C++ là viết lại bằng Rust.

Ví dụ tổng hợp: “Tái cấu trúc C/C++ là viết lại bằng Rust; mọi tái cấu trúc khác đều vô nghĩa.”

Nếu xem đây là mệnh đề tổng quát, nó có các vấn đề sau.

  1. Lỗi phạm trù: Nó định nghĩa refactoring, vốn giữ hành vi quan sát được, là cùng công việc với rewrite thay hiện thực.
  2. Lưỡng phân giả: Nó nén không gian lựa chọn thực tế—bảo trì và hardening, hiện đại hóa cùng ngôn ngữ, mã Rust mới, thay thế có chọn lọc, viết lại phạm vi rộng—thành chỉ “bỏ mặc” và “full rewrite”.
  3. Ngụy biện giải pháp hoàn hảo (nirvana fallacy): Vì công cụ và hiện đại hóa C/C++ không cung cấp cùng memory-safety guarantee như Safe Rust, nó coi cả hiệu quả cục bộ về phát hiện khiếm khuyết, giảm tác động và cải thiện khả năng bảo trì bằng không.
  4. Trộn bảo đảm với kết quả: Nó có nguy cơ đồng nhất contract cấp ngôn ngữ của Safe Rust với kết quả security, availability, correctness và maintainability toàn hệ thống sau migration.
  5. Bỏ sót chi phí chuyển đổi: Nó loại phục hồi đặc tả, FFI/ABI, dual-language build, rollout, rollback, tương thích data/protocol và học tập tổ chức khỏi so sánh.
  6. Tiêu chuẩn bằng chứng bất đối xứng: Nếu yêu cầu cải thiện C/C++ phải chứng minh loại bỏ hoàn toàn khiếm khuyết, nhưng coi bảo đảm ngôn ngữ Rust là đủ để chứng minh thành công toàn dự án sau chuyển đổi, hai chiến lược đang được đánh giá bằng tiêu chuẩn bằng chứng khác nhau.

Cũng cần tránh khái quát ngược. “Nếu hiện đại hóa C/C++ đủ tốt thì không có lý do chuyển bất cứ thứ gì sang Rust” cũng không đúng phổ quát. Nếu khiếm khuyết memory-safety là threat chính, process và testing không thể hạ rủi ro xuống mức chấp nhận được, hoặc yêu cầu assurance đòi hỏi prevention mạnh hơn, bảo đảm cưỡng chế của Safe Rust có thể là lý do quan trọng để biện minh thay thế có chọn lọc hoặc viết lại.

Kết luận trung gian

Kết luận của Mục 3.3 không phải ngôn ngữ nào luôn vượt trội, mà là bảo đảm ngôn ngữ và chiến lược thay đổi phải được đánh giá riêng. Safe Rust cung cấp một mặc định mạnh ngăn UB và data race xác định trong ranh giới sound, và đây là khác biệt thật về mức bảo đảm so với guideline, phân tích và testing của C/C++. Tuy vậy, tái cấu trúc, hiện đại hóa và hardening C/C++ hiện có vẫn có thể giảm rủi ro thực ở các lớp khác; trong hệ thống lớn hiện hữu, chúng có thể được kết hợp với áp dụng Rust mới và thay thế có chọn lọc.

Do đó, bảo trì, hiện đại hóa, áp dụng Rust cho mã mới, thay thế có chọn lọc hay viết lại toàn bộ phù hợp đến đâu phụ thuộc vào mô hình khiếm khuyết, yêu cầu bảo đảm, tài sản hành vi hiện có, interface và testability, khả năng rollout và rollback, giới hạn hiệu năng và tài nguyên, năng lực tổ chức và tổng chi phí vòng đời. Nếu không nêu các điều kiện này, cả hai mệnh đề phổ quát—“chỉ Rust rewrite mới có ý nghĩa” và “cải thiện C/C++ hiện có là đủ”—đều mạnh hơn bằng chứng hiện có.

3.4 Phân tích so sánh 2: Chứng minh toán học và mức bảo đảm của Ada/SPARK

Câu hỏi của mục này không phải là “Ada/SPARK có an toàn hơn Rust hay không”, mà là mỗi công nghệ phòng ngừa, phát hiện hoặc chứng minh thuộc tính nào, ở giai đoạn nào và dưới điều kiện nào, và các bảo đảm đó kết thúc ở đâu. Để so sánh với memory-safety contract của Safe Rust đã xác lập ở Mục 3.2, không thể gộp kiểu, run-time check và xử lý ngoại lệ của Ada với tập con ngôn ngữ bị giới hạn, flow analysis và proof của SPARK thành một “mức an toàn” duy nhất.

Đơn vị so sánh cũng phải được tách riêng. Trọng tâm của Safe Rust là dùng quy tắc ngôn ngữ để phòng ngừa UB và data race xác định bên trong một sound safe interface. Ada cung cấp strong typing, language-defined run-time check, cấu trúc đồng thời và đồng bộ hóa, cùng cơ chế xử lý ngoại lệ. SPARK đặt thêm hạn chế và contract lên tập con Ada có thể phân tích, rồi dùng GNATprove để dần dần xác minh tĩnh flow property, sự vắng mặt của run-time error, integrity property và functional contract.51 Ba mô hình khác nhau về thuộc tính được bảo đảm, thời điểm bảo đảm, điều kiện tiên quyết và chi phí.

Ada: Phát hiện lúc chạy và xử lý ngoại lệ không phải bảo đảm phục hồi tự động

Ada 2022 yêu cầu run-time check cho nhiều language-defined condition như array index, scalar range, signed integer overflow và null access; khi kiểm tra thất bại, ngoại lệ như Constraint_Error được phát sinh. Overflow của signed integer cũng được phân biệt với wraparound đã được định nghĩa của modular integer. Khi ngoại lệ phát sinh, phần còn lại của chuỗi thực thi hiện tại bị bỏ qua và quyền điều khiển chuyển đến handler phù hợp; nếu không có handler cục bộ, ngoại lệ lan truyền theo quy tắc ngôn ngữ.52

Đây là một lớp phòng vệ quan trọng khác với unchecked memory access trong C. Nhưng “lỗi được phát hiện dưới dạng ngoại lệ” và “hệ thống phục hồi” không phải cùng một bảo đảm. Handler có khôi phục trạng thái an toàn hay không, chỉ cô lập request thất bại hay không, có khởi động lại task hoặc process hay không, persistent state có giữ nhất quán hay không, và có đáp ứng deadline hoặc yêu cầu failover hay không đều phải được chương trình và kiến trúc hệ thống bảo đảm riêng. Exception mechanism của Ada cung cấp phương tiện để biểu đạt và thực thi recovery policy; bản thân ngôn ngữ không bảo đảm service availability hay mission continuity.

Dynamic check của Ada cũng có ranh giới. Suppress có thể cho phép bỏ qua language-defined check; nếu thực thi đi vào tình huống mà kiểm tra bị suppress vốn phải thất bại, tiêu chuẩn có thể phân loại thực thi đó là erroneous. Unchecked_Deallocation, Unchecked_Access, Unchecked_Conversion, hay access value hoặc representation không hợp lệ đi vào qua external interface cũng tạo nghĩa vụ xác minh riêng.52 Vì vậy, tóm tắt Ada thành “tự động bảo đảm mọi memory error đều vắng mặt” là không chính xác.

SPARK: “Có thể dùng xác minh hình thức” khác với “toàn bộ chương trình đã được chứng minh”

SPARK không phải toàn bộ Ada mà là một tập con ngôn ngữ hạn chế một số tính năng để có thể phân tích hình thức. SPARK User’s Guide hiện tại phân biệt các assurance level như sau.51

Mức Mục tiêu xác minh chính Ý nghĩa trong mục này
Stone Kiểm tra mã thuộc tập con SPARK hợp lệ Thiết lập ranh giới ngôn ngữ có thể phân tích, không đồng nghĩa chương trình đúng
Bronze Khởi tạo và data flow đúng Loại bỏ tĩnh uninitialized read và một số lỗi parameter/global interference
Silver Absence of Run-Time Errors (AoRTE) Chứng minh trong phạm vi đã phân tích rằng run-time error gây ngoại lệ bất ngờ như Constraint_Error hoặc assertion failure không xảy ra
Gold Chứng minh key integrity property Chứng minh các thuộc tính an toàn/toàn vẹn cốt lõi được nêu rõ, như invariant và state transition
Platinum Hình thức hóa và chứng minh functional requirement Chứng minh implementation thỏa specification trong phạm vi contract biểu đạt đầy đủ functional requirement

Vì vậy, câu “SPARK chứng minh toán học sự vắng mặt của run-time error” cần điều kiện rằng phạm vi phân tích và các proof obligation thực sự đã được khép kín. Silver AoRTE có thể chứng minh không xảy ra nhiều run-time error gắn với Ada check như division by zero, buffer/index error và overflow, nhưng tài liệu chính thức nêu rõ Storage_Error nằm ngoài phạm vi phân tích của SPARK. Vùng Skip_Proof, SPARK_Mode => Off, mã Ada/C/assembly bên ngoài, imported data và hardware model cần assumption hoặc phương pháp xác minh riêng.53

Đồng thời: vắng data race khác với vắng race condition

Bản thân Ada cung cấp các cơ chế shared-state synchronization như protected object và atomic/volatile object, nhưng nói rằng Ada tự động chặn mọi data race lúc chạy là quá mạnh. Ada 2022 cho phép task đọc và ghi shared variable theo các quy tắc ngôn ngữ yêu cầu synchronization phù hợp, đồng thời định nghĩa semantics như read/update của atomic object là indivisible.52

Concurrent subset của SPARK hẹp hơn. Dưới profile Ravenscar hoặc Jorvik, chia sẻ giữa các task bị giới hạn ở synchronized object và GNATprove có thể chẩn đoán possible data race. Với Ravenscar trên một lõi, protected-object locking bị ràng buộc dùng Priority Ceiling Protocol để phòng deadlock; GNATprove cũng kiểm tra potentially blocking action bên trong protected subprogram và các hạn chế tasking khác. Tuy nhiên ví dụ atomic counter chính thức cho thấy ngay cả khi không có data race, hai task vẫn có thể đọc cùng một giá trị rồi ghi đè lẫn nhau, tạo lost-update race condition. Cần protected operation hoặc protocol invariant mạnh hơn để ngăn loại lỗi này.54

Project-wide tasking analysis hiện tại của GNATprove cũng có giới hạn phạm vi. Phân tích dùng context của các unit mà source file đang xử lý trực tiếp hoặc gián tiếp with; tài liệu ghi rõ vì thế một số tasking check có thể bị bỏ sót khi các task trong những library unit không liên kết với nhau cùng truy cập một resource.54 Do đó, bảo đảm data-race và deadlock được SPARK tài liệu hóa phải được đọc cùng profile được hỗ trợ, điều kiện single-core khi áp dụng, và context phân tích GNATprove thực tế. Phân biệt này cũng áp dụng cho Safe Rust ở Mục 3.2: ngăn data race không phải chứng minh rằng TOCTOU, state transition sai, deadlock, starvation hay các concurrency defect nói chung không tồn tại.

Ranh giới của proof: contract, assumption và hệ thống bên ngoài

Modular proof của GNATprove giả định contract của callee khi phân tích caller và xác minh contract đó khi phân tích callee body. Trong hệ thống thực tế không được phân tích hoàn toàn như SPARK, có thể còn assumption về non-SPARK Ada, C, assembly, device register, imported value, compiler và target behavior. Tài liệu SPARK yêu cầu quản lý các assumption còn lại qua --assumptions và review riêng, đồng thời cảnh báo assumption như pragma Assume có thể đưa lỗi vào verification process nên phải được biện minh cẩn thận.53

Do đó khi diễn giải proof result, tối thiểu phải ghi cùng thuộc tính nào được chứng minh, code scope nào được phân tích, contract nào đóng vai specification, assumption nào được tin cậy, và external environment cùng compiler/runtime/hardware được xác minh bằng cách nào. Một proof hoàn chỉnh đối với specification sai hoặc không đầy đủ không đồng nghĩa correctness hoàn chỉnh so với yêu cầu thực tế.

So sánh cơ chế bảo đảm

Thuộc tính Safe Rust Ada SPARK Ranh giới chính
Memory access và lifetime Phòng ngừa tĩnh UB xác định trong sound safe boundary Thực hiện language-defined check như index/range/null access nhưng không đưa ra một bảo đảm bao trùm rằng mọi dangling-access lifetime error đều vắng mặt Có thể chứng minh tĩnh AoRTE liên quan dưới pointer/aliasing model bị giới hạn và proof obligation unsafe/FFI của Rust, suppressed/unchecked operation của Ada, code và assumption ngoài SPARK
Biên mảng Safe indexing panic khi vượt biên; unchecked access là ranh giới unsafe Index_Check thất bại phát sinh ngoại lệ Có thể chứng minh như proof obligation rằng check không thể thất bại Code chưa proof và contract của input bên ngoài
Integer overflow Theo semantics riêng cho profile/operation nêu ở Mục 3.2 và tách khỏi memory safety Signed integer phát sinh ngoại lệ khi overflow check thất bại; modular integer có wraparound được định nghĩa Có thể chứng minh không có overflow-check failure trong phạm vi phân tích như AoRTE Storage_Error, resource bound riêng và external arithmetic assumption
Data race Được phòng ngừa trong sound Safe Rust Cung cấp synchronization construct nhưng không tự động phát hiện hoặc chặn mọi shared access Loại trừ tĩnh data race trong concurrent subset được hỗ trợ General race condition và protocol bug là vấn đề riêng
General concurrency correctness Không bảo đảm chung rằng deadlock, livelock, starvation hay TOCTOU vắng mặt Cung cấp protected/tasking mechanism nhưng correct protocol vẫn là trách nhiệm thiết kế Loại trừ tĩnh data race trong subset được hỗ trợ, kiểm tra ràng buộc phòng deadlock của Ravenscar single-core và protected/tasking rule, đồng thời có thể phân tích invariant được nêu rõ General race như lost update và liveness là vấn đề riêng; project-wide tasking analysis hiện tại có giới hạn context
Logical/integrity property Ngoài một số invariant do type system biểu đạt, general functional correctness là vấn đề riêng Có thể biểu đạt contract và kiểm tra động Gold/Platinum có thể chứng minh integrity/functional contract được nêu rõ Phụ thuộc specification completeness và assumption
Recovery và availability Panic strategy cùng isolation/restart architecture là vấn đề riêng Exception handler có thể hiện thực response policy AoRTE có thể loại bỏ các unexpected exception xác định Không cơ chế nào tự động bảo đảm service recovery, redundancy, deadline hay resource ceiling
Resource exhaustion Tách khỏi memory/resource safety Storage_Error và điều kiện tương tự là failure mode riêng Storage_Error nằm ngoài SPARK analysis Cần invariant riêng như capacity planning, bounded allocation và admission control

Điểm quan trọng không phải là quy đổi các cột của bảng thành một điểm số duy nhất. Điểm mạnh của Safe Rust là cưỡng chế memory-safety invariant xác định như ràng buộc mặc định của mã thông thường với tương đối ít specification annotation. Ada cung cấp các lớp phòng vệ khác qua kiểu, dynamic check, exception và tasking abstraction. SPARK chấp nhận ngôn ngữ hạn chế hơn, contract rõ ràng và proof effort để đổi lấy khả năng mở rộng proof tĩnh từ AoRTE tới key integrity property và functional requirement.

Chi phí hiệu năng, thời gian thực và vòng đời

Vị trí của cơ chế bảo đảm cũng ảnh hưởng chi phí hiệu năng và bảo trì. Run-time check của Ada cung cấp phát hiện trong lúc thực thi, nên phải đánh giá chi phí thời gian và ảnh hưởng lên worst-case execution time trong workload đích. Ở phạm vi SPARK AoRTE thực sự hoàn tất, workflow GNAT/SPARK có thể dùng proof làm cơ sở tạo executable với check tương ứng được loại bỏ, nhưng điều đó không có nghĩa proof là miễn phí. Tài liệu chính thức giải thích proof cho chương trình lớn có thể mất hàng giờ; loop invariant, contract, manual proof và justification tạo chi phí bảo trì; full functional proof ở mức Platinum hiếm và thường chỉ áp dụng cho phạm vi nhỏ.51

Vì vậy trong môi trường quy mô lớn và cực hạn, phải so sánh không chỉ runtime overhead mà cả proof latency, tài nguyên CI, khả năng incremental verification, phạm vi lan truyền của thay đổi contract, vòng đời của external assumption, toolchain qualification, worst-case timing, memory ceiling và failure containment. Proof tĩnh mạnh có thể loại bỏ chi phí của một số run-time check, nhưng không tự động giải quyết resource exhaustion, hardware fault, yêu cầu sai hay operational recovery.

Kết luận trung gian

So sánh Ada/SPARK không cho thấy một bảng xếp hạng an toàn đơn giản trong đó Rust nằm ở một điểm giữa C/C++ và SPARK. Kết luận chính xác hơn là bảo đảm an toàn có nhiều chiều, và mỗi ngôn ngữ xử lý các phần khác nhau của các chiều đó với chi phí khác nhau.

Safe Rust có ưu điểm mạnh là mặc định phòng ngừa UB và data race xác định trong sound safe boundary. Ada cấu trúc phát hiện và phản ứng với lỗi qua strong typing, language-defined run-time check, exception và synchronization mechanism. SPARK có thể mở rộng proof tĩnh tới AoRTE, integrity property và functional contract khi có tập con có thể phân tích và specification rõ ràng. Ngược lại, proof của SPARK không tự động vượt qua Storage_Error, non-SPARK code, external system và assumption, hay specification completeness.

Vì vậy cả ba câu—“Rust biên dịch được thì an toàn”, “Ada có ngoại lệ nên bảo đảm phục hồi”, và “SPARK bảo đảm toàn bộ chương trình đúng về mặt toán học”—đều bỏ qua các điều kiện cần thiết và là những tóm tắt quá mạnh. Đối tượng cần so sánh không phải tên ngôn ngữ mà là thuộc tính cần bảo đảm, phạm vi bảo đảm, điều kiện thất bại, chi phí xác minh, chi phí thời gian chạy và proof obligation còn lại ở cấp hệ thống.

3.5 Phân tích so sánh 3: Đánh giá lại quản lý bộ nhớ thay thế bằng GC

Câu hỏi của mục này không phải “GC có chậm hơn Rust không?” hay “ngôn ngữ GC có không phù hợp với lập trình hệ thống không?”, mà là tự động thu hồi bộ nhớ và quản lý dựa trên ownership/lifetime mỗi cách làm giảm những loại khiếm khuyết nào, đồng thời để lại những chi phí thời gian chạy, tài nguyên, phát triển và vận hành nào. Tương tự Mục 3.2, cần tách bảo đảm của ngôn ngữ, chiến lược thu hồi bộ nhớ, một hiện thực runtime cụ thể và kết quả quan sát được trên workload thực tế.

GC và memory safety không phải cùng một khái niệm

Vai trò trực tiếp của tracing GC là theo dõi các object có thể đạt tới từ root và làm cho phần bộ nhớ trong managed heap không còn reachable có thể được tái sử dụng. Vì object do GC quản lý không cần free thủ công, đây là cơ chế mạnh để giảm các lỗi như premature free hay sử dụng lại object đã bị giải phóng trong vùng managed. Tuy nhiên, garbage collection là chính sách thu hồi bộ nhớ, không tự nó là định nghĩa memory-safety của toàn bộ ngôn ngữ. Bounds/type check, native/unsafe code, FFI, lỗi logic, concurrency protocol và resource exhaustion phụ thuộc vào các quy tắc riêng của ngôn ngữ, runtime và hệ thống.55

Reachability cũng không đồng nghĩa với “ứng dụng không còn cần object này”. Nếu root như global cache, collection hay event registration vẫn giữ tham chiếu, tracing GC sẽ đúng khi coi object đó là live và không thu hồi.

Vì thế hệ thống dùng GC vẫn có thể bị retention sai làm heap tiếp tục tăng cho tới OutOfMemory. Các tài nguyên không phải bộ nhớ như file descriptor, socket, lock và memory mapping cũng không thể được giả định sẽ được giải phóng đúng thời điểm chỉ nhờ GC theo dõi reachability.

Tài liệu runtime.AddCleanup của Go nêu rõ cleanup có thể chạy muộn tùy ý sau khi object trở nên unreachable và không được bảo đảm chạy trước khi chương trình thoát. Tài liệu .NET khuyến nghị cung cấp đường dọn dẹp rõ ràng như Dispose cho object bao bọc unmanaged resource. Vì vậy, tài nguyên mà thời điểm release tự nó là một phần của correctness không nên chỉ dựa vào GC reachability hay cleanup/finalizer.55

“GC hiện đại” không có một đặc tính latency/throughput duy nhất

Nếu gộp GC thành một hiện thực rồi khái quát rằng “chậm vì Stop-the-World”, hoặc ngược lại rằng “GC hiện đại đã giải quyết vấn đề pause”, ta sẽ đánh mất không gian lựa chọn thực tế. Cùng một runtime có thể có serial, parallel, generational, mostly-concurrent, fully-concurrent collector hoặc nhiều latency mode; chính hiện thực collector cũng thay đổi qua các release. Ví dụ, Go 1.26 đã chuyển Green Tea collector trước đây ở trạng thái experimental thành mặc định.56

Tài liệu HotSpot chính thức của Java SE 26 hiện tại cho thấy rõ sự khác biệt này. G1 mặc định được thiết kế để đạt throughput cao đồng thời đáp ứng pause-time goal với xác suất cao; ZGC được mô tả là low-latency collector giữ maximum pause dưới 1ms nhưng trả giá bằng một phần throughput. Oracle cũng giới hạn việc chọn collector theo kích thước heap, live data, CPU và workload. Đây là phản chứng mạnh đối với mệnh đề “mọi GC đều có pause dài”, nhưng không phải cơ sở để biến số liệu của ZGC thành thuộc tính phổ quát cho collector hay runtime khác.56

Hướng dẫn GC chính thức của Go cũng mô tả trade-off giữa memory và CPU qua GOGC cùng memory limit, chứ không chỉ throughput. Đặt memory limit quá sát live heap có thể khiến GC chạy quá thường xuyên, gây thrashing và suy giảm tiến triển nghiêm trọng; vì vậy Go định nghĩa memory limit là soft limit thay vì hard limit. Ngay cả khi phần lớn tracing chạy concurrent với application, vẫn còn các nguồn latency như chuyển trạng thái stop-the-world ngắn, GC CPU scheduling, mutator assist, write barrier và root scan.56

.NET cũng ghi nhận cùng loại trade-off. Low-latency mode hạn chế một số collection để giảm can thiệp do pause, nhưng managed heap có thể lớn hơn và fragmentation có thể tăng; khi có memory pressure, collection vẫn có thể chạy lại. Vì vậy chính sách giảm latency không phải tối ưu miễn phí, độc lập với CPU, memory, fragmentation và failure risk.56

Phải phân biệt pause thấp với bảo đảm hard real-time

Maximum pause dưới 1ms được tài liệu hóa của ZGC có thể là lựa chọn kỹ thuật quan trọng cho hệ thống low-latency. Tuy nhiên, GC pause ngắn, p99 latency hay pause-time target không phải cùng một mệnh đề với chứng minh rằng hard real-time deadline được đáp ứng. G1 mô tả pause-time goal theo xác suất; .NET low-latency mode vẫn có thể collection khi có memory pressure; tài liệu Go cũng liệt kê riêng các nguyên nhân ảnh hưởng end-to-end latency như mức CPU của concurrent GC và mutator assist ngoài chính GC pause.57

Khái quát ngược rằng “có GC thì hard real-time về nguyên tắc là không thể” cũng không phải kết luận được các nguồn này chứng minh. Mức phù hợp real-time phụ thuộc vào toàn bộ mô hình thực thi, gồm scheduling, allocation, barrier, pause bound, heap policy của collector cụ thể, OS scheduler, hardware và workload. Không nên coi mục tiêu low-pause thông thường hay số đo trung bình/percentile là bảo đảm hard deadline. Việc Rust không có tracing GC loại bỏ một nhóm biến động—tracing pause và tracing CPU—là một lợi thế, nhưng ngôn ngữ không tự động loại bỏ deadline miss do allocator, page fault, I/O, lock contention, destructor work hay scheduler.

Chi phí của Rust và tracing GC không thể chia thành hai ô “thời gian nhà phát triển” và “thời gian máy”

Phép ví von cũ rằng “Rust dùng thời gian nhà phát triển, còn ngôn ngữ GC dùng thời gian máy” mô tả được một phần dịch chuyển chi phí nhưng quá đơn giản để làm mô hình so sánh. Rust cũng có thể mang chi phí thời gian chạy từ heap allocator, Drop, reference counting, atomic operation, locking và cache behavior; ngôn ngữ GC cũng trả chi phí phát triển/vận hành cho heap sizing, quản lý allocation rate, profiling, tail-latency tuning và deterministic resource release. Ngược lại, tracing GC có thể tự động hóa thu hồi memory của object graph phức tạp và cycle, giảm gánh nặng biểu diễn lifetime rõ ràng; Rust có thể biểu diễn resource lifetime trực tiếp hơn ở các ranh giới scope/ownership thông thường.

Chiều so sánh Quản lý tập trung vào ownership/lifetime của Rust Quản lý tập trung vào tracing GC Ranh giới cần kiểm tra
Thu hồi managed memory Thường dễ gắn thời điểm thu hồi trực tiếp với kết thúc ownership và Drop Tự động thu hồi theo reachability và collector cycle Rc cycle, intentional leak, abort của Rust; retained root và delayed collection của GC
use-after-free / double-free Được phòng ngừa tĩnh trong sound Safe Rust boundary GC-managed object không bị thu hồi khi còn reachable, giảm các lỗi này trong managed heap Rust unsafe/FFI và native/unsafe boundary của managed runtime vẫn riêng biệt
cyclic object graph Có thể cần cấu trúc riêng như Rc/Weak, arena hoặc index Unreachable cycle có thể được tracing thu hồi Cycle/cache vẫn reachable nhưng không còn cần thì GC cũng không thu hồi
latency Không có tracing pause, write barrier hay GC thread, nhưng chi phí allocator, drop, scheduler vẫn còn Pause, concurrent work, barrier, mutator assist khác nhau theo collector Đo end-to-end tail latency và worst case trên workload
CPU / throughput Không có chi phí tracing heap graph, nhưng có allocator, drop, refcount, synchronization Tracing, barrier, GC worker dùng CPU; collector trao đổi latency với throughput Không suy ra tail latency hay energy chỉ từ throughput trung bình
memory footprint Không bắt buộc heap headroom cho GC, nhưng allocator fragmentation và working set vẫn còn Cần allocation headroom ngoài live set và GC metadata; footprint thay đổi theo tuning Đo RSS, peak committed memory, fragmentation, OOM/thrashing theo cùng định nghĩa
Tài nguyên không phải memory Drop/RAII có thể cấu trúc release trong lifetime bình thường GC reachability một mình không bảo đảm thời điểm release, nên có thể cần explicit close/dispose abort/process death/external resource semantics vẫn riêng ở cả hai phía
hard real-time Không có tracing GC tự nó không bảo đảm deadline Low-pause collector tự nó không bảo đảm deadline Bao gồm WCET, allocation policy, scheduler, page fault, I/O và failure containment

Tiêu chí đánh giá trong môi trường quy mô lớn và cực hạn

Vì vậy khi so sánh GC với Rust, không nên chỉ so throughput trung bình của một benchmark hay một con số GC pause. Ít nhất phải đo allocation rate, kích thước và biến động live set, pointer density của object graph, heap headroom và RSS, GC/allocator CPU, p50/p99/p99.9 và maximum pause, end-to-end tail latency, throughput, peak memory, OOM hoặc thrashing, startup, độ trễ resource-release, deadline miss, chi phí observability/tuning và chi phí vận hành dài hạn dưới cùng workload và điều kiện deployment. Khi collector hoặc phiên bản compiler thay đổi, cũng phải xác nhận lại tính hợp lệ của các phép đo này.

Kết luận trung gian

Kết luận Mục 3.5 không phải “GC hiện đại đủ nhanh nên lợi thế của Rust biến mất”, cũng không phải “GC không phù hợp với lập trình hệ thống vì pause”. Collector hiện tại có các đặc tính latency, throughput và memory khác nhau; cũng có hiện thực như Java ZGC đặt mục tiêu rõ ràng vào pause rất thấp. Đồng thời, như tài liệu Go và .NET cho thấy, giảm latency đi kèm các chi phí và điều kiện thất bại riêng về CPU, heap headroom, collection frequency và fragmentation.

Rust có ưu điểm mạnh là phòng ngừa tĩnh các lỗi memory-safety xác định trong sound Safe Rust boundary mà không cần tracing GC, đồng thời có thể cấu trúc resource lifetime một cách rõ ràng. Môi trường dựa trên GC có thể tự động hóa thu hồi managed object graph và đơn giản hóa quản lý lifetime cho cấu trúc chia sẻ/cyclic phức tạp. Lựa chọn phù hợp phụ thuộc vào memory-safety boundary cần thiết, latency và deadline, allocation pattern, live set, memory ceiling, tỷ trọng native/FFI, lifetime của tài nguyên không phải memory, năng lực phát triển/vận hành và tổng lifecycle cost. Nếu không nêu các điều kiện này, cả “GC chậm” lẫn “có GC thì vấn đề lifetime được giải quyết” đều là khái quát mạnh hơn bằng chứng hiện tại.

3.6 Phân tích diễn ngôn: Định nghĩa lại “tính thực dụng” và “trách nhiệm”

Các Mục 3.1–3.5 trước đó đã so sánh về mặt kỹ thuật các tiền lệ khái niệm của Rust, ranh giới bảo đảm giữa Safe Rust và unsafe, chiến lược thay đổi, Ada/SPARK và tracing GC. Câu hỏi của Mục 3.6 không phải chứng minh lại các kết luận kỹ thuật ấy, mà là những bước suy luận bổ sung nào xuất hiện khi một mệnh đề kỹ thuật có điều kiện trong diễn ngôn công khai được chuyển thành nhận định về tính thực dụng, trách nhiệm, ưu thế hoặc địa vị của lập trình viên. Đây là vấn đề của câu hỏi nghiên cứu 5 (RQ5).

Phân tích này trước hết tách các tầng nguồn. Tài liệu chính thức của Rust Project và Rust Reference được dùng làm nguồn sơ cấp để xác nhận mục tiêu được dự án công bố và ranh giới bảo đảm của ngôn ngữ. Bài đăng công khai trên Reddit, Rust Users Forum, blog và các nơi tương tự chỉ được dùng như ví dụ định tính cho thấy một dạng lập luận cụ thể có thể xuất hiện. Vì các ví dụ công khai dùng ở đây không phải mẫu xác suất hay corpus đại diện được định nghĩa trước, mục này không suy ra các mệnh đề về tần suất hoặc tính đại diện như “cộng đồng Rust nói chung” hay “đa số người dùng Rust”.58

Mô tả công khai của chính Rust Project cũng giúp xác lập sự phân biệt này. Trang chính thức hiện tại mô tả Rust như công cụ giúp mọi người xây dựng “reliable and efficient software”, còn kho mã chính thức trình bày performance, reliability và productivity như các lợi ích riêng. Vì vậy năng suất, công cụ và khả năng tiếp cận thuộc đề xuất giá trị chính thức của Rust, nhưng tự chúng không chứng minh Rust là nơi đầu tiên phát minh từng khái niệm nền tảng hay ưu việt trong mọi lĩnh vực.59

3.6.1 Chức năng diễn ngôn của “đổi mới thực dụng”

Phân tích lịch sử ở Mục 3.1 và đánh giá rằng “Rust là đổi mới thực dụng” không nhất thiết mâu thuẫn. Tính mới về khái niệm (conceptual novelty)việc tích hợp, biến thành mặc định, công cụ hóa và phổ biến các khái niệm có trước (engineering integration and adoption) là những trục đánh giá khác nhau. Dù ownership, RAII, các ý tưởng thuộc họ affine/linear và xác minh tĩnh đều có tiền lệ, thành tựu kỹ thuật của việc kết hợp ngôn ngữ, trình biên dịch, Cargo, chẩn đoán và hệ sinh thái thư viện thành một trải nghiệm phát triển vẫn có thể được đánh giá riêng.

Trong thảo luận công khai cũng có ví dụ dùng từ “democratization” để mô tả Rust hạ thấp rào cản vào những lĩnh vực trước đây đòi hỏi kiến thức C/C++ mạnh nhờ công cụ và trừu tượng hóa hiện đại. Cùng một thảo luận cũng có thể chứa phản luận rằng ngôn ngữ khác có thể năng suất hơn khi độ trưởng thành hệ sinh thái, chuyên môn của nhóm hoặc lĩnh vực thay đổi nhanh là yếu tố chi phối. Điều các ví dụ này chứng minh là những dạng lập luận và phản luận như vậy tồn tại trong diễn ngôn công khai, chứ không phải bên nào đại diện cho đa số cộng đồng.58

Vì vậy cần tách “đổi mới thực dụng” theo các câu hỏi sau.

Câu hỏi Bằng chứng cần thiết “Đổi mới thực dụng” có thể trả lời đến đâu
Rust có tạo ra khái niệm này đầu tiên không? Lịch sử ngôn ngữ, bài báo, tiêu chuẩn và hiện thực Không trả lời trực tiếp
Rust có tích hợp các khái niệm tiền lệ để dễ sử dụng hơn không? Thiết kế ngôn ngữ, công cụ, DX, hệ sinh thái và trường hợp áp dụng Có thể đánh giá trực tiếp
Rust có thực dụng hơn cho một tổ chức hoặc sản phẩm cụ thể không? workload, nhân lực, hiệu năng, assurance, chi phí chuyển đổi và vận hành Có thể đánh giá có điều kiện
Rust có ưu việt hơn trong mọi hệ thống không? Bằng chứng so sánh hỗ trợ toàn bộ phạm vi tuyên bố Trường hợp hạn chế không thể trả lời

Nếu câu hỏi “có mới về mặt khái niệm không?” chỉ được trả lời bằng “được dùng rộng rãi và thực dụng” trong khi che giấu việc tiêu chí đánh giá đã thay đổi, chủ đề đã bị chuyển. Ngược lại, nếu nói rõ “ngoài phát minh khái niệm, còn có đổi mới kỹ thuật trong tích hợp và phổ biến”, đó không phải né tránh mà là một tuyên bố chính đáng trên trục khác. Cần áp dụng cùng sự phân biệt này dù nó có lợi hay bất lợi cho Rust.

3.6.2 Quy “trách nhiệm”: Cách thảo luận rò rỉ bộ nhớ và unsafe

Phân tích trách nhiệm trước hết đòi hỏi tách điều ngôn ngữ không bảo đảm khỏi điều không quan trọng đối với hệ thống. Rust Reference không phân loại memory/resource leak hay việc destructor không chạy là unsafe. mem::forget trong thư viện chuẩn cũng là hàm safe; tài liệu giải thích điều đó vì safety guarantee của Rust không bảo đảm chính việc destructor sẽ chạy. Do đó câu “leak không vi phạm memory-safety guarantee của Safe Rust” phù hợp với ranh giới bảo đảm chính thức.60

Nhưng từ đó không suy ra “vì vậy leak không quan trọng” hoặc “vì vậy toàn bộ trách nhiệm thuộc về lập trình viên ứng dụng”. Trong dịch vụ chạy dài hạn, retained object hay resource leak có thể gây OOM, file-descriptor exhaustion, tăng latency, khởi động lại và giảm tính sẵn sàng. Đó là các thuộc tính vận hành tách biệt với định nghĩa memory safety. Thảo luận Rust công khai cũng vừa giải thích safe code có thể leak, vừa ghi nhận leak như vậy có thể là vấn đề tài nguyên nghiêm trọng trong dịch vụ thực tế. Đây là ví dụ định tính cho thấy guarantee boundary và operational severity là hai trục khác nhau.58

Cũng không chính xác nếu mô tả unsafe đơn thuần là “mã tắt kiểm tra của trình biên dịch” hoặc “dấu hiệu cô lập trách nhiệm cho tác giả khi có vấn đề”. Rust Reference mô tả unsafe là từ khóa tạo hoặc hoàn tất (create or discharge) nghĩa vụ chứng minh an toàn (proof obligation). unsafe fn, unsafe trait và các cấu trúc tương tự định nghĩa safety condition bổ sung phải được giữ ở nơi khác, còn unsafe {}unsafe impl nằm ở phía lập trình viên tuyên bố các safety condition liên quan đã được đáp ứng. Ranh giới quan trọng hơn là soundness: Reference định nghĩa một abstraction là unsound nếu phần hiện thực unsafe bên trong cho phép safe client gây UB.60

Vì vậy, với khiếm khuyết trong phần hiện thực unsafe của thư viện, cần tách các tầng sau.

Tầng Câu hỏi cần đặt ra
Bảo đảm ngôn ngữ/trình biên dịch Trường hợp đã ra ngoài phạm vi quy tắc tĩnh của Safe Rust, hay một proof obligation bên ngoài đã được discharge sai?
Soundness của unsafe abstraction Safe caller có thể gây UB mà không vi phạm điều kiện bổ sung nào đã được ghi tài liệu không?
Trách nhiệm thư viện/API invariant, safety contract, review và test có đầy đủ không?
Trách nhiệm ứng dụng/vận hành dependency management, cô lập, quan sát, giới hạn tài nguyên, cập nhật và phản ứng sự cố có đầy đủ không?
Trách nhiệm tổ chức/lifecycle owner của ranh giới rủi ro, chu kỳ audit, xác minh toolchain và supply chain đã được định nghĩa chưa?

Trong khung này, “bản thân quy tắc ngôn ngữ Safe Rust không trực tiếp thất bại” và “thư viện cung cấp safe API có khiếm khuyết soundness” có thể cùng đúng. Một thảo luận công khai về lỗi unsafe cũng xem xét trường hợp unsafe operation nơi UB thực sự biểu hiện và safe code đã phá invariant mà operation đó phụ thuộc có thể nằm xa nhau. Đây là ví dụ định tính cho thấy trách nhiệm không nhất thiết bị cô lập trong một khối unsafe; nó không chứng minh cấu trúc như vậy xuất hiện thường xuyên đến đâu.58 Ngược lại, từ một lỗi unsafe khái quát rằng “toàn bộ mô hình memory-safety của Rust vô nghĩa” cũng quá mức vì cùng lý do. Trách nhiệm phải được phân rã theo ranh giới bảo đảm và hợp đồng, không phải chuyển giao bằng một từ duy nhất.

3.6.3 Tách lợi thế kỹ thuật có điều kiện khỏi phán xét địa vị phổ quát

Ranh giới quan trọng nhất trong RQ5 là bước chuyển từ mệnh đề kỹ thuật sang mệnh đề về địa vị của con người hoặc công nghệ nói chung. Ba bước đầu sau đây đều có thể là kết luận kỹ thuật nếu từng bước có đủ bằng chứng.

  1. Trong một sound Safe Rust boundary, safe client một mình không thể gây undefined behavior, và data race thuộc các hành vi Rust phân loại là undefined behavior.60
  2. Trong một hệ thống cụ thể, rủi ro từ các lớp lỗi đó cao và chi phí áp dụng Rust có thể chấp nhận.
  3. Vì vậy Rust có thể là ứng viên áp dụng mạnh, hoặc lựa chọn tốt hơn, cho hệ thống đó.

Chuyển thẳng từ đây sang “vì vậy Rust ưu việt cho mọi hệ thống”, “ngôn ngữ khác đã lỗi thời”, hoặc “lập trình viên chọn khác thiếu năng lực, tư cách hay trách nhiệm” đòi hỏi bằng chứng và tiền đề chuẩn tắc hoàn toàn khác. Một thuộc tính ngôn ngữ ngăn một lớp lỗi cụ thể không tự động quyết định workload, tài sản hiện có, yêu cầu hard-real-time, mức phù hợp hệ sinh thái, nhân lực, rủi ro chuyển đổi hay lifecycle cost; một lựa chọn kỹ thuật có điều kiện cũng không phải thước đo trí tuệ hoặc giá trị đạo đức của lập trình viên.

Tiêu chuẩn này mang tính đối xứng. Dùng chi phí của borrow checker, lỗi tại ranh giới unsafe hay khoảng trống hệ sinh thái để kết luận “Rust không phù hợp với bất kỳ hệ thống nào”, hoặc hạ thấp năng lực của người dùng Rust, cũng là cùng loại khái quát quá mức. Đối tượng phân tích ở đây không phải sự hơn kém của một nhóm ngôn ngữ, mà là quá trình suy luận trong đó mệnh đề kỹ thuật có điều kiện mất phạm vi áp dụng và biến thành mệnh đề phổ quát về địa vị kỹ thuật hoặc xã hội.

Trong môi trường quy mô lớn và cực hạn, sự phân biệt này không chỉ là phép lịch sự tu từ. Phản ứng sự cố thực tế đòi hỏi xác định cụ thể defect locus, proof obligation, API contract, dependency owner, deployment và rollback, resource ceiling, audit và incident ownership. Nói “ngôn ngữ không bảo đảm điều đó” không loại bỏ trách nhiệm vận hành, còn nói “đó là trách nhiệm lập trình viên” không thay cho việc xác định quy trình kiểm chứng, quan sát và phục hồi cần thiết. Phân rã trách nhiệm chính xác là một phần của an toàn, độ tin cậy, khả năng bảo trì và lifecycle cost dài hạn.

Kết luận tạm thời

Kết luận của Mục 3.6 không phủ nhận tính thực dụng của Rust, cũng không quy mọi vấn đề unsafe thành thất bại của bản thân ngôn ngữ. “Đổi mới thực dụng” có thể là một trục đánh giá hợp lệ cho thành tựu tích hợp và phổ biến, tách biệt với phát minh khái niệm. Việc memory/resource leak nằm ngoài memory-safety guarantee của Rust cũng là giải thích đúng về kỹ thuật. unsafe cũng là cơ chế thiết kế quan trọng để làm rõ các proof obligation bên ngoài.

Đồng thời, ba sự thật này không lần lượt chứng minh tính nguyên bản khái niệm, tính vô hại trong vận hành, hay việc loại bỏ trách nhiệm hệ thống. Tiêu chuẩn phân tích RQ5 vì vậy tách tài liệu chính thức khỏi ví dụ diễn ngôn công khai, không suy ra tần suất từ ví dụ định tính, và làm rõ các tiền đề bổ sung cần có để đi từ bảo đảm kỹ thuật tới ưu thế phổ quát hoặc phán xét địa vị lập trình viên. Các ví dụ công khai được xem xét ở đây cho thấy những dạng lập luận ấy tồn tại; chúng không chứng minh một thái độ đại diện của toàn Rust Project hay nhóm người dùng Rust.58

3.7 Kết luận: Đánh đổi giữa hiệu năng, an toàn và năng suất

Chương 3 không thể khép lại bằng cách xếp Rust và các phương án thay thế theo thứ tự trên một tam giác duy nhất “hiệu năng-an toàn-năng suất”. Phân tích trước đó cho thấy cần xem xét đồng thời loại lỗi nào cần giảm, bảo đảm nào được yêu cầu và kéo dài tới ranh giới nào, bảo đảm ấy đạt được bằng quy tắc tĩnh, kiểm tra động, thu hồi tự động hay chứng minh hình thức, và lựa chọn đó đặt chi phí runtime, xác minh, chuyển đổi và vận hành ở đâu.

Vì vậy, khi so sánh ngôn ngữ và hệ sinh thái, ít nhất cần tách sáu trục sau.

  1. Mô hình lỗi và phạm vi bảo đảm: Trong use-after-free, double-free, data race, race condition nói chung, lỗi logic, resource exhaustion và availability failure, loại nào cần được phòng ngừa, phát hiện hay giảm nhẹ?
  2. Cơ chế bảo đảm: Kết hợp thế nào giữa phòng ngừa tĩnh bằng ngôn ngữ/hệ thống kiểu, run-time check và exception, tracing GC, contract và formal proof, cùng các công cụ phát hiện như sanitizer, static analysis và fuzzing?
  3. Chi phí thực thi và đặc tính tài nguyên: throughput, tail latency, worst-case timing, allocator/GC CPU, memory headroom, code size, startup, synchronization và chi phí resource-release xuất hiện thế nào trong workload mục tiêu?
  4. Yêu cầu assurance và real-time: Thuộc tính nào phải được proof, assumption và mã ngoài nào được tin cậy, và hard deadline cùng failure containment được chứng minh ra sao?
  5. Chiến lược thay đổi và tài sản hiện có: Cần thay đổi tới mức nào giữa giữ lại/hardening, modernization trong cùng ngôn ngữ, đưa vào component mới, thay thế có chọn lọc và rewrite toàn bộ?
  6. Chi phí tổ chức và lifecycle: Tổ chức có thể duy trì việc học, code review, build/test, proof và CI, dependency và toolchain, observability, triển khai và rollback, tuyển dụng và bảo trì dài hạn hay không?

Trên các trục này, khác biệt giữa các cách tiếp cận không hiện ra như một điểm số duy nhất mà như những cách bố trí bảo đảm và chi phí khác nhau.

Cách tiếp cận Điều kiện để ưu điểm phát huy Ranh giới và chi phí chính còn lại
C/C++ Tài sản hiện có, hệ sinh thái và quyền kiểm soát mức thấp quan trọng, đồng thời có thể áp dụng dần RAII, smart pointer, guideline, static analysis, sanitizer và hardening Ngôn ngữ không mặc định chặn tĩnh mọi memory-unsafe access; phạm vi và độ đầy đủ của quy tắc/công cụ, legacy boundary và verification discipline phải được quản lý riêng
Môi trường tracing-GC như Go, Java và C# Workload coi trọng tự động thu hồi managed object graph và giảm gánh nặng quản lý lifetime tường minh trong cấu trúc chia sẻ/cyclic phức tạp Trade-off latency/CPU/memory theo từng collector, retained object, native/unsafe boundary, release tường minh tài nguyên không phải bộ nhớ và chứng minh hard-real-time vẫn là các vấn đề riêng
Ada Cần strong typing, language-defined run-time check, exception, tasking abstraction và control flow tường minh Vẫn có các ranh giới như check suppression, unchecked operation và external representation; phát hiện không tự nó bảo đảm recovery hay availability, và timing cost của run-time check phải được đánh giá
SPARK Đáng chấp nhận một language subset bị giới hạn cùng contract/proof effort để mở rộng phạm vi proof vượt AoRTE tới integrity property và functional requirement được nêu rõ Phạm vi bảo đảm bị giới hạn bởi assurance level, code scope, specification completeness, Storage_Error, non-SPARK/external code, assumption và chi phí duy trì proof/CI
Rust Cần đồng thời quyền kiểm soát mức thấp không có tracing GC và memory-safety/data-race prevention trong một sound Safe Rust boundary, đồng thời có thể cấu trúc quan hệ ownership/lifetime trong type và interface unsafe, FFI, library/compiler correctness, race condition nói chung, logic, availability và resource bound vẫn là vấn đề riêng; chi phí runtime như allocator, Drop, refcount, atomic và locking, cùng chi phí học, biên dịch và tích hợp cũng còn lại

Bảng này không nhằm xếp hạng “ngôn ngữ nào an toàn nhất hay nhanh nhất”. Như Mục 3.4 cho thấy, memory-safety invariant mặc định của Safe Rust và contract proof tường minh của SPARK là các loại bảo đảm khác nhau; các assurance objective như Gold/Platinum của SPARK cũng không tự động vượt ra ngoài phạm vi specification và assumption. Như Mục 3.5 cho thấy, tracing GC tự động hóa thu hồi managed memory nhưng có đặc tính tài nguyên và latency riêng theo collector; không thể đơn giản gọi các chi phí đó là “thời gian máy”, cũng như không thể rút gọn chi phí Rust thành “thời gian lập trình viên”.

Lựa chọn ngôn ngữ và chiến lược thay đổi không phải cùng một quyết định

Một kết luận quan trọng của Mục 3.3 là độ mạnh của bảo đảm ở ngôn ngữ đích và mức độ cần thay đổi hệ thống hiện có là hai câu hỏi riêng. Trong một hệ thống C/C++, có thể kết hợp giữ lại/hardening, modernization, component Rust mới, thay thế có chọn lọc module rủi ro cao, bounded rewrite và rewrite diện rộng để giảm một loại lỗi cụ thể. Ưu điểm memory-safety của Rust không tự động biện minh cho rewrite toàn bộ legacy code; ngược lại, chỉ riêng việc có migration risk cũng không đủ để loại Rust khỏi vùng mới hoặc rủi ro cao.

Hiệu quả ròng của thay đổi phải so sánh rủi ro lỗi được giảm với rủi ro chuyển đổi mới phát sinh theo cùng một tiêu chuẩn. Việc phục hồi đặc tả, test oracle, FFI/ABI, data/protocol compatibility, dual-language build, rollout/rollback, performance regression, độ trưởng thành vận hành và năng lực tổ chức phải được đánh giá cùng bảo đảm ngôn ngữ. Từ góc nhìn này, câu hỏi “thay đổi ranh giới rủi ro nào bằng chiến lược nào?” chính xác hơn chỉ hỏi “có dùng Rust không?”.

An toàn không phải một trục duy nhất, và lựa chọn công nghệ không phải phán xét địa vị

So sánh ở Mục 3.2 và 3.4 cho thấy memory safety, security, functional correctness, concurrency correctness, availability, resilience và real-time assurance có thể liên quan nhưng không phải cùng một thuộc tính. Việc một ngôn ngữ có bảo đảm mạnh ở một chiều không tự động đem lại bảo đảm ở các chiều khác. Vì vậy các câu như “biên dịch được thì an toàn”, “có exception thì recovery được bảo đảm”, “đã proof nên toàn hệ thống đúng”, hay “có GC thì vấn đề lifetime được giải quyết” đều cần kiểm tra điều kiện áp dụng và ranh giới.

Phân tích diễn ngôn ở Mục 3.6 cũng áp dụng nguyên tắc này cho lựa chọn công nghệ. Một lợi thế kỹ thuật có điều kiện có thể biện minh cho quyết định áp dụng mạnh khi bằng chứng về điều kiện và chi phí liên quan là đủ, nhưng tự nó không thiết lập ưu thế phổ quát cho mọi hệ thống hay biện minh cho phán xét về năng lực, tư cách hoặc trách nhiệm của lập trình viên chọn phương án khác. Cần áp dụng cùng tiêu chuẩn bằng chứng cho sự khái quát quá mức theo chiều ngược lại.

Tiêu chí đánh giá cuối cùng cho môi trường quy mô lớn và cực hạn

Trong môi trường quy mô lớn, chạy dài hạn, mission-critical và hard-real-time, một benchmark trung bình hay một đặc tính tiêu biểu của ngôn ngữ là chưa đủ để kết luận.

Ít nhất phải đo hoặc chứng minh cùng nhau, dưới workload và điều kiện triển khai thực tế, tần suất và severity của lỗi mục tiêu, tail latency và worst-case timing, throughput, CPU budget, code size và storage budget, peak memory và resource ceiling, energy/power budget, OOM hoặc thrashing, deadline miss, failure containment và recovery, startup, build/test và proof latency, tài nguyên CI, xác minh dependency/supply-chain/toolchain, observability, rollout/rollback, incident response, nhân lực và lifecycle cost dài hạn.

Khi compiler, collector, proof tool, dependency, hardware hoặc workload thay đổi, tính hợp lệ của kết quả trước đó cũng phải được đánh giá lại.

Kết luận chương

Kết luận của Chương 3 không phải xếp hạng một ngôn ngữ bằng một điểm số tổng hợp. Rust là một lựa chọn kỹ thuật quan trọng vì có thể mặc định chặn những UB và data race xác định trong một sound Safe Rust boundary, đồng thời giữ quyền kiểm soát mức thấp mà không cần tracing GC. C/C++ có thể giữ tài sản hiện có và quyền kiểm soát mức thấp trong khi áp dụng hardening và modernization từng bước. Môi trường tracing-GC có thể tự động thu hồi managed memory và unreachable cycle, qua đó giảm gánh nặng quản lý lifetime cho object graph phức tạp. Ada cung cấp các lớp phòng vệ như strong typing, language-defined run-time check và exception; SPARK có thể mở rộng proof vượt AoRTE tới integrity property và functional requirement dựa trên subset bị giới hạn và contract tường minh.

Lựa chọn nào phù hợp hơn phụ thuộc vào mô hình lỗi, assurance level và ranh giới cần thiết, workload và ràng buộc real-time, resource ceiling, tài sản hiện có và phạm vi thay đổi, tài sản xác minh, interop, chiến lược triển khai và recovery, hệ sinh thái, năng lực tổ chức và tổng lifecycle cost. Làm rõ các điều kiện này và so sánh các phương án theo cùng tiêu chuẩn bằng chứng là kết luận kỹ thuật của chương này.

4. Đánh giá lại mô hình sở hữu và triết lý thiết kế

Chương 4 không trình bày ownership của Rust như một câu chuyện đơn tuyến về nơi một khái niệm được “phát minh đầu tiên”. Trước hết, Mục 4.1 tách ảnh hưởng trực tiếp được tài liệu xác nhận, tiền lệ lịch sử, tương đồng khái niệm và niên biểu tiêu chuẩn hóa giữa RAII, smart pointer, move semantics của C++ và Rust ownership. Mục 4.2 sau đó so sánh với các kỹ thuật đi trước này để phân tích Rust đặt các quy tắc ownership, move và borrowing vào hệ kiểu và kiểm tra của trình biên dịch như thế nào. Cuối cùng, Mục 4.3 so sánh với contract-based verification của Ada/SPARK và xem xét những ràng buộc, chi phí mà các cơ chế bảo đảm khác nhau tạo ra trong những cấu trúc dữ liệu và workload cụ thể. Quan hệ ảnh hưởng lịch sử tự nó không chứng minh độ mạnh của bảo đảm hiện tại, hiệu năng, an toàn hay độ phù hợp với một dự án cụ thể.

4.1 Mối quan hệ lịch sử giữa sở hữu Rust và RAII/con trỏ thông minh C++

Mục này áp dụng nguyên vẹn tiêu chuẩn quy thuộc lịch sử đã dùng ở Mục 3.1. Việc hai công nghệ giống nhau có thể cho thấy tương đồng khái niệm, nhưng tự nó không chứng minh một dòng kế thừa trực tiếp. Ngược lại, khi nguồn chính thức nêu rõ một ảnh hưởng cụ thể, ta có thể gọi đó là ảnh hưởng trực tiếp được tài liệu xác nhận trong phạm vi ấy. Rust Reference liệt kê references, RAII, smart pointers và move semantics của C++ như các ảnh hưởng tới thiết kế Rust, đồng thời liệt kê riêng region-based memory management của ML Kit và Cyclone như những ảnh hưởng khác.33 Vì vậy câu hỏi ở đây không phải “C++ có phải nơi đầu tiên phát minh ownership như một khái niệm chung hay không”, mà là những kỹ thuật quản lý tài nguyên nào của C++ có thể được xác nhận là ảnh hưởng tới Rust, và quy tắc cùng vị trí cưỡng chế của hai bên giống hoặc khác nhau ở đâu.

Quản lý bộ nhớ thủ công trong C là nền của không gian vấn đề, không phải bằng chứng dòng dõi

malloc()free() của C cho phép lập trình viên kiểm soát rõ ràng việc cấp phát và giải phóng bộ nhớ động. Ghép lifetime sai có thể tạo ra memory leak, double free và use-after-free. Điều này mô tả không gian vấn đề mà RAII, smart pointer và ownership system cố gắng xử lý, nhưng tự nó không chứng minh một kỹ thuật là tổ tiên trực tiếp của kỹ thuật khác.

  • memory leak: Một allocation không còn cần thiết vẫn không được giải phóng, có thể làm tăng mức dùng bộ nhớ và resource pressure trong vận hành dài hạn.
  • double free: Cùng một allocation bị giải phóng hai lần, có thể làm hỏng allocator state hoặc gây undefined behavior.
  • use-after-free: Storage đã hết lifetime bị dùng lại, có thể dẫn tới memory corruption hoặc security vulnerability.

Ngay cả trong nhóm rộng “quản lý thủ công”, ba lỗi này có nguyên nhân và ranh giới bảo đảm khác nhau. Một tính năng ngôn ngữ làm giảm một lỗi không tự động bảo đảm logical correctness, availability hay resource bound. Cách phân biệt này giữ nguyên các ranh giới an toàn đã thiết lập ở Mục 3.2 và 3.7.

C++ RAII: kỹ thuật đi trước gắn giải phóng tài nguyên với scope và object lifetime

RAII của C++ gắn việc lấy và giải phóng tài nguyên với object lifetime. C++ Core Guidelines khuyến nghị quản lý tài nguyên tự động bằng resource handle và RAII, đồng thời coi entity chịu trách nhiệm giải phóng tài nguyên là owner. Rust Book cũng giải thích việc Rust dọn tài nguyên bằng drop khi giá trị rời scope và trực tiếp dùng RAII của C++ làm đối tượng so sánh.33 Vì vậy có cơ sở để nói rằng RAII có liên hệ lịch sử và khái niệm với resource cleanup của Rust được gắn vào scope/object-lifetime.

Tuy nhiên, bằng chứng ở đây không cho phép mở rộng mối liên hệ đó thành tuyên bố rằng ownership như một khái niệm chung được thiết lập đầu tiên trong C++. Rust ownership kết hợp cleanup khi kết thúc scope với hạn chế dùng binding cũ sau move, các quy tắc shared/mutable borrowing, và compiler checking đối với các quy tắc này. Việc Rust Reference còn liệt kê ML Kit và Cyclone như các ảnh hưởng ngoài C++ cũng là một ranh giới chống việc quy thiết kế memory/lifetime của Rust về một dòng C++ duy nhất.33

Tách niên biểu tiêu chuẩn hóa smart pointer khỏi so sánh ngữ nghĩa

Nói rằng smart pointer “lần đầu được đưa vào ở C++11” cũng không chính xác. Thư viện chuẩn C++ đã có auto_ptr trước C++11, và tài liệu WG21 ghi lại rằng hướng thêm unique_ptr đồng thời deprecate auto_ptr được chấp nhận năm 2007. Tài liệu tiêu chuẩn hóa C++ năm 2011 đã có unique_ptrshared_ptr trong thiết kế thư viện chuẩn thời C++11.61 Vì vậy, thời điểm tồn tại và quá trình tiêu chuẩn hóa của một smart pointer cụ thể được tách khỏi tuyên bố về ảnh hưởng trực tiếp tới Rust.

Hai hình thức ownership tiêu biểu của C++ hiện đại hữu ích khi so sánh ngữ nghĩa với Rust.

  • std::unique_ptr: Biểu diễn exclusive ownership và chuyển ownership bằng move thay vì copy. Sau move construction trong C++, source unique_ptr vẫn là một object nhưng không còn sở hữu pointer; còn với giá trị non-Copy của Rust, sau khi toàn bộ giá trị được move thì việc dùng binding cũ bị từ chối tĩnh. Cả hai đều phân biệt ownership transfer với copy, nhưng quy tắc về moved-from state không giống nhau; sự tương đồng này cũng không chứng minh unique_ptr là nguyên mẫu trực tiếp của toàn bộ Rust ownership.62
  • std::shared_ptr: Biểu diễn shared ownership bằng reference counting. Rc<T>Arc<T> của Rust cũng cung cấp reference-counted shared ownership nên là điểm so sánh hữu ích. Tuy nhiên, các nguồn dùng trong mục này không thiết lập một dòng dõi một-một trong đó shared_ptr là “nền tảng” trực tiếp của Rc<T> hay Arc<T>.62

Khác biệt quan trọng không chỉ là các công cụ này có tồn tại hay không, mà là quy tắc áp dụng ở đâu và ranh giới mặc định nằm ở đâu. C++ có thể dùng mạnh RAII và standard smart pointer đồng thời vẫn dùng raw pointer, manual allocation và custom lifetime protocol. Trong Rust, các quy tắc move và borrowing là một phần của value semantics mặc định trong Safe Rust: compiler từ chối tĩnh các mẫu như use-after-move và shared/mutable borrow xung đột, còn unsafe đưa vào các safety obligation riêng bên ngoài ranh giới đó. Vì vậy, thay vì phân đôi đơn giản “một bên là kỷ luật, một bên là an toàn”, nên so sánh theo quy tắc nào được cưỡng chế mặc định và còn những escape hatch cùng proof obligation nào.

Kết luận tạm thời

Rust Reference trực tiếp ghi nhận RAII, smart pointers và move semantics của C++ đã ảnh hưởng tới Rust. Đồng thời, tài liệu chính thức cũng ghi nhận những ảnh hưởng ngoài C++ đối với thiết kế ownership/lifetime của Rust, gồm ML Kit và Cyclone. Vì thế, mệnh đề “có ảnh hưởng lịch sử giữa C++ và Rust” không đồng nhất với mệnh đề “khái niệm ownership tự nó bắt nguồn từ C++”. So sánh unique_ptr với Rust move/ownership hay shared_ptr với Rc/Arc hữu ích để giải thích khác biệt thiết kế, nhưng chỉ sự tương đồng không đủ để suy ra một dòng dõi một-một.

Bản tường thuật lịch sử này cũng không quyết định ưu thế kỹ thuật hiện tại. Độ phù hợp của mỗi mô hình cần được đánh giá riêng theo memory-safety guarantee, unsafe/FFI boundary, concurrency model, allocator và reference-counting cost, latency và resource ceiling, existing codebase, migration risk, verification assets và lifecycle cost. Vì vậy Mục 4.2 dùng quan hệ lịch sử này làm bối cảnh, nhưng phân tích khác biệt thực tế của Rust không theo câu hỏi ai phát minh khái niệm trước, mà theo cách các quy tắc được cấu thành và vị trí compiler enforcement.

4.2 Vị trí thực thi và ranh giới bảo đảm của các quy tắc sở hữu Rust

Sau khi Mục 4.1 tách ảnh hưởng lịch sử khỏi sự tương đồng khái niệm, câu hỏi ở đây không còn là nhị nguyên “trong C++ thì tùy chọn còn trong Rust thì bắt buộc hay không”. Câu hỏi chính xác hơn là thuộc tính nào được kiểm tra ở lớp nào, kiểm tra đó cung cấp bảo đảm dưới những giả định và ranh giới nào, và phần trách nhiệm nào vẫn thuộc về thư viện, nhà phát triển và môi trường vận hành.

ownership, move và borrowing không được thực thi tại một vị trí duy nhất

Rust Book mô tả ownership là một tập quy tắc chi phối cách chương trình Rust quản lý bộ nhớ, và trình biên dịch kiểm tra các quy tắc ấy rồi từ chối chương trình vi phạm. Gán hoặc truyền một giá trị non-Copy vào hàm có thể move ownership; sau khi toàn bộ giá trị đã được move, việc dùng lại binding cũ bị từ chối tĩnh. Reference và borrowing chịu các quy tắc bổ sung, trong đó reference validity và các shared/mutable borrow xung đột được kiểm tra lúc biên dịch.63

Tuy nhiên, mở rộng điều này thành “mọi quy tắc liên quan ownership của Rust đều được borrow checker cưỡng chế lúc biên dịch” cũng không chính xác. Chẳng hạn RefCell<T> cung cấp interior mutability phía sau safe API và kiểm tra một phần borrowing rule lúc chạy. borrow()borrow_mut() panic khi gặp borrow xung đột, còn try_borrow()try_borrow_mut() trả cùng xung đột đó dưới dạng lỗi Result. Vì vậy cần tách run-time checking tự thân khỏi những API cụ thể biến vi phạm thành panic. Ngay trong Rust, cùng một mục tiêu thiết kế có thể được đảm nhiệm ở các vị trí khác nhau bởi static type/borrow checking, library abstraction và run-time check.64

Thuộc tính hoặc cơ chế Vị trí thực thi/kiểm tra chính Ranh giới còn lại
ownership và move type system và compiler check logical correctness, resource policy và trạng thái hệ thống bên ngoài là vấn đề riêng
shared/mutable reference borrow checking và reference validity rule điều kiện của raw pointer, UnsafeCell và unsafe abstraction vẫn tách biệt
borrowing của RefCell<T> run-time check bên trong safe API xung đột ở borrow()/borrow_mut() gây panic; try_borrow()/try_borrow_mut() trả lỗi; recovery và availability là vấn đề riêng
unsafe contract/operation compiler giới hạn vị trí và hình thức dùng unsafe; tác giả chịu trách nhiệm thỏa các safety condition compiler không thể xác minh nghĩa vụ ngăn UB và duy trì safe-client soundness vẫn còn
xử lý Result và panic policy library API và application control flow khả năng recovery, failure isolation và availability là vấn đề thiết kế application/operation

unsafe không phải chế độ tắt toàn bộ kiểm tra an toàn

Rust Reference mô tả unsafe là nơi định nghĩa các safety condition bổ sung mà compiler không thể xác minh, hoặc nơi tác giả khẳng định những điều kiện đó đã được thỏa. unsafe block cho phép một số operation cụ thể như dereference raw pointer hay gọi unsafe function, nhưng như Rust Book nêu rõ, nó không vô hiệu hóa borrow checker hay những kiểm tra an toàn thông thường khác. Các quy tắc về undefined behavior trong Rust Reference cũng tiếp tục áp dụng bên trong unsafe code.63

Vì vậy, chính xác hơn là xem unsafe không phải “vùng tự do ngoài quy tắc Rust” mà là ranh giới nơi proof obligation đổi vị trí. Thuật ngữ proof obligation của Rust Reference không có nghĩa bắt buộc phải có machine-checked formal proof kiểu SPARK.

Reference giải thích obligation có thể được discharge bằng nhiều cách, gồm run-time check hoặc data-structure invariant. Trong mục này, thuật ngữ chỉ trách nhiệm kiểm tra có căn cứ và duy trì các safety condition mà compiler không thể xác minh. Nếu một unsafe implementation duy trì invariant cần thiết và tạo API sao cho safe client không thể gây UB, abstraction đó có thể cung cấp safe interface.

Ngược lại, nếu client chỉ dùng safe API vẫn có thể chạm tới UB, soundness của abstraction đã bị phá vỡ theo nghĩa đã bàn ở Mục 3.2 và 3.6. Trách nhiệm không chuyển nguyên khối từ compiler sang developer mà được chia giữa compiler check, unsafe contract, library soundness và application invariant.63

C++ cũng không vận hành chỉ bằng “lựa chọn của nhà phát triển”

Khác biệt với C++ cũng quá rộng nếu chỉ mô tả là “pattern tùy chọn đối lập compiler rule bắt buộc”. Object lifetime và destructor semantics của C++ là quy tắc ngôn ngữ; khi đã chọn std::unique_ptr, các ràng buộc như hạn chế copy và ownership-transfer interface thực sự được type system và compiler thực thi. C++ Core Guidelines cũng khuyến nghị dùng unique_ptrshared_ptr để biểu diễn ownership, đồng thời nói rằng parameter unique_ptr không chỉ ghi nhận mà còn enforce ownership transfer.65

Đồng thời, C++ cho phép raw pointer, new/delete tường minh và custom lifetime protocol; một số quy tắc trong Core Guidelines giả định guideline checker hoặc static-analysis tooling thay vì compiler tự thực thi. Vì vậy điều cần so sánh không phải “C++ không có cưỡng chế còn Rust có”, mà là phạm vi mặc định của các ràng buộc ownership và aliasing, vai trò của opt-in type, độ rộng escape hatch, và tool nào phát hiện vi phạm ở thời điểm nào. Safe Rust boundary áp dụng rộng move và reference borrowing rule vào cách dùng ngôn ngữ thông thường, trong khi RAII và ownership-aware type của C++ cũng là cơ chế ngôn ngữ/thư viện mạnh nhưng cùng tồn tại với raw/custom boundary rộng hơn.65

Tính bảo thủ của kiểm tra tĩnh và vai trò của safe abstraction

Kiểm tra tĩnh mạnh không đồng nghĩa compiler trực tiếp chấp nhận mọi memory-safe implementation. Rust Reference mô tả type system như một xấp xỉ bảo thủ của dynamic safety requirement. Trong ví dụ split_at_mut của tài liệu Rust chính thức, con người có thể xác lập invariant rằng hai slice không chồng lấp, nhưng borrow checker không thể trực tiếp nhận ra disjointness ấy từ một cặp mutable borrow đơn giản. Cách giải tiêu chuẩn là xác lập invariant trong một unsafe implementation nhỏ bằng raw pointer và điều kiện độ dài, rồi cung cấp safe API phía trên.64

Do đó compile rejection tự nó không chứng minh “operation dự định thực tế là unsafe”. Ngược lại, việc con người tin rằng code an toàn cũng không chứng minh compiler rejection là sai. Điều quan trọng về kỹ thuật là tách biểu thức compiler có thể chứng minh trực tiếp, điều kiện có thể chuyển sang run-time check, và invariant phải được biện minh tường minh bên trong unsafe abstraction. Phân biệt này đặc biệt quan trọng với graph phức tạp, intrusive structure, FFI và device memory, nơi quan hệ lifetime và aliasing khó xử lý.

unwrap() không phải bằng chứng cho suy luận tâm lý về bảo đảm ownership

Văn bản cũ suy luận rằng niềm tin vào bảo đảm an toàn của compiler có thể làm giảm defensive programming và tăng việc dùng unwrap(), nhưng mục này không có bằng chứng xác lập quan hệ nhân quả đó trong developer behavior. Vì vậy lập luận ấy được loại bỏ. Điều tài liệu thư viện chuẩn nói trực tiếp về Result::unwrap() hẹp hơn: nó panic khi giá trị là Err, và tài liệu nhìn chung khuyến nghị các lựa chọn như ? hoặc xử lý lỗi tường minh.64

Dùng hay không dùng unwrap() là một lựa chọn error-handling và failure-policy tách khỏi memory-safety guarantee. Có code dựa trên invariant để cho rằng Err không thể xảy ra; nếu giả định sai, code có thể panic. Panic đó unwind hay abort, service có bị cô lập hay khởi động lại, và failure ảnh hưởng availability thế nào là các câu hỏi riêng đã được phân biệt ở Mục 3.2. Ownership hay borrow checker không quyết định các policy vận hành ấy thay application.

Chính xác hơn là phân lớp trách nhiệm thay vì nói nó “chuyển giao”

Theo các phân biệt trên, câu “Rust chuyển trách nhiệm an toàn từ developer sang compiler” cũng quá rộng. Compiler và type system tự động kiểm tra các move, borrow và reference rule đã xác định. Tác giả unsafe code phải thỏa safety condition compiler không thể xác minh, còn tác giả library phải duy trì soundness của safe API. Application vẫn phải xử lý domain invariant, Result và panic policy, resource exhaustion, timeout và recovery; ở giai đoạn triển khai/vận hành vẫn còn trách nhiệm riêng về dependency, FFI, observability, failure containment, rollback và các vấn đề liên quan.

Trong môi trường quy mô lớn, chạy dài hạn và cực đoan, không nên gộp các lớp này thành “compile được thì an toàn”. Tối thiểu cần đánh giá unsafe/FFI surface, dependency và compiler/library soundness assumption, chi phí lúc chạy như borrow check và reference counting, panic và recovery policy, resource ceiling, tail latency, build/verification cost cùng workload thực tế. Đây là việc áp dụng tiêu chí đa trục của Mục 3.7 vào ownership enforcement.

Kết luận tạm thời

Đặc trưng kỹ thuật của Rust có thể được mô tả chính xác hơn câu “compiler cưỡng chế các ý tưởng có trước”. Trong Safe Rust, các ràng buộc quan trọng về ownership, move và borrowing được gắn rộng với cách dùng ngôn ngữ thông thường và type checking; một số điều kiện chuyển sang run-time check bên trong safe abstraction như RefCell; còn invariant mức thấp compiler không thể xác minh tạo thành ranh giới của unsafe proof obligation tường minh và sound abstraction. C++ cũng có các quy tắc thực sự được compiler thực thi qua RAII và ownership-aware type, nhưng phạm vi raw/custom lifetime boundary và guideline/tool enforcement khác nhau.

Vì vậy trọng tâm so sánh không phải “developer hay compiler”, cũng không phải “tùy chọn hay bắt buộc”, mà là property nào được enforce ở đâu, dưới điều kiện nào, và trách nhiệm proof, logic, failure, resource, operation còn nằm ở đâu bên ngoài ranh giới ấy. Tiêu chí này cho phép thừa nhận lợi thế memory safety của Rust mà không mở rộng compiler enforcement thành bảo đảm về functional correctness, panic recovery, availability hay an toàn toàn hệ thống. Mục 4.3 mở rộng so sánh cơ chế bảo đảm này sang contract và proof của Ada/SPARK.

4.3 Rust, Ada và SPARK: Ranh giới của sở hữu, truy cập, hợp đồng và chứng minh

Như Mục 4.2 đã cho thấy, cơ chế bảo đảm không thể chia thành hai ô “compiler tự động ngăn” và “developer viết contract”. Mục này so sánh ownership/borrowing của Rust, access type và language-defined run-time check của Ada, cùng Memory Ownership Policy và contract/proof của SPARK theo các trục chung: cấu trúc dữ liệu có thể biểu diễn, ràng buộc aliasing và mutation, vị trí kiểm tra, proof scope, escape boundary và chi phí thực thi. Như đã giới hạn ở Mục 4.2, unsafe proof obligation của Rust không đồng nghĩa với machine-checked formal proof; proof của SPARK cũng chỉ nên được diễn giải trong phạm vi code, contract và assumption mà phân tích thực sự khép kín.

Danh sách liên kết đôi là ví dụ hữu ích để bộc lộ các khác biệt này, nhưng trước hết phải thu hẹp đơn vị so sánh. Một danh sách liên kết đôi được đóng gói mà node không lộ ra ngoài như container chuẩn, một cấu trúc dạng graph chia sẻ nơi nhiều object giữ node handle lâu dài, và một intrusive structure nơi node được nhúng trong object khác là những bài toán khác nhau. Dùng một ví dụ code làm đại diện cho tất cả sẽ trộn lẫn khả năng biểu đạt của ngôn ngữ, thiết kế library, ranh giới an toàn và chi phí hiệu năng.

Rust: phân biệt biểu diễn an toàn và quan hệ sở hữu thay vì nói rằng cấu trúc chu kỳ bị cấm

Thư viện chuẩn Rust cung cấp std::collections::LinkedList<T>, một danh sách liên kết đôi có safe public API. Tài liệu chính thức mô tả nó là doubly-linked list có owned node và nói rõ rằng với phần lớn workload thông thường, Vec hoặc VecDeque thường nhanh hơn, tiết kiệm bộ nhớ hơn và tận dụng CPU cache tốt hơn.66 Vì vậy, khẳng định rằng Rust không thể hiện thực danh sách liên kết đôi an toàn nếu không nhất thiết dùng Rc<RefCell<...>> là sai.

Bài toán thay đổi khi cấu trúc dữ liệu trực tiếp lộ node identity và handle được chia sẻ ra ngoài. Rc<T> cung cấp single-threaded shared ownership, RefCell<T> có thể chuyển kiểm tra borrowing sang run time, và back-reference có thể dùng Weak<T> để tránh strong reference-count cycle. Tuy nhiên đây chỉ là một biểu diễn library-level khả dĩ, không phải đáp án duy nhất cho danh sách liên kết đôi trong Rust. Các thiết kế khác gồm arena/index handle, generational handle, container API được đóng gói, hoặc một unsafe implementation nhỏ duy trì invariant cần thiết.

Cũng không nên nói Rust cấm reference cycle ở cấp ngôn ngữ. Rust Book cho thấy Rc<T>RefCell<T> có thể tạo strong-reference cycle, khiến value không được drop và gây memory leak. Weak<T> là reference không biểu đạt ownership và có thể phá ownership cycle như vậy.66 Theo phân biệt ở Mục 3.2, leak này là vấn đề resource/availability chứ không phải memory-safety UB.

Ada: access type cho phép biểu diễn chu kỳ và chia sẻ, nhưng khả năng biểu đạt ấy không phải automatic memory-safety proof

access type thông thường của Ada có thể trực tiếp biểu diễn cấu trúc trong đó PrevNext của node chỉ tới các node khác. Language-defined check có thể phát hiện lỗi lúc chạy trong các điều kiện như giải tham chiếu null access và nhiều vi phạm range/overflow rồi phát sinh exception. Tuy nhiên, như Mục 3.4 đã xác lập, unchecked operation, explicit deallocation, external interface và lifetime protocol vẫn để lại proof hoặc review obligation riêng. Vì vậy, có thể biểu diễn cấu trúc trực tiếp không đồng nghĩa với tự động chứng minh không có dangling access, double deallocation, leak hay protocol error.52

Ada contract cũng là một lớp riêng. precondition, postcondition và type invariant có thể được cấu hình để kiểm tra lúc chạy, đồng thời có thể làm specification cho SPARK analysis. Vì thế, gộp “Ada/SPARK” thành một model “được tự do dùng pointer đổi lại việc viết contract” sẽ làm mất khác biệt giữa ngôn ngữ Ada và SPARK subset.

SPARK: hạn chế pointer aliasing mạnh hơn unrestricted Ada và trên trục này có ownership discipline có thể so sánh với Rust

SPARK User’s Guide nói rõ Memory Ownership Policy áp dụng cho access value để hạn chế arbitrary aliasing. Mutable memory có thể có một read-write owner tại một thời điểm, hoặc nhiều tên chỉ giữ read-only permission. Gán một access object có thể move ownership và loại bỏ read/write permission khỏi source; borrowing và observing cũng được điều chỉnh bằng các quy tắc riêng.67

Mục đích của các hạn chế này là làm cho memory được pointer chỉ tới có thể formal verification. Một hệ quả quan trọng là SPARK hạn chế hơn unrestricted Ada đối với cyclic hoặc shared pointer graph. SPARK User’s Guide hiện tại giải thích rằng pointer-based data structure có thể được hiện thực và xác minh khi không chứa cycle hay sharing; singly linked list và tree điển hình là các ví dụ được hỗ trợ, trong khi doubly linked list và DAG không được hỗ trợ ở conventional pointer form.67

Tuy nhiên, hạn chế này liên quan đến việc biểu diễn trực tiếp cyclic/shared pointer graph bên trong ownership model của SPARK; nó không có nghĩa rằng abstract data structure “danh sách liên kết đôi” không thể dùng trong SPARK.

SPARK Libraries cung cấp SPARK.Containers.Formal.Doubly_Linked_ListsSPARK.Containers.Formal.Unbounded_Doubly_Linked_Lists, và guide chính thức khuyến nghị dùng container abstraction thay cho pointer-intensive structure khi thực tế cho phép.

Đồng thời, visible specification và contract của formal container nằm trong SPARK, nhưng private part và implementation nằm ngoài SPARK. Vì vậy GNATprove có thể chứng minh client code dùng container đúng theo contract, nhưng client proof ấy tự nó không chứng minh container implementation thỏa specification.68

Do đó không thể giữ bảng cũ “Rust restrictive by default, Ada/SPARK permissive by default”. Phải tách khả năng biểu đạt của unrestricted Ada khỏi SPARK verification subset, đồng thời thừa nhận SPARK dùng chính hạn chế ownership và aliasing làm điều kiện cho khả năng xác minh. Khi cần doubly linked relation, phải phân biệt giữa việc giữ explicit pointer graph làm verification target trực tiếp, dùng SPARK formal container hoặc wrapper của nó, thay đổi data structure/traversal algorithm để phù hợp ownership policy, hoặc đặt một phần implementation sau full-Ada boundary. Lựa chọn cuối không hẳn là lời giải SPARK proof mà là ranh giới thu hẹp analysis scope của GNATprove; mỗi lựa chọn làm thay đổi proof scope, implementation phải tin cậy và run-time/resource cost.68

SPARK proof và Rust unsafe obligation không phải cùng một loại “chứng minh”

Trong SPARK, GNATprove thực hiện flow analysis và proof; Stone/Bronze/Silver/Gold/Platinum đã phân biệt ở Mục 3.4 là các verification objective khác nhau. Silver AoRTE hướng tới chứng minh không có Ada run-time error trong phạm vi được phân tích, nhưng Storage_Error nằm ngoài phạm vi đó; integrity và functional property ở Gold/Platinum cũng chỉ có ý nghĩa khi contract liên quan biểu đạt đầy đủ yêu cầu và code chưa phân tích cùng external assumption được biện minh.53

unsafe proof obligation của Rust có nghĩa tác giả phải biện minh và duy trì safety condition mà compiler không thể xác minh; obligation có thể được discharge bằng run-time check hoặc data-structure invariant. Ngược lại, SPARK proof bao gồm quá trình GNATprove discharge bằng máy các verification condition đã nêu. Hai mechanism cùng có điểm kỹ thuật rằng ai đó vẫn chịu trách nhiệm cho điều kiện ngoài ranh giới tự động, nhưng dạng evidence, mức tự động hóa, proof target và trusted assumption khác nhau.

So sánh trường hợp danh sách liên kết đôi theo cùng đơn vị

Trục so sánh Safe Rust / Rust library Ada SPARK
Dùng danh sách liên kết đôi thông thường Có safe API của LinkedList<T> chuẩn Có thể biểu diễn bằng library/container hoặc access type Có formal doubly-linked-list abstraction trong SPARK Libraries; direct cyclic pointer graph vẫn chịu ownership-policy restriction
Direct Prev/Next pointer graph Khó trực tiếp biểu diễn long-lived cyclic mutable graph chỉ bằng safe reference, cần abstraction khác Có thể biểu diễn trực tiếp bằng access type thông thường Conventional pointer graph có cycle/sharing bị Memory Ownership Policy hạn chế
Shared ownership và back-reference Có thể kết hợp Rc/RefCell/Weak; strong Rc cycle có thể leak Lựa chọn thiết kế giữa access/controlled abstraction và cơ chế liên quan Chỉ được phép trong ownership/borrowing/observing rule; arbitrary aliasing bị hạn chế
Kiểm tra mutation Native borrow ở compile time; RefCell ở run time Phân tán giữa language check và application protocol flow/proof + ownership policy + run-time check cần thiết
Low-level escape boundary unsafe invariant và safe-abstraction soundness unchecked operation, raw representation, deallocation/FFI boundary SPARK_Mode => Off, external/non-SPARK code và assumption tạo proof boundary
Broader correctness proof General functional correctness cần specification/tool riêng Có thể biểu đạt contract và kiểm tra lúc chạy Có thể thực hiện AoRTE, integrity, functional proof theo từng mức với contract và assumption đã nêu; formal-container client proof không chứng minh private implementation tự nó thỏa specification

Bảng này không nhằm nén các ngôn ngữ thành một thứ hạng “linh hoạt hơn” hay “an toàn hơn”. Ngay với cùng doubly linked list, cost structure thay đổi tùy việc tái dùng standard container, lộ node identity ra ngoài, cần intrusive layout, phải kiểm soát allocator, hay có worst-case latency và memory ceiling.

Trong môi trường quy mô lớn và cực hạn, đặc biệt cần kiểm tra representation cost bằng benchmark và resource bound. Tài liệu chuẩn Rust nói trực tiếp rằng Vec/VecDeque dựa trên mảng thường nhanh hơn, hiệu quả bộ nhớ hơn và cache-friendly hơn LinkedList.66

SPARK formal container cũng không có một cost model duy nhất: bounded definite formal container không dùng dynamic allocation, còn unbounded indefinite formal container dùng dynamic allocation cho element và việc mở rộng internal storage.68

Vì vậy reference counting của Rc, run-time borrow check của RefCell, access/allocation representation được chọn trong Ada, container variant hoặc pointer representation của SPARK, cùng proof effort tạo ra các CPU, memory, latency và verification cost khác nhau. Không thể quyết định cost nào chi phối nếu không đo workload, hardware, lifetime pattern, allocator policy và proof objective.

Kết luận tạm thời

Trường hợp danh sách liên kết đôi không ủng hộ kết luận “Rust ownership chặn cấu trúc dữ liệu phức tạp còn Ada/SPARK giải quyết tự do bằng contract”. Rust có thể cung cấp danh sách liên kết đôi qua safe API; khi thiết kế shared node graph trực tiếp phải nêu rõ chi phí ownership/borrowing và runtime/unsafe abstraction. Ada dễ biểu diễn trực tiếp cyclic pointer structure, nhưng khả năng biểu đạt ấy tự nó không phải lifetime safety hay whole-correctness proof. SPARK, với tư cách Ada subset, áp ownership restriction lên pointer aliasing và hạn chế conventional cyclic pointer graph, đồng thời cung cấp formal doubly-linked-list container abstraction. Ngay ở đây, proof về client use và việc library implementation thỏa specification vẫn là hai verification boundary khác nhau.68

Vì vậy trọng tâm so sánh không phải ngôn ngữ nào hạn chế hơn, mà với data structure và property cần thiết, chọn representation nào, error nào được language/type/runtime/proof loại bỏ, invariant và assumption nào vẫn do con người duy trì, và lựa chọn ấy ảnh hưởng thế nào tới performance, resource và verification cost. Góc nhìn này đặt Ada/SPARK assurance boundary của Mục 3.4 và Rust enforcement boundary của Mục 4.2 lên cùng một cơ sở kỹ thuật.


Phần 3: Thực tế hệ sinh thái và chi phí cấu trúc

Phần 3 phân tích những thách thức thực tế mà hệ sinh thái Rust đối mặt và chi phí cấu trúc phía sau. Khi đánh giá trải nghiệm nhà phát triển, nguyên tắc trừu tượng hóa không chi phí và các ràng buộc áp dụng công nghiệp, hữu ích là phân biệt hai loại vấn đề.

  1. Vấn đề trưởng thành: Thiếu thư viện, một số công cụ không ổn định, tài liệu chưa đầy đủ và vấn đề tương tự có thể tự nhiên được giải quyết hoặc giảm nhẹ khi thời gian và nỗ lực cộng đồng tích lũy. Đây là vấn đề trưởng thành chung của các hệ sinh thái công nghệ đang phát triển.

  2. Đánh đổi thiết kế nội tại: Chúng phát sinh khi ngôn ngữ cố ý hy sinh một giá trị—dễ học, tốc độ biên dịch, hay tính linh hoạt khi hiện thực mẫu cụ thể—để đạt các giá trị cốt lõi như hiệu năng thời gian chạy và an toàn bộ nhớ không GC. Vì là lựa chọn chứ không phải khiếm khuyết, chúng khó biến mất chỉ theo thời gian.

Dùng khung này, các chương sau phân biệt và đánh giá bản chất của các thách thức kỹ thuật Rust.

5. Thành tựu và chi phí của trải nghiệm nhà phát triển

Câu hỏi của Chương 5 không đơn giản là Rust có “khó” hay “năng suất” hay không. Câu hỏi chính xác hơn là những cơ chế nào của ngôn ngữ, trình biên dịch, thư viện và công cụ tạo ra những trải nghiệm phát triển nào, và bằng chứng có thể được mở rộng đến đâu từ trải nghiệm học tập của cá nhân sang năng suất của đội và tổ chức.

Trải nghiệm nhà phát triển (DX) ở đây không phải một con số duy nhất. Việc học và hình thành mô hình tinh thần, chẩn đoán của trình biên dịch và phản hồi edit-build-test, hiện thực, refactoring, code review và debugging, tìm hiểu thư viện và phụ thuộc, tài nguyên build/CI, cùng trải nghiệm vận hành và bảo trì là những trục khác nhau. Năng suất cũng không thể rút gọn thành “biên dịch có nhanh không” hay “mã có ít dòng không”; cần nêu rõ khối lượng công việc và tổ chức nơi đo thời gian hoàn thành nhiệm vụ, rework, defect escape, review cycle, chi phí training/mentoring và chi phí bảo trì dài hạn.

Mục 5.1 dùng bộ kiểm tra mượn và việc học ownership/lifetime làm trường hợp để xác lập ranh giới bằng chứng này. Mục 5.2 xem xét lập luận tổng quát hóa một lựa chọn công nghệ sang lĩnh vực vấn đề khác; Mục 5.3-5.4 xem chi phí cụ thể của async và xử lý lỗi; Mục 5.5-5.7 xem thư viện, chuỗi công cụ và môi trường build. Mỗi mục tách sự thật về cơ chế ngôn ngữ khỏi kết quả quan sát ở người dùng, đội và tổ chức.

5.1 Bộ kiểm tra mượn, đường cong học tập và năng suất: ranh giới của bằng chứng

Câu “năng suất Rust thấp vì borrow checker khó” gộp bốn loại tuyên bố khác nhau vào một câu.

Cấp độ tuyên bố Cần xác lập điều gì Bằng chứng thích hợp
hành vi ngôn ngữ/trình biên dịch Quan hệ move, borrow và tham chiếu nào bị từ chối lúc biên dịch? Rust Reference, Book chính thức, chẩn đoán trình biên dịch
learnability Khái niệm nào được người học nào cảm thấy khó hoặc hiểu sai? thí nghiệm học tập, nghiên cứu người dùng, survey có phạm vi rõ
task-level productivity Thời gian hiện thực, sửa đổi, debugging và review thay đổi thế nào với một nhiệm vụ cụ thể? task có thể so sánh, nghiên cứu quan sát, thí nghiệm
team/organization outcome Hiệu ứng ròng lên onboarding, lịch, bảo trì và chi phí defect/incident là gì? dữ liệu project dài hạn, so sánh cấp tổ chức, phân tích yếu tố gây nhiễu

Cấp thứ nhất có thể được xác lập trực tiếp từ tài liệu ngôn ngữ; ba cấp sau cần bằng chứng thực nghiệm riêng. Đặc biệt, việc trình biên dịch từ chối một đoạn mã không tự nó cho phép suy luận lịch hay chi phí của tổ chức.

Bảo đảm kỹ thuật: không đồng nhất toàn bộ ownership với bộ kiểm tra mượn

Trình biên dịch Rust kiểm tra các quy tắc ownership. Trong ngữ cảnh chuyển ownership như phép gán hoặc đối số hàm by-value, giá trị non-Copy được move còn giá trị Copy có thể được copy. Rust cũng giới hạn tĩnh các điều kiện như tính hợp lệ của tham chiếu và xung đột giữa shared/mutable borrow. Tuy nhiên, như Mục 4.2 đã phân biệt, không phải mọi cơ chế liên quan ownership đều được bộ kiểm tra mượn xử lý tại một nơi và theo cùng một cách. Rc<T> cung cấp shared ownership ở cấp thư viện, RefCell<T> chuyển một phần kiểm tra borrow sang thời gian chạy, còn unsafe không phải ngoại lệ đơn giản tắt kiểm tra thông thường; nó tạo obligation riêng cho những safety condition mà trình biên dịch không thể xác minh trực tiếp.69

Vì vậy, mở rộng giải thích sư phạm “one owner” thành “mọi giá trị luôn chỉ có một binding” là không chính xác. Giá trị Copy có thể được copy qua phép gán hoặc truyền hàm; borrowing cho phép truy cập mà không chuyển ownership, và nhiều shared reference có thể cùng tồn tại. Trừu tượng thư viện như Rc<T> biểu đạt quan hệ sở hữu khác, chẳng hạn shared ownership qua reference counting. Quy tắc tham chiếu của Safe Rust chặn dangling reference và mutable aliasing bị cấm trong phạm vi Safe Rust sound, nhưng không tự động bảo đảm correctness hay availability của toàn hệ thống, bao gồm biên unsafe, FFI và soundness đã nêu ở Mục 3.2.

Chú thích lifetime cũng không phải ký hiệu kéo dài thời gian sống của đối tượng lúc chạy hay cấp một thời gian sống mới. Như Book chính thức giải thích, chú thích mô tả quan hệ giữa các lifetime của tham chiếu, và trong nhiều trường hợp không cần viết trực tiếp nhờ lifetime elision và inference. Sự xa lạ của tình huống cần chú thích có thể tạo chi phí học, nhưng chính xác hơn là nói chú thích biểu đạt quan hệ để trình biên dịch xác minh tính hợp lệ của tham chiếu, thay vì nói “lifetime được viết ra tự nó ngăn dangling pointer”.69

Lỗi biên dịch không lập tức có nghĩa “thuật toán không an toàn” hoặc “cấu trúc dữ liệu không thể biểu đạt”

Phân tích tĩnh có thể giới hạn các representation được chấp nhận, và trình biên dịch đôi khi không thể trực tiếp kiểm tra invariant mà lập trình viên dự định. Như ví dụ split_at_mut ở Mục 4.2, một safe API có thể thiết lập một unsafe invariant hẹp ở bên trong; hoặc như Mục 4.3, chương trình có thể chọn representation khác như container, index/arena, reference counting hay run-time checking. Điều mà một lần từ chối của bộ kiểm tra mượn trực tiếp xác lập là representation hiện tại của chương trình bị từ chối vì không thỏa quy tắc tĩnh của Safe Rust. Chỉ từ đó không thể chứng minh bản thân vấn đề có semantic unsafety hay một cấu trúc dữ liệu cụ thể là bất khả thi.

Phân biệt này cũng quan trọng cho việc học. Lỗi biên dịch người mới gặp có thể là quan hệ tham chiếu thực sự phải bị cấm, thiết kế cần representation ownership khác, hoặc trường hợp phải ghi quan hệ lifetime trong signature. Chẩn đoán trình biên dịch vì vậy có thể vừa là chi phí ma sát vừa là công cụ học. 2024 State of Rust Survey báo cáo các trường hợp người trả lời “learned by doing” dùng error message của rustc và Clippy làm guide. Bài theo dõi học tập năm 2026 tổng kết nghiên cứu Rust Vision Doc thực hiện năm 2025 cũng cho biết nhiều interviewee mô tả chẩn đoán trình biên dịch là tài nguyên chính để học quan hệ lifetime và borrow.70

Khó khăn học tập được quan sát, nhưng không thể tổng quát thành một “đường cong học Rust” cố định

Bản thân chi phí học có bằng chứng thực nghiệm. Nghiên cứu mixed-methods tại ICSE 2022 phân tích 100 câu hỏi Stack Overflow liên quan Rust và khảo sát 101 Rust programmer, xác nhận khó khăn lặp lại khi hiểu và áp dụng ownership/lifetime safety rule. Nghiên cứu OOPSLA 2023 đánh giá một công cụ đo hiểu sai về ownership cùng một pedagogy mới; trong initial deployment, điểm Ownership Inventory cao hơn trung bình 9% so với original version (N = 342, d = 0.56). Nghiên cứu tiếp nối OOPSLA 2024 phân tích 1.140.202 câu trả lời quiz do 62.526 độc giả Book gửi trong 13 tháng, quan sát sự rời bỏ học tập quanh các khái niệm khó như ownership type, và báo cáo mười hai can thiệp giáo dục làm tăng điểm ở câu hỏi mục tiêu trung bình 20%.70

Các kết quả cho thấy đồng thời hai điều. Thứ nhất, ownership, borrowing và lifetime có thể tạo khó khăn học tập đo được. Thứ hai, độ khó không phải hằng số cố định của ngôn ngữ; nó có thể thay đổi theo cách giải thích, diagnostics, luyện tập, prior experience và mentoring. Trong 2024 State of Rust Survey, khoảng 31% người không dùng Rust nêu perceived difficulty là lý do chính không dùng Rust, còn 53% người trả lời tự đánh giá Rust expertise của mình ở mức productive. Nhưng khoảng 92% trong 7.310 câu trả lời hoàn chỉnh đến từ người dùng Rust và survey chủ yếu tiếp cận các nhà phát triển Rust hiện có, nên không thể tổng quát các con số này thành phân bố thời gian học hoặc năng suất của toàn bộ quần thể nhà phát triển.70

Rust Vision Doc process thu thập khoảng 4.200 câu trả lời survey và hơn 70 interview. Bài theo dõi học tập năm 2026 đưa ra các trường hợp prior experience, training trong tổ chức, mentoring và task ban đầu rủi ro thấp ảnh hưởng đường học. Tuy nhiên, nhóm nghiên cứu nêu rõ selection bias, đặc biệt khó tuyển đủ người đã từ chối hoặc ngừng dùng Rust, và phạm vi tập trung nhiều hơn vào individual developer experience thay vì toàn tổ chức. Vì vậy các pattern định tính này cho thấy sự đa dạng trải nghiệm và những cách hỗ trợ có thể có, chứ không ước lượng tần suất, thời gian ramp-up chuẩn hay tác động nhân quả lên năng suất cấp tổ chức.71

Chi phí học và năng suất ròng là hai biến khác nhau

Từ chối lúc biên dịch có thể tăng lượng công việc phải xử lý ngay trong lúc hiện thực. Ngược lại, chặn một số quan hệ tham chiếu sai trước khi chạy có thể giảm debugging hoặc sửa defect về sau. Hiệu ứng nào lớn hơn phụ thuộc task, codebase, defect mix, chất lượng phản hồi trình biên dịch, kinh nghiệm đội và quy trình review, test, CI; vì vậy không thể quyết định hiệu ứng ròng chỉ từ cơ chế ngôn ngữ.

Survey của chính Rust Project cũng thể hiện sự phân biệt này. Trong survey 2021, 83% người trả lời cho biết nơi làm việc đã áp dụng Rust đánh giá việc áp dụng là challenging, nhưng chỉ 13% nói Rust làm đội chậm lại và 82% nói Rust giúp đội đạt mục tiêu. Đây là self-report từ mẫu self-selected, không chứng minh ưu thế năng suất của Rust.

Phù hợp hơn là dùng nó như phản ví dụ cho suy luận từ khó học sang năng suất ròng: báo cáo rằng việc áp dụng khó và báo cáo rằng Rust giúp đội có thể cùng tồn tại.

2025 State of Rust Survey cũng báo cáo slow compile time, storage usage và debugging trong các vấn đề productivity không nhỏ, đồng thời survey team cảnh báo rõ không nên ngoại suy quá mức từ 7.156 câu trả lời và các mẫu số nhỏ hơn của câu hỏi tùy chọn.71

Do đó, mọi tuyên bố “năng suất” trong sách ít nhất phải nêu đơn vị đo. Việc học ban đầu có thể đánh giá bằng time-to-first-change, thời gian tới khi có thể bảo trì độc lập và thời gian mentoring. Luồng phát triển có thể đánh giá bằng thời gian hiện thực, review cycle, rework, defect escape và thời gian debugging. Trong repository lớn và môi trường cực hạn, cần tách không chỉ trung bình mà cả p50/p95 edit-build-test latency, chi phí CPU, memory, storage của CI, nút thắt chuyên gia và bus factor, cùng chi phí refactoring dài hạn. Nếu đồng thời quan sát ít lỗi an toàn hơn và thời gian phát triển dài hơn, cả hai phải đi vào mô hình chi phí thay vì che một phía.

Ranh giới của tuyên bố diễn ngôn

Khó học không phải chỉ báo về trí tuệ hay địa vị nghề nghiệp của nhà phát triển; ngược lại, học nhanh hoặc ngôn ngữ đơn giản hơn cũng không có nghĩa kém hơn về kỹ thuật. Phán xét địa vị hay năng lực như vậy phải tách khỏi bảo đảm kỹ thuật và đo năng suất; muốn tuyên bố tần suất hay quan hệ nhân quả cần tiêu chuẩn lấy mẫu diễn ngôn đã định nghĩa ở Mục 3.6. Mục 5.1 không tổng quát hành vi người học hay văn hóa tổ chức từ giai thoại trực tuyến.

Kết luận tạm thời

Bằng chứng hiện tại hỗ trợ kết luận rằng ownership, borrowing và lifetime của Rust có thể tạo chi phí học đáng kể cho một số người học. Đồng thời cũng có bằng chứng rằng pedagogy và diagnostics có thể cải thiện hiểu biết, và trải nghiệm học thay đổi theo prior experience cùng hỗ trợ tổ chức. Ngược lại, kết luận nhân quả phổ quát rằng chỉ sự tồn tại của bộ kiểm tra mượn tự nó làm giảm năng suất dự án hoặc làm xấu khả năng dự đoán lịch vượt quá bằng chứng hiện có.

So sánh kỹ thuật cần thiết vì vậy không phải một điểm số duy nhất xem đường cong học có “dốc” hay không, mà là chi phí học, hiện thực, build, debugging, review, defect, vận hành và bảo trì được tái phân bổ theo thời gian thế nào trong một tổ chức và khối lượng công việc cụ thể. Giữ tiêu chuẩn này cho phép công nhận lợi ích của bảo đảm compile-time của Rust mà không tự động mở rộng nó thành ưu thế năng suất, đồng thời công nhận chi phí học mà không tự động mở rộng thành bất lợi năng suất.

5.2 Xu hướng tổng quát hóa lựa chọn công nghệ và đánh đổi kỹ thuật

“Rust có lợi thế cho một vấn đề cụ thể” và “vì vậy nên mở rộng phạm vi áp dụng Rust hơn nữa” không phải cùng một mệnh đề. Mệnh đề thứ nhất nói về mức độ phù hợp giữa đặc tính của language, compiler, library, toolchain với một workload cụ thể; mệnh đề thứ hai là tuyên bố tổng quát hóa rằng kết quả đó có thể chuyển sang workload, project và organization khác. Thay vì mặc định mở rộng hay thu hẹp phạm vi của một công nghệ, mục này xem xét cần thêm bằng chứng gì khi một lợi thế có điều kiện được chuyển thành khuyến nghị lựa chọn công nghệ rộng hơn.

Một lập luận lựa chọn công nghệ ít nhất có thể tách thành bốn giai đoạn sau.

Giai đoạn của tuyên bố Cần kiểm tra gì Bằng chứng phù hợp
Đặc tính công nghệ language, compiler, runtime, library cung cấp bảo đảm hay đặc tính chi phí nào specification, tài liệu chính thức, benchmark có thể tái lập
Mức phù hợp workload đặc tính đó có quan trọng đối với defect model, latency, throughput, memory, real-time và deployment requirement của system hiện tại hay không requirement, production profile, load test, incident và defect data
Mức phù hợp so sánh dưới cùng requirement, tổng chi phí và rủi ro của các công nghệ ứng viên khác nhau thế nào so sánh cùng workload, prototype, migration experiment, dữ liệu lifecycle cost
Khả năng tổng quát hóa kết quả của một project có thể chuyển sang domain, tổ chức hay giai đoạn khác không dữ liệu nhiều project và tổ chức, sampling rõ ràng, longitudinal data, phân tích confounder

Lợi thế mạnh ở giai đoạn đầu không làm các giai đoạn sau tự động đúng. Ngược lại, việc Rust không được chọn trong một project cụ thể cũng không có nghĩa Rust không có lợi thế kỹ thuật. Như Mục 3.7 đã tổng kết, defect model, ranh giới bảo đảm, chi phí thực thi, assurance, chiến lược thay đổi, chi phí tổ chức và lifecycle là các trục so sánh khác nhau.

“Luật của công cụ” là cảnh báo phương pháp luận, không phải quy luật nhân quả riêng của Rust

“Law of the instrument” được Abraham Kaplan bàn trong The Conduct of Inquiry năm 1964 và phép ví von hammer của Abraham Maslow trong The Psychology of Science năm 1966 có thể dùng như một cảnh báo phương pháp luận rằng phương pháp quen thuộc hoặc thành thạo có thể thu hẹp cả cách định nghĩa vấn đề.72 Tuy nhiên, các tác phẩm này không phải nghiên cứu về Rust developer và cũng không đo hiệu ứng nhân quả trong đó thời gian học một programming language cụ thể tạo tâm lý sunk-cost-like rồi mở rộng phạm vi áp dụng của nó.

Vì vậy, nếu muốn giữ cách giải thích trong bản cũ rằng “nỗ lực đầu tư để học Rust có thể dẫn đến thử áp dụng rộng hơn” như một cơ chế đã quan sát của việc áp dụng Rust, cần có bằng chứng riêng. Ví dụ: longitudinal data theo dõi tập ứng viên và tiêu chí đánh giá trước/sau khi học, architecture decision record thực tế, mẫu tổ chức có thể so sánh, và nghiên cứu kiểm soát requirement cùng stack hiện có. Không có những dữ liệu như vậy thì không suy ngược động cơ hay tâm lý developer chỉ từ kết quả lựa chọn.

Hơn nữa, sự quen thuộc tự nó không phải lúc nào cũng là bias. Technology choice trong software architecture còn xem xét tool sẵn có, familiarity nội bộ, external support, side effect của lựa chọn và compatibility với stack hiện có.73

Trong 2024 State of Rust Survey, 21% người trả lời dùng Rust tại nơi làm việc nói họ dùng Rust vì đã biết nó và do đó coi nó là default choice.74 Đây là bằng chứng rằng familiarity được self-report như lý do lựa chọn trong mẫu đó; không phải bằng chứng lựa chọn là phi lý hay là “golden hammer”.

Expertise, kiến thức vận hành, build infrastructure và tài sản training đã có có thể thay đổi switching cost và failure risk thực tế, nên chỉ kết quả lựa chọn không thể phân biệt cognitive bias với lifecycle cost hợp lý.

Lựa chọn công nghệ không phải bảng xếp hạng một ưu điểm, mà là so sánh các requirement đã nêu rõ

Điều này không có nghĩa memory safety, không có GC, latency thấp, phát triển nhanh, library ecosystem hay formal assurance là không quan trọng. Trong một môi trường cụ thể, một requirement có thể là hard constraint làm thu hẹp mạnh tập ứng viên. Vấn đề xuất hiện khi một ưu điểm trên một trục được biến thành xếp hạng toàn bộ công nghệ mà không nêu điều kiện khiến trục đó quan trọng.

Khi so sánh công nghệ ứng viên trong môi trường quy mô lớn hoặc cực hạn, để có thể tái lập nên ghi ít nhất các mục sau trong decision record.

Trục đánh giá Câu hỏi cần ghi
workload và resource ngoài steady-state, cần gì ở p50/p95/p99 tail latency, peak throughput, memory headroom, startup, code size và worst-case timing
defect và assurance trong memory error, data race, logic error, resource exhaustion, availability failure, loại nào phải được phòng ngừa, phát hiện hoặc chứng minh tới boundary nào
ecosystem và integration protocol, database, SDK, library, platform, native dependency, observability cần thiết và build/deploy stack hiện có có thật sự được hỗ trợ không
staffing và workflow chi phí của expertise hiện tại, hiring, onboarding, mentoring, review, debugging, expert concentration và bus factor là bao nhiêu
migration và operation có interoperability với tài sản hiện có, chuyển đổi theo giai đoạn, rollback, incident response, data migration và vận hành song song hay không
lifecycle và toolchain CPU, memory, storage của build/CI, dependency update, security response, toolchain support, refactoring dài hạn và rewrite opportunity cost tích lũy ra sao

Bảng này không phải empirical result báo cáo hiệu ứng trung bình của một ngôn ngữ cụ thể, mà là decision procedure để tránh bỏ sót điều kiện quan trọng trong so sánh. Trọng số và tiêu chí đạt thực tế phải xuất phát từ requirement của project.

Các tiêu chí này cũng không nhằm tạo kết luận rằng một ngôn ngữ luôn vượt trội. Ví dụ, nếu memory-safety defect là rủi ro chính và workload đồng thời đòi hỏi low-level control cùng resource budget chặt, việc đặt trọng số cao cho lợi thế có điều kiện của Rust có thể hợp lý. Ngược lại, nếu bottleneck của application nằm ở database hoặc external service và rủi ro chính của tổ chức là tốc độ thay đổi chức năng, integration với framework hiện có và nguồn nhân lực, các trục khác có thể quan trọng hơn. Trong mọi trường hợp, không nên mở rộng một đặc tính thành phán quyết tổng thể như “có GC nên không phù hợp”, “không có static type nên không ổn định”, hay “Rust khó nên năng suất thấp” khi chưa có requirement và measurement thực tế.

Web backend là lĩnh vực sử dụng thực tế cần nêu điều kiện, không phải bằng chứng của “áp dụng quá mức”

Bản cũ trực tiếp coi việc đề xuất Rust cho một số web backend thông thường là ví dụ tổng quát hóa. Phạm vi diễn đạt đó quá rộng. 2024 State of Rust Survey báo cáo server backend, web/networking service và cloud technology là những technology domain đặc biệt phổ biến trong người trả lời.74 Như Mục 5.1 đã xác nhận, khoảng 92% trong 7.310 câu trả lời hoàn chỉnh là Rust user và survey chủ yếu nhắm tới Rust developer hiện có, nên không thể dùng nó để ước lượng market share toàn bộ backend hay ưu thế tương đối. Nhưng tài liệu này cũng không hỗ trợ tiền đề rằng bản thân domain backend là cách dùng Rust bất thường hoặc vốn nằm ngoài mục đích của nó.

Vì vậy, đối tượng cần xem xét không phải “có dùng Rust cho backend hay không” mà là các điều kiện đi kèm tuyên bố. Nếu tail latency, memory footprint, requirement về memory safety và concurrency defect model thật sự là yêu cầu cốt lõi của một API gateway hay service cụ thể, và benchmark cùng dữ liệu vận hành cho thấy phù hợp, việc chọn Rust có thể có căn cứ kỹ thuật trực tiếp trong điều kiện đó. Ngược lại, chỉ các nhãn như SaaS, internal system hay commerce service cũng không thể quyết định Go, Java, C#, Python hay Rust phù hợp hơn. Phải so sánh database latency, deployment model, framework dependency, team expertise, security requirement, traffic distribution và tài sản hiện có theo cùng tiêu chí.

Tính đối xứng này cũng áp dụng cho tổng quát hóa tiêu cực. Tuyên bố “memory safety và runtime performance của Rust là lợi thế nên Rust phải là default cho mọi backend” cần bằng chứng để mở rộng sang workload khác; tuyên bố “Rust có chi phí học nên không phù hợp với web backend thông thường” cũng cần dữ liệu so sánh ở cùng mức độ. Trường hợp thành công hay chi phí có điều kiện có thể cho biết khả năng và failure condition, nhưng không có thiết kế sampling thì không thể quyết định hiệu ứng trung bình của toàn domain.

Tách sự tồn tại và tần suất của diễn ngôn khỏi nguyên nhân lựa chọn công nghệ

Tiêu chuẩn sampling đã định nghĩa ở Mục 3.6 được áp dụng nguyên vẹn. Nếu trong một bài đăng công khai được chọn có lập luận “công nghệ này có một ưu điểm nên cũng phải dùng ở domain khác”, điều đó có thể cho thấy sự tồn tại của dạng lập luận ấy. Nhưng không có corpus và sampling được định nghĩa trước thì không thể ước lượng lập luận đó có phổ biến hay chi phối trong Rust community hay không, hoặc nó thay đổi adoption decision thực tế bao nhiêu.58 Suy từ vài giai thoại ngược chiều rằng Rust user không tổng quát hóa cũng là cùng một lỗi.

Kết luận tạm thời

Tài liệu hiện đã kiểm tra trực tiếp hỗ trợ ba kết luận. Thứ nhất, “luật của công cụ” và phép ví von hammer cung cấp câu hỏi phương pháp luận để kiểm tra liệu phương pháp quen thuộc có đang thu hẹp cách định nghĩa vấn đề hay không. Thứ hai, technology choice phải so sánh tooling, expertise, compatibility, migration, operation và lifecycle cost cùng với workload và quality attribute. Thứ ba, Rust thực tế được dùng trong server backend và web/networking, nên bản thân việc áp dụng cho backend không thể được coi là bằng chứng của tổng quát hóa.

Ngược lại, bằng chứng hiện tại không đủ để kết luận về nhân quả, tần suất hay hiệu ứng trung bình rằng developer học Rust mở rộng phạm vi áp dụng vì chi phí đã đầu tư, Rust community thực hiện golden-hammer reasoning thường xuyên hơn người dùng ngôn ngữ khác, hoặc Rust nhìn chung vượt trội hay kém hơn trong web backend thông thường. Những kết luận như vậy cần quần thể developer và organization hoặc discourse corpus được định nghĩa trước, decision data ghi lại công nghệ ứng viên và requirement, chỉ số chi phí, defect và vận hành từ workload giống hệt hoặc có thể so sánh, cùng nghiên cứu xử lý confounder như expertise, legacy, deadline và thay đổi architecture. Kết luận kỹ thuật của mục này hẹp hơn: lợi thế của công nghệ có thể là căn cứ áp dụng, nhưng phạm vi áp dụng phải do requirement rõ ràng và bằng chứng so sánh quyết định, không phải do tên gọi của lợi thế.

5.3 Độ phức tạp và đánh đổi kỹ thuật của mô hình lập trình bất đồng bộ

Khi đánh giá async/await của Rust, cần tách Future model do ngôn ngữ định nghĩa, hiện thực executor và I/O runtime, lựa chọn API trong library ecosystem, FFI boundary, và chi phí quan sát trong một workload cụ thể. Bản cũ gộp các tầng này thành một “mô hình bất đồng bộ” rồi mô tả conceptual complexity, ecosystem fragmentation và interoperability cost như các thuộc tính cố định của Rust. Câu hỏi ở đây hẹp hơn: Rust async được thiết kế để giảm chi phí nào, lựa chọn đó tạo ra chi phí và integration boundary nào khác, và bằng chứng hiện tại cho phép tổng quát các chi phí ấy tới đâu?

async không loại bỏ executor; đó là Future model đặt execution policy bên ngoài ngôn ngữ

Theo Rust Reference, gọi async fn không lập tức chạy thân hàm mà trả về một Future capture các đối số; thân hàm tiến triển khi future được poll. Operation cốt lõi của standard Future trait cũng là poll(self: Pin<&mut Self>, cx: &mut Context<'_>). Official Async Book mô tả đây là “zero-cost” async nhưng đồng thời nêu rõ Rust không cung cấp built-in runtime, và community crate cung cấp runtime.75

Vì vậy không nên đọc “zero-cost” thành “không có chi phí executor, scheduler, I/O driver, timer hay task management”. Phạm vi trực tiếp của tuyên bố chính thức là lợi thế thiết kế rằng async không bắt buộc heap allocation hay dynamic dispatch, và có thể chạy nhiều I/O-bound task trên số ít OS thread. Application thực tế vẫn có thể cần tầng thực thi liên tục poll future và truyền I/O readiness cùng timer; chi phí hiện thực và cấu hình tầng đó phải được đo riêng với cú pháp ngôn ngữ.

Độ phức tạp của Pin là có thật, nhưng phải phân biệt ranh giới nơi nó lộ ra

Future do compiler tạo lưu local state tồn tại qua các điểm await, và giữa các state đó có thể hình thành phụ thuộc địa chỉ. Pin là contract để address-sensitive value như vậy duy trì quan hệ địa chỉ hợp lệ; compiler-generated Future là một trường hợp sử dụng tiêu biểu. Tuy nhiên, official Async Book giải thích rằng trong cách dùng async/await thông thường, compiler xử lý pinning nên developer thường không cần ý thức trực tiếp các chi tiết này.76

Ranh giới nơi Pin trực tiếp xuất hiện với người dùng cụ thể hơn. Khi poll future hoặc stream trực tiếp, xử lý concrete type của boxed future, hiện thực custom Future, hoặc viết low-level library cần pin projection, developer có thể phải hiểu Pin, Unpin, projection và safety contract liên quan. Do đó, cả tổng quát hóa “muốn dùng Rust async thì mọi developer phải hiểu sâu self-referential structure và Pin” lẫn khẳng định ngược lại “Pin chỉ là chi tiết nội bộ compiler nên không có chi phí” đều không chính xác.

Vấn đề usability này cũng không chỉ là phê bình bên ngoài. Năm 2025 Rust project thúc đẩy công việc đưa trải nghiệm async Rust gần hơn với sync Rust và cải thiện Pin ergonomics; 2026 project goals cũng có Continue Experimentation with Pin Ergonomics. Phần tổng kết open answer của 2024 State of Rust Survey cũng nhắc khó khăn với async programming trong các vấn đề hạn chế productivity.77 Tuy nhiên, open answer của survey không phải controlled study về tỷ lệ xuất hiện trong toàn quần thể hay chi phí học tương đối so với Go, Java hoặc C#. Bằng chứng này hỗ trợ rằng vấn đề tồn tại và được nhìn nhận là đối tượng cần cải thiện, không hỗ trợ kết luận “năng suất Rust async trung bình thấp hơn bao nhiêu”.

Đa dạng runtime và ecosystem coupling là hai mặt của cùng một lựa chọn thiết kế

Rust standard library cung cấp interface thực thi tối thiểu là Future nhưng không cố định một executor cụ thể làm standard runtime. Cấu trúc này cho phép chọn các chiến lược thực thi khác nhau như single-thread, multi-thread và embedded. Đồng thời, các chức năng application cần như task spawning, I/O driver, timer, asynchronous I/O type và shutdown nằm trong runtime hoặc library API, nên chỉ việc hai library cùng trả về Future không bảo đảm end-to-end interoperability.78

Nhưng biến điều này thành mệnh đề toàn diện “phụ thuộc Tokio thì mất compatibility với runtime khác” cũng quá mạnh. Tài liệu Tokio hiện tại giải thích runtime kết hợp I/O driver, scheduler và timer, đồng thời nêu phần lớn synchronization primitive trong tokio::sync là runtime-agnostic, với ngoại lệ như một số operation timeout cần timer. Vì vậy đơn vị coupling không phải “toàn bộ Rust async” mà là API và resource driver dependency thực sự sử dụng. Khi chuyển sang runtime hay library khác phải kiểm tra dependency graph về adapter, feature flag, chuyển đổi I/O trait, task-local state, cùng timer và cancellation semantics cần thiết.

Sự phân biệt này quan trọng đối với maintainability. Tự do chọn runtime cho phép scheduler và resource policy phù hợp một môi trường cụ thể, nhưng system quy mô lớn chạy dài hạn cũng phải xem runtime-specific API lan vào public interface tới đâu, có lý do đặt nhiều runtime trong một process hay không và chi phí là gì, blocking operation có chiếm executor thread hay không, và shutdown cùng backpressure đi qua library boundary thế nào. Bản thân sự thật “không có standard runtime” không phải phán quyết về ưu hay nhược điểm; đó là điều kiện thiết kế quyết định các chi phí lựa chọn này được trả ở đâu.

Vấn đề async FFI không phải là “không thể”, mà là ABI không định nghĩa execution protocol

Rust có thể trao đổi foreign function và value qua C ABI, nhưng C ABI không chuẩn hóa polling protocol của Rust Future. Foreign function khai báo trong external block của Rust Reference không thể dùng async qualifier, còn Rust async fn trả về opaque future khi được gọi. Ngoài ra, Future::poll giả định Pin, Context và wake-up protocol.79 Vì vậy chỉ chia sẻ ABI gọi hàm đồng bộ không cho phép foreign event loop tự động drive Rust future.

Điều đó cũng không buộc phải giới hạn như bản cũ rằng “chỉ có thể block hoặc tự viết callback wrapper”. Boundary thực tế có thể được thiết kế bằng callback, opaque handle cộng explicit poll function, completion queue, file descriptor/event notification, message passing, thread chạy Rust runtime riêng, hoặc bridge do host-language binding cung cấp. Đối tượng so sánh quan trọng không phải có bridge hay không, mà bên nào chịu contract cho ownership, wake-up, cancellation, lifetime, error propagation, shutdown và thread safety. Chi phí FFI không phải một con số nội tại duy nhất của Rust async mà thay đổi theo tổ hợp host runtime và ABI protocol.

Không gộp machine time và developer time thành một câu chuyện “chuyển chi phí” duy nhất

Official Rust Async Book giải thích rằng với nhiều I/O-bound task, async có thể giảm CPU và memory overhead so với mô hình lấy OS thread làm trung tâm, đồng thời cũng nêu state machine của async function và việc bao gồm runtime có thể làm binary lớn hơn. 2026 Rust Project Goals còn có Async Future Memory OptimisationAsync statemachine optimisation; problem statement của mục trước nêu memory bloat của nested future, stack overflow trong một số cloud/network workload, cùng lo ngại ở môi trường có memory budget chặt như embedded và kernel.80

Điều này cho bức tranh cụ thể hơn nhiều so với một công thức trao đổi đơn như “async là miễn phí” hoặc “async giảm runtime cost bằng cách hy sinh developer time”. Runtime CPU, allocation, future size, binary size, compiler optimization, debugging, integration và maintenance là các trục chi phí khác nhau. Giảm ở một trục không tự động chứng minh tăng ở trục khác. Việc open answer của survey 2024 nhắc async và debuggability cho thấy khó khăn thực tế tồn tại, nhưng không định lượng thời gian truy lỗi tăng bao nhiêu hay debugging có khó hơn ngôn ngữ khác hay không.

So sánh với Go goroutine cũng phải dùng cùng workload và trục chi phí

Go specification định nghĩa go statement là bắt đầu một lời gọi hàm trong một concurrent thread of control độc lập, tức goroutine, trong cùng address space. Ngược lại, Rust async call tạo inert future và chỉ tiến triển khi executor poll nó.81 Đây là khác biệt thiết kế thực sự, nhưng như bảng sau, cần tách khác biệt cơ chế khỏi kết quả về hiệu năng và năng suất.

Trục so sánh Rust async/await Go goroutine Giới hạn kết luận
Đơn vị thực thi lời gọi tạo Future, tiến triển khi được poll go statement bắt đầu thực thi goroutine khác biệt execution model ở cấp ngôn ngữ
Quan hệ runtime không có built-in runtime; chọn executor/runtime dùng Go runtime gồm goroutine và GC bên nào rẻ hơn cần đo workload
Điều khiển resource có thể tránh allocation và dispatch, chọn cấu hình runtime runtime cung cấp scheduling và memory management phải ghi peak task count, stack/heap, scheduler và điều kiện GC
Library integration I/O, timer, spawn API runtime-specific có thể thành integration boundary goroutine là tính năng ngôn ngữ nhưng boundary của library, Cgo, external loop vẫn riêng không thể rút thành một điểm “integration cao/thấp”
Usability Pin, Send, runtime context có thể lộ ở một số low-level boundary cú pháp tạo goroutine đơn giản nhưng race, cancellation, leak, blocking policy vẫn cần thiết kế chi phí học và debugging tương đối cần user research

Vì vậy câu cũ “CPU-bound thì Rust async có lợi, còn I/O-bound thì Go tốt hơn” không thể tổng quát khi thiếu bằng chứng. Mục tiêu tiêu biểu của Rust async chính là I/O concurrency quy mô lớn, còn CPU-bound work có thể cần thread pool riêng hoặc blocking strategy. Ngược lại, chi phí scheduling và GC của Go runtime có quan trọng dưới một latency budget cụ thể hay không phải được đo theo workload, runtime version, allocation pattern, GOMAXPROCS và hardware. Không thể suy vị trí bottleneck chỉ từ tên ngôn ngữ.

Trong môi trường quy mô lớn, chạy dài hạn và cực hạn, ghi failure condition trước average throughput

Khi chọn async architecture, thay vì một average benchmark duy nhất nên đo peak live future memory khi task count tăng, allocator pressure, scheduler queue và wake-up storm, p95/p99/p999 latency, mức executor bị blocking call chiếm, số timer, cancellation safety, thời gian graceful shutdown, resource leak, binary size, stack headroom, runtime upgrade và dependency compatibility.

Trong môi trường có resource ceiling hoặc requirement recovery nghiêm ngặt như embedded, kernel và long-running service, worst-case và degradation behavior đặc biệt quan trọng.

Cần các dữ liệu này để phân biệt tự do chọn runtime có phải lợi ích thực tế, integration surface có phải chi phí bảo trì, hay vấn đề compiler optimization có trở thành deployment risk hay không.

Kết luận tạm thời

Các nguồn primary và official hiện tại trực tiếp hỗ trợ các kết luận có giới hạn sau. Rust async kết hợp lazy Future với executor bên ngoài và có thể xử lý nhiều I/O task trên số ít OS thread mà không bắt buộc heap allocation hay dynamic dispatch.

Mặt khác, vì không cố định runtime trong standard library, application và ecosystem phải chọn scheduler, I/O, timer, shutdown API và quản lý integration boundary.

Pin là low-level contract quan trọng để xử lý compiler-generated future an toàn, nhưng bị ẩn trong phần lớn high-level async/await code và lộ trực tiếp hơn ở boundary như custom future, stream và projection.

Việc Pin ergonomics cùng tối ưu memory/layout của async future vẫn là project goal trong năm 2026 cho thấy chi phí và usability của lĩnh vực này không phải thuộc tính bất biến mà vẫn là đối tượng của thiết kế ngôn ngữ và implementation đang tiếp diễn.

Ngược lại, bằng chứng hiện tại không cho phép kết luận rằng Rust async nhìn chung khó học hơn hoặc năng suất thấp hơn Go, ecosystem tập trung quanh Tokio vốn dĩ không tương thích, async FFI thực tế là không khả thi, hoặc trong I/O-bound backend, developer cost luôn lớn hơn lợi ích về hiệu quả thực thi của Rust async. So sánh như vậy cần dữ liệu từ service giống hệt hoặc có thể so sánh về task count, latency distribution, CPU, memory, binary size, failure/recovery, implementation effort, defect/incident, staffing và maintenance. Vì vậy kết luận mà mục này cung cấp cho RQ2 và RQ3 hẹp hơn: lợi thế và chi phí của Rust async phải được tách theo execution model, runtime/library boundary, workload, resource ceiling và điều kiện vận hành của tổ chức, thay vì suy trực tiếp từ khẩu hiệu “zero-cost”.

5.4 Xem lại tính thực dụng của xử lý lỗi rõ ràng với Result<T, E>

Đánh giá xử lý lỗi của Rust cần tách biểu diễn lỗi bằng type, cú pháp truyền lỗi, panic như một failure path riêng, và chính sách phục hồi của application. Bản cũ nói Result<T, E> bắt buộc mọi lỗi phải được xử lý ở compile time, nhưng phạm vi thực tế hẹp hơn. Result biểu diễn thành công/thất bại bằng Ok(T)Err(E) và có #[must_use], nên bỏ qua kết quả mặc định tạo warning; đây là lint chứ không phải hard compile error không thể tránh trong mọi program. Caller vẫn có thể truyền lỗi lên trên, biến nó thành panic bằng unwrap/expect, hoặc chủ động bỏ qua.82

Vì vậy câu hỏi là việc đưa recoverable failure vào return type và control flow thông thường tạo lợi ích/chi phí gì, và application nối contract đó với operational policy thế nào.

Không thể so Result và exception chỉ bằng trục explicit/implicit

Với Result, ? early-return khi gặp Err(e) và có thể dùng From::from để chuyển residual khi error type bên ngoài khác, nên không chỉ dùng được với cùng một error type.83 Các ngôn ngữ exception cũng không có một mô hình duy nhất. Java checked exception phải được xử lý hoặc khai báo bằng throws, nếu không sẽ là compile-time error; đồng thời RuntimeExceptionError là unchecked.84 Rust cũng có panic!, unwrap, expect và abort. Không bên nào có thể mô tả chính xác là “mọi failure đều nằm trong type” hay “mọi failure đều bị ẩn khỏi compiler”.

So sánh thực tế phải xét error contract xuất hiện ở đâu trong API, normal/failure flow được truyền thế nào, conversion/composition, cleanup, FFI, logging/retry/fallback. Result biến error thành return type thông thường; exception có thể chuyển control không cục bộ tới handler. Readability và maintainability phụ thuộc call depth, error taxonomy, vị trí recovery, library boundary và team convention, không thể xếp hạng productivity/reliability chỉ từ syntax.

Biểu diễn thành công/thất bại bằng sum type có trước Rust

Haskell 2010 có MaybeEither; F# định nghĩa Result<'T,'TError> là discriminated union với OkError.85 Điều này xác lập các biểu diễn algebraic-data-type tương tự đã tồn tại trước Rust, nhưng không tự chứng minh lineage trực tiếp tới Rust hay tuyên bố rộng hơn rằng Rust đã “phổ biến hóa” ý tưởng này; những tuyên bố lịch sử đó cần tài liệu thiết kế Rust ban đầu hoặc bằng chứng từ designer.

Chuyển đổi lỗi vẫn có chi phí thiết kế

Application lớn kết hợp filesystem, parser, database, network với các error type khác nhau nên vẫn phải thiết kế public error taxonomy. custom enum, giữ source error, thêm context và phân loại retryability có thể cần code. Nhưng không phải mọi call site đều phải viết map_err(...); khi có conversion thích hợp, ? có thể dùng From::from.83 Điều này không xóa các quyết định về dependency error nào đi vào public API, context dạng string hay structured, và thay đổi error variant ảnh hưởng compatibility ra sao. Việc anyhow/thiserror phổ biến không tự chứng minh standard facility thiếu thực dụng, cũng không chứng minh bỏ helper là tốt hơn.

panicResult là các failure policy khác nhau, không phải hai hệ thống loại trừ nhau

Rust thường hỗ trợ panic strategy unwindabort. Unwind chạy Drop cleanup khi tháo stack frame và một số panic có thể được quan sát ở catch_unwind; abort kết thúc process. Cargo profile có thể chọn policy và support còn phụ thuộc target.86 Vì vậy gọi unwrap() trên Result nên được hiểu là lựa chọn nâng value-level recoverable failure thành panic path, chứ không chỉ là “lách compiler rule”. Hậu quả vận hành phụ thuộc thread/process termination, supervisor, request isolation, shared-state invariant và FFI.

Sự cố Cloudflare 2025 cho thấy thiết kế failure boundary, không chỉ sự tồn tại của unwrap

Postmortem Cloudflare ngày 18/11/2025 cho biết thay đổi database access-control khiến query tạo feature của Bot Management trả về quá nhiều metadata row; configuration sinh ra vượt preallocated 200-feature limit. FL2 Rust module tạo error và Result::unwrap() ở handling boundary biến nó thành panic liên quan đến 5xx response.87 unwrap là escalation point thực tế, nhưng không phải nguyên nhân duy nhất: configuration generation, schema/query assumption, resource limit, validation placement, module isolation và kill-switch đều thuộc chuỗi phòng thủ. Kết luận giới hạn là typed error vẫn cần boundary rõ ràng cho recover/reject/isolate/panic/abort.

Trong system lớn, chạy lâu hoặc bị giới hạn tài nguyên, cần đo recoverable/retryable/fatal taxonomy, phạm vi error truyền ra public API, causal context, panic/exception isolation, cleanup/cancellation, FFI, logging cardinality, retry amplification, graceful degradation, restart time, downstream rebuild và migration cost khi error type đổi. Điều quan trọng có thể là đường đi từ error tới resource leak, partial state update, retry storm hoặc process loss.

Kết luận tạm thời

Rust Result<T, E> biểu diễn recoverable failure trong return type thông thường, còn ? hỗ trợ early return và From conversion. #[must_use] khiến việc bỏ qua kết quả mặc định sinh warning, nhưng không biến mọi error thành hard compile error và không loại panic path. Checked exception cũng có thể tạo compile-time contract. Vì vậy RQ2/RQ3 cần so sánh explicit error type, chi phí propagation/conversion, non-local flow, cleanup, API compatibility, observability và recovery boundary trên workload tương đương, thay vì tuyên bố Result hay exception vốn dĩ ưu việt hơn.

5.5 Thách thức trưởng thành định tính của hệ sinh thái Rust và diễn ngôn cộng đồng

crates.io và Cargo cung cấp nền tảng chung để phát hành/kết hợp Rust library. Số package, download hay vài crate nổi tiếng không biến “qualitative maturity” của cả ecosystem thành một con số; vài abandoned crate, thiếu documentation hay incident cũng không chứng minh toàn ecosystem chưa trưởng thành. Phần này tách production suitability của từng dependency khỏi sampling cần thiết để khái quát toàn hệ sinh thái.

Version 0.x tự nó không phải phép đo API instability

Cargo coi các version có cùng left-most non-zero component là compatible, nên 0.2.3 thường cho phép >=0.2.3, <0.3.0; SemVer guide coi thay đổi y trong 0.y.z là major-like và thay đổi z là minor-like.88 Đây là convention chứ không phải hard guarantee mọi project đều tuân theo. Production review nên xem release history, changelog, MSRV, breaking-change policy, deprecation window, CI target và upgrade test thực tế thay vì chỉ nhìn số 0; 1.0 cũng không tự bảo đảm runtime/operational compatibility.

Documentation và maintenance phải được quan sát theo từng crate

cargo doc và docs.rs có thể tạo/host tài liệu nhưng không bảo đảm chất lượng; vài anecdote phải đọc source cũng không đo được trung bình ecosystem. Candidate dependency nên được kiểm tra về API completeness, example, safety contract, platform limit, upgrade guide, MSRV và feature documentation.

crates.io/Cargo hỗ trợ nhiều owner và yanking: release bị yank sẽ không được chọn trong resolution mới nhưng code không bị xóa và lockfile cũ không bị phá.89 RustSec và công cụ như cargo-audit cung cấp kiểm tra known vulnerability.90 Các cơ chế này giảm một số maintenance/supply-chain risk nhưng không bảo đảm một crate sẽ được duy trì mãi.

Bằng chứng hiện tại chỉ ra challenge, không cho điểm chất lượng trung bình

2025 State of Rust Survey có 7.156 câu trả lời, cảnh báo không ngoại suy quá mức, ghi nhận quan tâm tăng đối với developer/maintainer support và kêu gọi doanh nghiệp hỗ trợ contributor/crate author mà họ phụ thuộc.91 Nó không đo registry-wide bus factor. Khoảng 70 Vision Doc interview cũng nêu khó khăn về crate discovery/trust và coverage chưa đủ trưởng thành ở một số domain.92 Đây là qualitative challenge trong sample cụ thể, không phải registry-wide reliability, documentation, abandonment rate hay ranking giữa ecosystem.

Do đó kết luận “lớn về lượng nhưng chưa trưởng thành về chất” là quá rộng. Kết luận giới hạn hơn là Rust có không gian lựa chọn lớn và infrastructure hữu ích, đồng thời project vẫn chịu chi phí dependency selection, trust, maintainer sustainability và domain coverage, với mức độ tùy domain/graph.

Success/failure example và community reply đều cần sampling discipline

serde hay tokio cho thấy crate được duy trì tốt là khả thi, không cho average maturity của mọi crate; abandoned/malicious package chỉ cho possible failure mode. Cần định nghĩa sampling frame—registry-wide, download threshold, production transitive dependency hay domain-specific candidate—rồi đo activity, owner concentration, compatibility, MSRV, documentation, CI/test, advisory response, unsafe boundary, dependency depth, license, platform và replacement cost bằng cùng tiêu chuẩn.

Tương tự, “Pull Requests are welcome” có thể là responsibility shifting trong một context và là lời mời collaboration hợp lý trong context khác. Theo Mục 3.6, vài forum post không có corpus và coding rule định trước không thể cho biết cách dùng nào phổ biến hơn, Rust community có né phê bình nhiều hơn community khác hay không, hoặc phản hồi đó có thật sự làm giảm contribution/bug report không.

Trong system lớn và sống lâu, hãy coi mỗi dependency là một supply chain nhỏ: ghi direct/transitive depth, owner concentration, provenance, lockfile reproducibility, advisory response, emergency patch/fork, feature combination, build-script/proc-macro, native dependency, unsupported platform, compliance, replacement lead time, update frequency, CI rebuild cost và quy trình phục hồi khi abandonment/transfer/yank.

Kết luận tạm thời

Rust có infrastructure cho publication, resolution, ownership transfer, yanking và vulnerability advisory; survey/interview cũng cho thấy maintainer support, crate discovery/trust và một số domain coverage vẫn là concern. Chúng không xác lập average quality của crates.io hay maturity ranking giữa các ngôn ngữ. RQ2/RQ3/RQ5 vì vậy yêu cầu đo compatibility, maintenance, security, documentation, integration và replacement cost trên dependency population đã nêu rõ, đồng thời tách discourse pattern khỏi ecosystem-quality metric.

5.6 Thách thức kỹ thuật trong chuỗi công cụ phát triển và năng suất

Đánh giá Rust toolchain cần tách chi phí của compiler, build system, language server và debugger. Compile latency cùng memory/disk là tool cost đo được; IDE diagnostic latency và debugger coverage là workflow cost khác, phụ thuộc codebase, CI, cache, linker, dependency graph và debugging workflow.

5.6.1 Sử dụng tài nguyên trình biên dịch và ảnh hưởng

2025 Rust Compiler Performance Survey nhận hơn 3.700 response; build-performance satisfaction trung bình 6/10, mode là 7. Báo cáo nói experience thay đổi lớn nên không thể rút gọn thành “Rust builds are slow”; đồng thời khoảng 45% người đã ngừng dùng Rust nêu long compile time là ít nhất một lý do.93 Với project mà mỗi respondent tự chọn là gây khó khăn build-time nhất, 55% chờ hơn 10 giây sau code change, thay đổi mạnh theo project size. Đây cố ý là troublesome workload chứ không phải rebuild distribution của mọi Rust project, nhưng cho thấy constraint incremental-feedback thực tế trong một số codebase.

monomorphization là một mechanism, không phải toàn bộ nguyên nhân. rustc guide ghi rõ concrete generic instance có thể tăng compile time và binary size.94

Build thực còn gồm parsing, macro, type/borrow checking, codegen, linking, proc macro/build script, dependency rebuild, debuginfo và cache. Survey tách riêng incremental compilation, cargo check/cargo build cache, linking, workspace rebuild và CI caching.

Full debuginfo của dev profile giúp debugging nhưng tăng build/link và target storage; benchmark mà survey dẫn cho thấy line-tables-only cải thiện 2–30% cycle count trong một số điều kiện, và chính lựa chọn đó cũng là workflow trade-off. Cranelift, parallel frontend, faster linker và workspace rebuild vẫn đang được cải thiện.

Nên đo p50/p95 incremental rebuild, type-check/link latency, peak RSS, target growth, CI cold/warm cache, parallel memory pressure và developer idle time.

5.6.2 Tích hợp IDE và gỡ lỗi: Chi phí phía sau trừu tượng

Trong cùng survey, khoảng 87% dùng editor inline annotation làm cách chính xem compiler error; khoảng 33% trong số đó coi việc chờ annotation là major blocker, open answer thường nêu rust-analyzer performance/memory, và hơn 35% coi IDE/Cargo resource contention là vấn đề lớn.93 Đây là self-selected survey, không phải average của toàn bộ developer.

Khẳng định cũ rằng debugger luôn chỉ hiển thị Vec<String> như raw field cũng quá tuyệt đối. Rust có debugger visualizer, chất lượng tùy tool/OS/version. 2026 compiler-team debugging survey nói debugging hiện có thể làm được nhưng chưa đủ tốt trong một số tình huống, và nêu cross-debugger/OS support, type visualizer, first-class async debugging, Rust expression evaluation là vùng cần cải thiện.95 Vì vậy nên đo optimized/generic stepping, visualizer coverage, async causality, backtrace/core dump/sanitizer/profiler, remote/cross target, incident artifact, symbol, reproducible build và postmortem time.

5.6.3 Tính linh hoạt của hệ thống xây dựng Cargo

Cargo chuẩn hóa dependency resolution, metadata, profile, workspace, feature và build command. Khẳng định cũ rằng non-standard build thường vượt khả năng build.rs là quá rộng: tài liệu chính thức liệt kê bundled C library, tìm native library, tạo Rust module và platform-specific configuration như use case tiêu biểu.96

Build graph phức tạp vẫn có chi phí. Build script phải compile/run và có thể rerun thừa nếu change detection không chính xác; feature cần hiểu unification/resolver rule; workspace chia sẻ Cargo.lock và output state nhưng package selection, feature combination, cross target và native dependency có thể mở rộng rebuild surface.97 Trade-off vì vậy không đơn giản là “convention over configuration gây cứng nhắc”. Common model có thể cải thiện reproducibility/tool integration, trong khi generated code, non-Rust toolchain, multiple target, hermetic build, constrained feature set và monorepo cache policy cần integration layer rõ ràng. Đo graph invalidation, số feature state, native-build reproducibility, cross-compile parity, cache hit ratio, build-script time và external-build integration.

Kết luận tạm thời

Bằng chứng chính thức xác lập compile, editor, disk và debugging cost thực trong một số Rust workflow, đồng thời cho thấy experience phân tán và có nhiều bottleneck. RQ2/RQ3 nên so feedback latency, peak resource, CI cost, diagnostic quality, debugger capability, reproducibility và integration maintenance trên cùng project/workflow, thay vì quy tất cả cho monomorphization hoặc language complexity.

5.7 So sánh môi trường phát triển: Nơi độ trưởng thành gặp triết lý thiết kế

So sánh “Java/C# là integrated IDE, Rust là VS Code cộng toolchain tách rời” trộn các configuration khác nhau. Editor có thể dùng language server, IDE có thể tích hợp build/debug/profiling, và command-line tool có thể chạy automation. Câu hỏi thực là cùng một development task có thể được thực hiện chính xác, nhanh, tiết kiệm tài nguyên và tự động hóa đến mức nào.

Maturity là đa chiều

tooling maturity gồm feature coverage, correctness, latency, resource use, platform coverage, compatibility, documentation, support lifecycle và recovery; tuổi đời hay language complexity riêng lẻ không quyết định tất cả. Tài liệu Rust hiện tại cho thấy 2025 survey có cả build/editor experience hài lòng và không hài lòng cùng vấn đề rust-analyzer/resource contention; 2026 debugging status chỉ ra khác biệt tool/OS và gap ở visualizer, async debugging, expression evaluation.98 Điều này xác định capability gap cụ thể chứ không cho một điểm “early-stage” toàn cục.

So cùng task và project

Symbol rename có thể kiểm macro/generated/config reference và compile/test success; completion đo p50/p95 latency và memory; diagnostic đo disagreement với compiler; debugging đo breakpoint/watch/expression/async causality/core dump; build đo cross target/native/generated/cache. “Integrated IDE hay LSP” tự nó không phải quality score. Integration có thể cải thiện installation/discoverability nhưng tăng update coupling/footprint; modular tooling có thể dễ thay thế/automation nhưng tăng compatibility/setup surface.

Ở quy mô tổ chức, tách sự hài lòng IDE cá nhân khỏi chi phí vận hành toolchain qua nhiều target, OS/architecture, air-gapped build, hermetic CI và branch sống lâu. Ghi installation/index size, update, extension trust, compiler-debugger compatibility, CI image, pinning, offline mirror, support escalation, onboarding, rollback, symbol/source retention và khả năng build/debug release branch cũ.

Kết luận Chương 5

Chương 5 tách learning, technology choice, async, error handling, dependency ecosystem và compiler/IDE/debugger/build workflow thay vì nén developer experience thành một productivity score. Bằng chứng xác lập các learning/workflow challenge thực của Rust, nhưng mức độ thay đổi theo population, task, codebase, tool version và organization; một phần là implementation/ecosystem state có thể thay đổi chứ không phải fixed language property.

RQ2/RQ3 vì vậy yêu cầu không tự động đổi compile-time guarantee/runtime performance thành productivity, cũng không tự động đổi learning curve/tooling friction thành technical unsuitability. Project tương đương nên đo onboarding, edit-build-test latency, review/debugging, defect escape, dependency maintenance, CI resource, incident recovery và long-term refactoring. RQ5 tách rhetoric từ vài forum khỏi population behavior/outcome. Môi trường lớn, chạy lâu, cực hạn còn cần p95/p99 feedback latency, peak build memory/disk, expert concentration, toolchain outage/rollback, security response, reproducible debugging artifact và multi-year support cost.

6. Phân tích chi phí thực của “trừu tượng hóa không chi phí”

Để đánh giá cụm từ “Zero-Cost Abstraction” (ZCA), trước hết phải giới hạn loại chi phí nào được tuyên bố là không phát sinh. Rust Book dùng iterator làm ví dụ: high-level abstraction có thể được tối ưu để không tạo thêm runtime overhead so với lower-level code tương đương, và liên hệ nguyên tắc này với zero-overhead principle của C++.99

Điều đó không có nghĩa tổng CPU/memory cost của program bằng 0, cũng không bảo đảm mọi abstraction luôn được hạ xuống assembly tối ưu. Chính ví dụ iterator cũng nói rằng benchmark toàn diện hơn cần nhiều input và query hơn. Vì vậy Chương 6 đặt câu hỏi hẹp hơn: khi Rust giảm runtime abstraction overhead, những chi phí có điều kiện nào xuất hiện ở compile, code size, dispatch, linking và deployment, và phần nào đến từ language mechanism so với build configuration và workload?

6.1 Cơ chế chuyển dịch chi phí: Vai trò của đơn hình hóa

Rust generic thường được hiện thực bằng monomorphization, tạo machine-code instance cho từng concrete type. rustc development guide nói trực tiếp rằng cách này có thể tạo code chạy nhanh, nhưng việc tạo nhiều copy tốn compile time và các copy có thể chiếm binary space.94 Vì vậy trong generic-heavy code, monomorphization có thể là nguồn thực của build cost và code-size growth.

Tuy nhiên từ đó không thể suy ra quy luật phổ quát rằng “runtime cost tiết kiệm được từ mọi ZCA đều chuyển sang compile time và binary size”. Không phải zero-cost abstraction nào cũng dùng monomorphization; zero-sized typestate hay abstraction bị optimizer xóa là mechanism khác. Compile time và binary size còn phụ thuộc macro, type checking, MIR optimization, codegen, linking, debuginfo, dependency, profile và target. Evidence ở Mục 5.6 cũng tách nhiều build bottleneck khác nhau.

Monomorphization có thể tạo chi phí cơ học, nhưng kích thước cuối phụ thuộc optimization và reuse

Dùng generic function với các concrete type như Vec<i32>Vec<String> có thể cần các mono item riêng. Nhưng không thể giả định mọi instance được tạo ra đều còn lại trong final artifact theo cùng tỷ lệ. Inlining, dead-code elimination, linker section garbage collection, identical-code folding khi được hỗ trợ, cross-crate codegen, LTO và reachable call path đều có thể thay đổi kết quả. Vì vậy số source-level instantiation không thể chuyển thẳng thành số byte binary.

dyn Trait dynamic dispatch có thể giảm duplication trong một số thiết kế, nhưng cũng không thể khái quát rằng “dynamic dispatch luôn giảm compile time và binary size”. Nó đưa vào indirect call và thay đổi optimization opportunity, object-safety/API shape, allocation hoặc pointer representation, branch prediction và code locality; compiler cũng có thể tối ưu lại một số dispatch. Static/dynamic dispatch cần được so đồng thời về runtime latency, instruction-cache footprint, compile time, size và API flexibility.

Dùng cost shifting như giả thuyết đo lường, không phải đẳng thức kế toán

Nếu một project thêm iterator/generic abstraction, quan sát runtime work bằng hoặc thấp hơn, đồng thời build time hay artifact size tăng, thì workload đó có trade-off quan sát được. Nhưng một trục tốt lên không tự chứng minh nguyên nhân của trục khác xấu đi. Nên cố định baseline, feature set, compiler version, optimization profile, codegen unit, LTO, linker và target khi so trước/sau.

Trong codebase lớn, incremental fan-out có thể quan trọng hơn clean-build mean. Cần ghi số crate recompile sau generic API change, monomorphized code phân bố qua codegen unit thế nào, peak linker memory và target cache tăng ra sao, CI cold build khác developer warm build thế nào. Embedded/kernel cần đo riêng flash/RAM, build-host memory và worst-case build time.

Kết luận tạm thời

Primary documentation trực tiếp hỗ trợ rằng monomorphization là mechanism quan trọng của Rust generic và có thể tốn compile time cùng binary space. Đồng thời zero-cost abstraction là mục tiêu tránh thêm runtime overhead, không phải guarantee không có cost trong toàn lifecycle. RQ2/RQ3 vì vậy cần đo một abstraction mechanism cụ thể thay đổi runtime, compile, code size, dispatch và maintenance cost ra sao trong workload đã nêu, thay vì giả định cost luôn chuyển từ runtime sang compilation.

6.2 Kích thước binary: Nguyên tắc thiết kế ảnh hưởng miền ứng dụng

Không thể coi “Rust binary lớn hơn C/C++ binary” là fixed language property nếu không kiểm soát điều kiện so sánh. Executable size phụ thuộc linked library, static/dynamic policy, feature set, panic strategy, debuginfo và stripping, optimization/LTO, target runtime, libc, linker và package format. Vì vậy không thể quy trực tiếp chênh lệch size giữa các program khác nhau cho language-level effect. Tuy nhiên, snapshot của deployment artifact thực tế trong cùng distribution, architecture và latest stable repository vẫn có giá trị như dữ liệu vận hành tái lập được.

Ngày 28-08-2026, sách tải APK busybox, GNU coreutils và Rust uutils từ v3.24 stable x86_64 repository của Alpine Linux 3.24.1, latest stable release chính thức lúc đó, rồi đo trực tiếp multicall ELF chính của từng package.100 Cả ba file đều là stripped, dynamically linked x86-64 PIE.

Bảng 6.1: Snapshot multicall executable trên Alpine Linux 3.24 stable x86_64

Implementation Ngôn ngữ package version File đo file size
BusyBox C 1.37.0-r31 /bin/busybox 804.616 B
GNU coreutils C 9.11-r0 /bin/coreutils 1.138.944 B
uutils Rust 0.9.0-r0 /bin/uutils 9.171.040 B

Đây là deployment snapshot, không phải controlled experiment giữa các ngôn ngữ. Command coverage, dependency graph và shared-library closure của ba implementation không hoàn toàn giống nhau; file size trong bảng cũng không bao gồm shared library. Có thể tái lập quan sát rằng executable uutils lớn hơn dưới các điều kiện này, nhưng không thể quy toàn bộ chênh lệch cho riêng Rust, monomorphization hay static linking. Snapshot chủ yếu cho thấy claim về binary size phải đi kèm version, architecture, linkage, stripping, feature set và dependency closure.

Rust mặc định ưu tiên static dependency nhưng vẫn hỗ trợ dynamic linking

Tài liệu rustc nói dependency mặc định được ưu tiên statically link, còn -C prefer-dynamic có thể ưu tiên dynamic linkage khi cả hai dạng sẵn có. Rust Reference định nghĩa rlib, Rust dylib, system staticlibcdylib cho FFI.101 Vì vậy khẳng định “Rust không thể dynamic link vì ABI không ổn định” là không chính xác.

Một vấn đề khác là dùng Rust-native ABI làm plugin contract được deploy độc lập và lâu dài. Reference nói rõ extern "Rust" ABI không có stability guarantee, còn default repr(Rust) layout chỉ có guarantee giới hạn và có thể thay đổi giữa compilation. Rust đồng thời có boundary rõ như extern "C"#[repr(C)] cho interoperability.102 Câu hỏi kỹ thuật không phải dynamic linking có/không, mà là ABI và representation nào tạo compatibility contract qua version boundary nào.

Binary size là kết quả của build profile và dependency graph

Default release profile của Cargo vẫn là strip = "none", lto = false, panic = 'unwind', nên release build không tự động là minimum-size build. Cargo cung cấp opt-level = "s"/"z", stripping, LTO, codegen-units, panic strategy và các control khác. Tài liệu chính thức nói optimization mạnh hơn có thể tăng compile time, s/z không nhất thiết cho binary nhỏ hơn ở mọi program, và LTO đánh đổi link time dài hơn để lấy whole-program optimization.103

panic = 'abort' có thể giảm size khi không cần unwinding machinery, nhưng mức giảm phụ thuộc target/program và nó thay đổi failure policy bằng cách từ bỏ unwind cleanup cùng catch_unwind boundary đã bàn ở Mục 5.4. Stripping có thể giảm shipped artifact nhưng production postmortem có thể cần giữ debug symbol riêng.

no_std không có nghĩa phải tự viết lại collection

#![no_std] ngừng tự động link std và dùng core. Heap-backed type không nằm trong core, nhưng nếu environment cung cấp allocator thì có thể link alloc một cách explicit và dùng Vec, Box, String.104 Vì vậy claim cũ rằng no_std buộc phải tự hiện thực các type này là sai.

Trách nhiệm thực sự chuyển sang boundary khác: no_std binary có thể cần target-specific startup/entry và panic handling; cần allocator nếu dùng heap; filesystem, thread, network và platform integration tương tự cũng không tự có từ core/alloc. Boundary explicit này có thể hữu ích trong firmware, kernel và bootloader nhưng có thể là chi phí không cần thiết với application server.

Đo deployment footprint, không chỉ shipped file size

Target có flash nhỏ nên tách .text/.rodata/.data, relocation, unwind table, allocator metadata và stack/heap budget. Container/serverless có thể quan tâm compressed image size, cold-start I/O, page cache, shared dynamic page, update transfer và symbol sidecar. Desktop có thể quan tâm shared-library compatibility, installer size và security-patch propagation hơn vài MiB executable.

Fleet lớn còn phải tính static copy lặp lại qua nhiều binary, page sharing và compatibility risk của dynamic dependency, full-artifact redeploy khi vá vulnerability, debug-symbol retention và rollback image storage. Binary size chỉ là một phần của lifecycle footprint.

Kết luận Chương 6

Evidence hiện tại hỗ trợ rằng Rust cố giảm additional runtime overhead của một số high-level construct, và generic monomorphization có thể tăng compile time/code size trong một số điều kiện. Nó cũng cho thấy rustc mặc định ưu tiên static dependency nhưng hỗ trợ dynamic linking, Rust-native ABI stability khác với C ABI/representation boundary, và Cargo profile cùng lựa chọn no_std/alloc có thể thay đổi đáng kể artifact footprint.

Evidence này không xác lập rằng runtime gain của Rust abstraction luôn chuyển một-một thành build time/binary size, Rust binary vốn dĩ lớn hơn C/C++ binary, dynamic linking không dùng được, hoặc muốn binary nhỏ phải bỏ Rust safety feature. Các claim đó cần reproducible comparison kiểm soát functionality, target, dependency, linkage, optimization, symbol và panic policy.

Kết luận RQ2/RQ3 của Chương 6 là đo runtime latency/throughput, compile time, peak build memory, code/deployment size, link/ABI strategy, failure policy và maintenance cost trong cùng một configuration được nêu rõ, thay vì dựa vào nhãn “zero-cost” hay anecdote về package size. Môi trường lớn, chạy lâu hoặc cực hạn cần thêm flash/RAM headroom, cold start, shared-page effect, update bandwidth, patch/rebuild time, rollback storage và postmortem symbol retention.

7. Ràng buộc áp dụng công nghiệp

Chương 7 không rút gọn việc áp dụng Rust trong công nghiệp thành một thước đo “độ trưởng thành” hay adoption percentage. Chương hỏi mỗi bằng chứng thực sự chứng minh điều gì (RQ3), và chiến lược thay đổi nào phù hợp trong điều kiện nào (RQ4). Language guarantee, production deployment, tool qualification, ecosystem và staffing, legacy asset, interoperability và migration risk thuộc các tầng phân tích khác nhau nên phải tách biệt.

Chương lần lượt xem xét hỗ trợ hiện tại và source snapshot trong môi trường embedded/kernel (7.1), boundary của safety-critical qualification/certification (7.2), chiến lược staffing/dependency/legacy/migration trong tổ chức thông thường (7.3), và phạm vi chứng cứ của production adoption case tại Google, Microsoft, AWS (7.4). Mỗi case phân biệt feasibility, observed outcome, prevalence và causation, rồi tổng hợp các lựa chọn có điều kiện từ maintenance tới selective replacement và full rewrite.

7.1 Môi trường nhúng và kernel: Áp dụng thực tế và thách thức kỹ thuật

Một trong những lĩnh vực Rust được đánh giá như lựa chọn thay thế C/C++ là hệ thống nhúng và phát triển kernel hệ điều hành. Tuy nhiên, ranh giới quan trọng không chỉ là có dùng được std hay không. Như Mục 6.2 đã phân tích, #![no_std] làm rõ trách nhiệm của môi trường thực thi quanh core; khi có allocator, alloc vẫn có thể cung cấp các heap-backed type như Vec, Box, String. Ngược lại, các API user-space OS mà std cung cấp như thread, filesystem, network và process không tồn tại nguyên dạng trong kernel hay firmware, nên allocator, synchronization, I/O, panic, startup và device abstraction phải phù hợp với platform.

Rust support của Linux kernel xử lý khác biệt này bằng kernel API và abstraction riêng. Kernel documentation hiện tại cho phép Rust qua CONFIG_RUST, hướng dẫn developer tới support code dưới rust/samples/rust/, mô tả complete LLVM toolchain là build setup được support tốt nhất hiện nay, đồng thời coi GCC-based Rust build cho một số configuration là very experimental.105 Vì vậy không thể đánh giá cost và benefit của kernel Rust bằng cách giả định cùng library surface với application std thông thường.

Một hướng thiết kế quan trọng của Rust for Linux là xây Rust-facing abstraction trên kernel API viết bằng C và để unsafe implementation boundary chịu trách nhiệm cho invariant hứa với Safe Rust caller. Điều này không loại bỏ unsafe; nó là chiến lược tập trung proof obligation vào các ranh giới nhỏ hơn. Kernel resource như lock, reference counting, device registration và memory allocation có điều kiện khác các type cùng tên trong application, nên lifetime, aliasing và concurrency contract của wrapper phải khớp với invariant thật của kernel.

Source tree của latest stable Linux 7.2.1 có phạm vi Rust rộng hơn giai đoạn đầu chỉ có infrastructure. drivers/android/binder/ chứa Rust Binder, còn drivers/gpu/drm/nova/drivers/gpu/drm/tyr/ chứa Rust driver code. Tuy nhiên Kconfig trong source đánh dấu Nova và Tyr là work in progress và có thể chưa hoạt động. Do đó cần phân biệt “kernel có Rust code” với “subsystem tương ứng đã thay thế implementation C trong production”.105

Mức tích hợp Rust trong Linux kernel được đo lại như một latest stable snapshot. Ngày 30-08-2026, tarball chính thức Linux 7.2.1—được kernel.org liệt kê là stable, phát hành 27-08-2026—được phân tích bằng cloc v2.04 với lệnh cloc . tại source root.106 Sau khi loại comment và dòng trống, tổng SLOC là 30.518.591 dòng; cloc phân loại 114.481 dòng là Rust, khoảng 0,375%.

Con số 0,375% là tỷ lệ source SLOC được phân loại là Rust trong toàn bộ tarball Linux 7.2.1. Khoảng 92.808 dòng Rust nằm dưới rust/, 19.726 dòng dưới drivers/, phần còn lại ở samples/, scripts/, lib/, mm/tools/. Không nên đọc nó như tỷ lệ Rust driver hay tỷ lệ kernel code thực sự được thực thi. SLOC cũng không gán trọng số cho tầm quan trọng, tần suất thực thi, hiệu quả an toàn hay maintenance cost.

Snapshot Linux 6.15.5 trước đây của sách ghi 14.194 dòng Rust, khoảng 0,05%, nên latest snapshot rõ ràng có quantitative footprint lớn hơn. Cả phép đo trước và phép đo hiện tại đều dùng cloc v2.04, nên loại bỏ được sai khác do tool version. Dù vậy source tree đã thay đổi đáng kể và SLOC không phản ánh trọng số về tầm quan trọng hay tỷ lệ thực thi của code, vì vậy tỷ lệ giữa hai snapshot không được coi là growth rate chính xác của Rust adoption. Khi nói về trạng thái kỹ thuật hiện tại, sách dùng giá trị latest stable 0,375%; Mục 8.4 tham chiếu bền hơn bằng category dưới 1%.

Bảng 7.1: Phân bố ngôn ngữ cloc trong source tree Linux 7.2.1 (SLOC, %)

Hạng Ngôn ngữ code lines Tỷ lệ (%)
1 C 19.623.126 64,30
2 C/C++ Header 8.400.038 27,52
3 JSON 553.644 1,81
4 reStructuredText 540.837 1,77
5 YAML 518.483 1,70
6 Assembly 230.041 0,75
7 Bourne Shell 159.494 0,52
8 Rust 114.481 0,38

Tỷ lệ được làm tròn từ tổng 30.518.591 SLOC; chỉ hiển thị tám cloc language category đứng đầu.

Tách khỏi quantitative snapshot ở Bảng 7.1, câu hỏi engineering trung tâm của kernel Rust là safe abstraction dựa trên những unsafe proof obligation nào. CVE-2025-68260 là một failure cụ thể ở ranh giới này: xử lý death_list của Rust Binder kết hợp unsafe list removal với điều kiện truy cập song song không tương thích, dẫn tới data race và pointer corruption.107 Trường hợp này không có nghĩa Rust cho phép data race; nó cho thấy nếu unsafe implementation thiết lập sai invariant hứa với Safe Rust, guarantee bên ngoài ranh giới đó có thể không còn đúng.

CVE record liệt kê Linux 6.18 là affected và ghi nhận fix ở 6.18.1 cùng dòng 6.19, nên latest stable 7.2.1 được đo ở đây không được mô tả là chưa vá.107 Đơn vị phân tích hữu ích không phải “Rust kernel không an toàn” mà là cách review, regression-test và isolate aliasing, locking, lifetime precondition của unsafe operation tại subsystem boundary.

Kết luận tạm thời

Latest stable snapshot cho thấy source footprint của Rust trong Linux lớn hơn phép đo cũ của sách và đã có driver code thực tế như Binder và GPU driver. Đồng thời Rust vẫn dưới 1% tổng source SLOC, và con số này không trực tiếp đo giá trị adoption hay safety effect. Tính phù hợp của Rust trong môi trường embedded và kernel không thể suy ra chỉ từ nhãn no_std; cần đánh giá cùng lúc target/toolchain support, allocator và panic policy, platform API coverage, khả năng review unsafe boundary, subsystem maturity, binary/RAM budget, debugging, upgrade và long-term maintenance cost.

7.2 Hệ thống trọng yếu nhiệm vụ và thiếu chuẩn quốc tế

“Thiếu chuẩn quốc tế” trong mục này nghĩa là bản thân ngôn ngữ Rust chưa được chuẩn hóa thành một chuẩn ngôn ngữ quốc tế như C, C++ và Ada theo ISO/IEC. Điều đó không đồng nghĩa với việc không có chuỗi công cụ Rust đã được qualification hoặc không có con đường hỗ trợ certification thương mại cho phát triển an toàn hay trọng yếu nhiệm vụ. Trong các lĩnh vực đòi hỏi mức bảo đảm cao như hàng không vũ trụ, ô tô, điều khiển công nghiệp và thiết bị y tế, cần phân biệt chuẩn hóa đặc tả ngôn ngữ, qualification của compiler và công cụ phát triển, certification của thư viện, và certification của hệ thống hoặc sản phẩm cuối cùng như những lớp khác nhau.

Việc bản thân Rust chưa phải ngôn ngữ chuẩn hóa quốc tế vẫn là một khác biệt thể chế so với C/C++/Ada. Tuy nhiên, chuẩn quốc tế cũng được sửa đổi theo thời gian, và khả năng bảo trì dài hạn hay khả năng certification không do riêng tình trạng chuẩn hóa ngôn ngữ quyết định. Một dự án thực tế phải xem xét đồng thời đặc tả ngôn ngữ sẽ dùng, phiên bản compiler cụ thể, tài liệu xác minh, target được hỗ trợ, phạm vi thư viện và điều kiện hỗ trợ dài hạn của nhà cung cấp.

Ferrocene minh họa cho sự phân biệt này. Ferrous Systems cùng công ty con Critical Section GmbH công bố Ferrocene năm 2021 như một nỗ lực qualification ngôn ngữ và compiler Rust cho lĩnh vực an toàn trọng yếu; năm 2022, Ferrous Systems và AdaCore công bố cùng phát triển cho thị trường an toàn và trọng yếu nhiệm vụ. Release mới nhất Ferrocene 26.05.0, phát hành ngày 28-07-2026, cung cấp compiler được TÜV SÜD qualification để hỗ trợ phát triển liên quan an toàn theo ISO 26262 ASIL D, IEC 61508 SIL 3 và IEC 62304 Class C, đồng thời bao gồm thay đổi upstream Rust từ 1.93.0 đến 1.95.0.108 Vì vậy không thể khái quát rằng Rust ecosystem không có compiler thương mại hay qualification path đáp ứng các safety standard.

Tuy nhiên, không được mở rộng qualification này thành certification cho toàn bộ ngôn ngữ Rust, mọi Rust program hay toàn bộ development tool được phân phối cùng Ferrocene. Ferrocene Safety Manual giới hạn qualification bằng Ferrocene Language Specification (FLS), target environment được chỉ định, usage restriction và nghĩa vụ của người dùng xác minh Tool Confidence Level cùng môi trường sử dụng. Tài liệu qualification công khai xác định rustc là qualified tool và phân biệt cargo, Clippy, rust-analyzer, debugger, rustdoc/rustfmt cùng nhiều LLVM tool là unqualified. Tuy vậy tài liệu main công khai hiện nay là development-branch preview, nên version number của rolling tiếp theo trong đó không được coi là qualification version của release 26.05.0 đã phát hành.108

Qualification của compiler và certification của library cũng là hai việc khác nhau. Release 26.05.0 mới nhất cung cấp certified subset của Rust core ở ISO 26262 ASIL B và IEC 61508 SIL 2, đồng thời mở rộng certification scope sang core::fmt; không phải toàn bộ core được certification ở cùng mức ASIL D/SIL 3 như compiler. Trong hàng không vũ trụ, Ferrocene cũng nói rằng họ hỗ trợ customer certification effort hướng tới DO-178C DAL C, nhưng không nên xem hỗ trợ đó là một qualification đã hoàn tất tương đương trạng thái ISO 26262/IEC 61508.108

Do đó, câu hỏi cốt lõi khi đánh giá Rust cho lĩnh vực trọng yếu nhiệm vụ không chỉ là “Rust có phải ngôn ngữ chuẩn quốc tế hay không”. Cần xem xét đồng thời đặc tả và chuỗi công cụ Rust nào được dùng, phiên bản và nền tảng target cụ thể có nằm trong phạm vi qualification không, thư viện cần thiết có thuộc phạm vi certification không, và ai chịu trách nhiệm cho certification cấp hệ thống của sản phẩm cuối cũng như bảo trì dài hạn. Ferrocene là phản ví dụ cho lập luận rằng thiếu một ngôn ngữ chuẩn quốc tế đồng nghĩa với không có con đường certification an toàn; đồng thời nó cũng cho thấy qualification của công cụ không tự động thay thế certification của từng sản phẩm.

7.3 Rào cản tiếp nhận công nghiệp nói chung và chiến lược thay đổi

Khi đánh giá khả năng áp dụng Rust trong công nghiệp nói chung, cần tách “ngôn ngữ có tốt hay không” khỏi “tổ chức hiện tại có thể vận hành ngôn ngữ đó một cách an toàn hay không”. Staffing, dependency, hệ thống hiện hữu, FFI, deployment, observability và support là các tầng ràng buộc khác với language semantics, và giá trị của chúng khác nhau theo project. Vì vậy phần này so sánh capability của từng tổ chức và chiến lược thay đổi, thay vì tạo một bảng xếp hạng thị trường đơn giản.

Đo vấn đề nhân lực bằng capability thực tế của tổ chức, không phải ranking thị trường ngôn ngữ

2025 State of Rust Survey báo cáo xu hướng tiếp tục tăng của các tổ chức dự định tuyển thêm Rust developer. Tuy nhiên đây là self-selected sample thiên về Rust với 7.156 người trả lời, và chính report cảnh báo không nên ngoại suy quá mức.109 Dữ liệu này không chứng minh rằng labor pool Rust nhỏ hơn Java/C#/Python, việc tuyển dụng luôn khó hơn, hay mức lương luôn cao hơn.

Project nên ghi nhận Rust expertise thực sự có thể sử dụng, số người có khả năng code review, bus factor của reviewer cho unsafe/FFI, thời gian ramp-up của nhân sự mới, incident on-call coverage, thời gian đào tạo, external hiring lead time và long-term retention. Ở một tổ chức, đào tạo lại C++ engineer hiện có có thể nhanh nhất; ở tổ chức khác, kinh nghiệm Rust đã đủ. Expertise mà team có thể duy trì lâu dài là ràng buộc trực tiếp hơn khẩu hiệu về trung bình thị trường.

“Độ trưởng thành” của ecosystem cũng phải thu hẹp theo domain và dependency

Tài liệu Rust Project Vision Doc 2026 đã xét ở Mục 5.5 ghi nhận các vấn đề thực về lựa chọn/tin cậy crate và coverage chưa đủ trong một số domain công nghiệp, đồng thời nêu giới hạn sample và generalization.92 Vì vậy xếp toàn bộ Rust enterprise ecosystem thấp hơn Java/.NET chỉ từ vài ví dụ như ORM, cloud SDK hay authentication vượt quá phạm vi evidence.

Trong thực tế, từng protocol, database, cloud, cryptography, GUI, embedded hoặc safety library cần được audit về maintainer capacity, release cadence, phản ứng security advisory, API stability, platform coverage, license, transitive dependency, khả năng offline/vendor, replacement candidate và long-term support. Thiếu crate cần thiết hoặc assurance không đủ là cost áp dụng thực, nhưng không nên chuyển nguyên kết quả thành công/thất bại từ domain khác.

Legacy là tập hợp trạng thái hiện tại và chi phí tương lai, không phải phán quyết phải loại bỏ

Hệ thống vận hành lâu dài tích lũy implicit specification không chỉ trong code mà còn trong test, deployment script, data format, operational workaround và compatibility với khách hàng hoặc thiết bị. Software không hao mòn vật lý, nhưng environment và requirement thay đổi nên sustainment cost vẫn tiếp tục.110 Tuổi của hệ thống tự nó không quyết định giữ hay loại bỏ.

Chi phí phát triển đã chi là sunk cost, nhưng maintenance, security remediation, migration, parallel operation, data conversion, retraining, outage, rollback và regression risk trong tương lai đều là future cost. Nghiên cứu legacy modernization của CMU SEI cũng so sánh nhiều chiến lược, gồm incremental modernization và coexistence, theo điều kiện của hệ thống lớn và phức tạp.111

Google Android cho thấy ranh giới này trong thực tế. Android team giải thích rằng rewrite toàn bộ hàng chục triệu dòng C/C++ hiện hữu là không khả thi, nên ưu tiên memory-safe language cho code mới cùng Rust↔C++ và Rust↔Kotlin interoperability. Công việc firmware cũng ghi lại cách đưa Rust dần vào C codebase hiện hữu, ưu tiên code mới và component có security risk cao.112 Điều này không phủ nhận Rust; nó cho thấy full rewrite và incremental adoption có risk profile khác nhau.

FFI và giai đoạn chuyển tiếp là cost center độc lập

Áp dụng Rust từng bước phải duy trì boundary với ABI C/C++ hiện hữu. Như Mục 6.2 đã trình bày, extern "Rust" và default Rust layout không thể được coi là ABI ổn định dài hạn; có thể cần contract rõ ràng như C ABI và repr(C).102 Ngoài ra còn phải thiết kế ownership transfer, allocator ownership, string/buffer lifetime, error mapping, callback, cancellation, thread affinity và panic/exception boundary. Tương tự error model ở Mục 5.4, hai ngôn ngữ phải xác định cùng một failure được biểu diễn thế nào và ai chịu trách nhiệm cleanup/retry.

Cả “incremental adoption an toàn nên rẻ” lẫn “có FFI nên full rewrite tốt hơn” đều không phải quy tắc phổ quát. Module có boundary nhỏ và ổn định có thể phù hợp selective replacement; fine-grained crossing trải khắp hot path hoặc ownership thường xuyên qua lại có thể làm tăng performance, debugging và maintenance cost.

Chiến lược thay đổi là lựa chọn có điều kiện, không phải thứ hạng

Chiến lược Điều kiện có thể phù hợp Lợi ích chính Chi phí hoặc điều kiện thất bại chính
Củng cố implementation hiện hữu Defect cục bộ và validated behavior asset lớn Transition/regression risk thấp Structural memory-safety risk hoặc technical debt có thể còn lại
Modernize trong cùng ngôn ngữ Có thể cải thiện architecture/test/observability trước Tận dụng ABI và operational knowledge hiện hữu Safety rule tiếp tục phụ thuộc process và tooling
Viết chức năng mới bằng Rust Ít phải tái tạo behavior cũ và boundary rõ Tích lũy kinh nghiệm và safety boundary mà không rewrite Duy trì hai toolchain và interoperability
Selective replacement module rủi ro cao Memory-safety exposure tập trung và interface ổn định Tập trung assurance investment vào vùng rủi ro FFI, data ownership hoặc performance boundary có thể thành failure mode mới
Full rewrite Architecture hiện hữu không đáp ứng requirement và specification/test/budget/cutover plan đủ Thiết kế lại ngôn ngữ và architecture cùng lúc Schedule overrun, mất implicit specification, lỗi parallel operation/rollback có tác động lớn

Môi trường quy mô lớn và chạy dài hạn nên theo dõi migration duration và double-run cost, tác động p95/p99 request, peak memory, build/CI capacity, incident rate, rollback time, FFI crossing volume, duplicated tooling, security-patch latency, expert bus factor và multi-year support cost cho từng chiến lược. Selective adoption thành công vẫn có thể tích lũy boundary; rewrite có thể duy trì operational complexity của old/new system trong thời gian dài.

Kết luận tạm thời

Đối với RQ3 và RQ4, evidence hiện có không rút adoption barrier của Rust thành “thiếu nhân lực” hay “ecosystem chưa trưởng thành” cố định. Quyết định phụ thuộc staffing capability thực của tổ chức, assurance của dependency cần thiết, legacy asset và implicit specification, FFI boundary, migration/cutover risk. Codebase C/C++ lớn như Android thực tế dùng new-code-first và interoperability làm chiến lược chuyển đổi; full rewrite chỉ là một trong nhiều lựa chọn. Vì vậy Rust adoption nên được quyết định theo đơn vị thay đổi nào có thể giảm defect, cost và operational risk, không phải theo tỷ lệ code cần chuyển đổi.

7.4 Phân tích đa chiều câu chuyện “tập đoàn lớn tiếp nhận”

Việc các công ty công nghệ lớn như Google, Microsoft và AWS dùng Rust trong production là evidence quan trọng. Nhưng câu “công ty X dùng Rust” có thể trộn nhiều câu hỏi khác nhau: có thể production deployment hay không, outcome nào được quan sát trong workload cụ thể, Rust được dùng rộng đến đâu trong tổ chức, Rust có gây ra outcome đó không, và kết quả có lặp lại ở tổ chức khác không. Đây là các claim khác nhau.

Vì vậy phần này xem corporate adoption như case-study evidence, không phải logo ranking.

Case Việc sử dụng đã xác nhận Phạm vi case trực tiếp hỗ trợ Điều case đó tự nó không chứng minh
Google Android Rust trong native system code, kernel/firmware và security-critical component New-code-first và interoperability có thể vận hành trong codebase lớn hiện hữu, đồng thời đo được outcome nội bộ Android Ưu thế productivity/security của mọi Rust project, ngôn ngữ chuẩn toàn Google, hay kết quả giống hệt ở nơi khác
Microsoft Windows win32kbase_rs.sys triển khai GDI region trong Windows 11 24H2 Rust được ship trong một Windows kernel component production Toàn bộ Windows kernel chuyển sang Rust hoặc ranking defect/cost chung Rust-vs-C/C++
AWS Firecracker viết bằng Rust hỗ trợ AWS Lambda và các serverless offering khác; EC2 dùng Rust cho Nitro System component mới Rust vận hành như production technology trong workload high-performance isolation/infrastructure Tối ưu cho mọi AWS workload hoặc economics giống nhau ở tổ chức khác

Số liệu Google Android là case evidence mạnh, nhưng external validity là vấn đề riêng

Report Android 2025 của Google cho biết memory-safety vulnerability density của Rust code thấp hơn Android C/C++ code khoảng 1000 lần; Rust change có kích thước tương tự cần ít revision hơn khoảng 20%; thời gian ở code review thấp hơn khoảng 25%; và rollback rate của medium/large change thấp hơn C++ khoảng 4 lần.113 Những quan sát này có nhiều thông tin hơn rất nhiều so với câu “Google cũng dùng Rust”.

Tuy nhiên không nên đọc các con số đó như language-only causal effect. Vai trò, tuổi, thời điểm phát triển của code, thành phần team và review process không được random assignment; chính Google cũng nêu khả năng Rust expertise tăng trong Android team đã góp phần vào thay đổi review time. Vì vậy dữ liệu hỗ trợ mạnh outcome được quan sát cùng Rust adoption trong production environment Android, nhưng không chứng minh các hệ số giống hệt sẽ tái hiện phổ quát ở mọi tổ chức.

Microsoft và AWS cho thấy các adoption mode khác nhau

Documentation Windows 11 24H2 của Microsoft nêu rõ Rust implementation của GDI region trong win32kbase_rs.sys.114 Điều quan trọng là Rust không chỉ ở research prototype mà đã vào kernel component của OS release chính thức. Mở rộng một component thành “Windows đã chuyển sang Rust” là đọc sai adoption scale.

AWS có mode khác. Firecracker là microVM technology viết bằng Rust, dùng dưới AWS Lambda và các serverless offering khác; AWS cũng cho biết EC2 dùng Rust cho Nitro System component mới.115 Điều này cho thấy production operation trong workload virtualization, isolation và infrastructure, nhưng không thay thế evidence về suitability cho enterprise CRUD, data science, GUI, firmware, safety certification hay domain khác.

Do đó “tập đoàn lớn tiếp nhận” không phải homogeneous sample. New-code-first của Android, một Windows kernel component có boundary rõ, và Firecracker/Nitro thiên về Rust khác nhau về adoption unit, legacy boundary, performance requirement, assurance goal và đầu tư tổ chức. Xóa các điều kiện đó rồi chỉ đếm tên công ty sẽ biến evidence thành logo counting.

Successful case được chọn sẵn có selection effect

Công ty không random assignment ngôn ngữ cho mọi module. Họ có khả năng chọn Rust trước ở nơi memory-safety guarantee hoặc predictable low-level control có giá trị, có thể tạo component boundary, và có đủ expertise/tooling. Vì vậy adoption case thành công hỗ trợ “đã khả thi trong điều kiện này” và “outcome này được quan sát trong điều kiện này”, nhưng không tự động cung cấp counterfactual cho workload không chọn Rust.

Selection effect cũng không làm case study mất giá trị. Production deployment là evidence rằng system thật đã xử lý các vấn đề build, incident response, dependency, upgrade, observability và staffing mà toy benchmark không thể thể hiện. Chỉ cần giữ đơn vị evidence là product, component, khoảng thời gian và team cụ thể—not toàn bộ công ty.

Điều nên chuyển sang tổ chức khác là mechanism và điều kiện, không phải logo

Từ new-code-first/interoperability của Google, bounded kernel component của Microsoft và infrastructure-specific deployment của AWS, điều có thể rút ra không phải appeal to authority “tập đoàn lớn cũng dùng Rust” mà là change mechanism: giữ asset hữu ích, định nghĩa boundary, xây tooling/training cần thiết, đo mục tiêu security/rollback/review/latency/resource rồi mở rộng hoặc dừng dựa trên kết quả.

Tổ chức nhỏ hơn có thể thiếu interoperability tool chuyên dụng, compiler expertise, security-research capacity hoặc training budget dài hạn. Ngược lại, codebase nhỏ và deployment boundary đơn giản có thể làm migration dễ hơn. Không thể suy ra adoption difficulty đơn điệu chỉ từ kích thước tổ chức.

Kết luận Chương 7

Tổng hợp evidence của Chương 7, việc áp dụng Rust trong công nghiệp không thể tóm tắt bằng một trục “chưa trưởng thành” hoặc “đã được chứng minh vì tập đoàn lớn dùng”. Snapshot Linux 7.2.1 ở Mục 7.1 cho thấy Rust source footprint tăng và có code Binder/GPU driver thực tế, nhưng Rust vẫn dưới 1% tổng source SLOC; tỷ lệ này tự nó không đo safety effect hay adoption value. Ferrocene ở Mục 7.2 cho thấy qualified toolchain và một số certification path có thể tồn tại dù Rust chưa là ngôn ngữ chuẩn ISO/IEC, nhưng compiler qualification không chứng nhận mọi library hay final product.

Mục 7.3 cho thấy staffing, dependency assurance, legacy asset, FFI và cutover định hình change strategy của từng tổ chức. Mục 7.4 xác nhận Rust có thể vận hành trong các điều kiện production khác nhau như Android, một Windows kernel component và AWS infrastructure. Không case nào tự nó xác lập industry-wide prevalence, language-only causation hay comparative superiority cho mọi workload.

Đối với RQ3, adoption case và measurement phải được hiểu theo đúng unit thực tế. Production use hỗ trợ feasibility; internal longitudinal metric hỗ trợ observed outcome trong environment đó; qualification hỗ trợ assurance scope đã chỉ định. Kết hợp chúng không cho phép tự động suy ra universal superiority hay future market dominance.

Đối với RQ4, maintenance, same-language modernization, new-component Rust, selective replacement và full rewrite là chiến lược có điều kiện, không phải một ladder. Cần so sánh defect profile, code age, implicit specification, interoperability boundary, staffing, assurance goal, migration duration, rollback capability và long-term support trong cùng decision record.

Trong môi trường quy mô lớn, chạy dài hạn và cực hạn, memory/resource headroom, p95/p99 latency, failure containment, patch latency, toolchain reproducibility, dependency-replacement time, incident recovery, expert bus factor, duy trì certification evidence và multi-year upgrade/rollback cost có thể quan trọng hơn adoption percentage. Việc Rust thành công trong production vẫn cần một bước evidence riêng trước khi kết luận rằng một tổ chức cụ thể nên migration sang Rust.


Phần 4: Phân tích diễn ngôn cộng đồng kỹ thuật

Cho đến hết Phần 3, cuốn sách đã phân tích các bảo đảm của ngôn ngữ Rust, trải nghiệm nhà phát triển, chi phí build và triển khai, cùng các điều kiện áp dụng trong công nghiệp. Sang Phần 4, đơn vị phân tích chuyển từ bản thân công nghệ sang những tuyên bố và mẫu lập luận được công khai đưa ra về công nghệ. Câu hỏi trung tâm không phải là thích hay không thích một ngôn ngữ, mà là làm thế nào nhận ra thời điểm một lợi thế kỹ thuật có điều kiện bị mở rộng thành mệnh đề lựa chọn mang tính phổ quát, sự loại trừ các phương án khác, hoặc phán xét địa vị đối với con người.

Phần này phân biệt nghiêm ngặt các tầng bằng chứng. Tài liệu chính thức và project goals của Rust Project được dùng làm nguồn sơ cấp để xác nhận các giá trị được tuyên bố chính thức, ranh giới bảo đảm và các hạng mục cải tiến. Bài đăng công khai trên Reddit, Rust Users Forum và blog kỹ thuật chỉ được dùng như ví dụ định tính cho thấy một dạng lập luận cụ thể có thể thực sự xuất hiện. Hiện cuốn sách chưa có corpus được định nghĩa trước hoặc mẫu xác suất đại diện cho toàn bộ diễn ngôn trực tuyến về Rust, vì vậy không suy ra tần suất, tính đại diện hay đồng thuận của toàn cộng đồng từ các ví dụ được chọn.58

Nếu cùng một phép đo, sự cố hoặc bài đăng xuất hiện lại ở các mục sau, sách không đếm nó lại như một quan sát độc lập mới. Các sự kiện kỹ thuật và số liệu vẫn neo vào phần kỹ thuật đã được audit đầu tiên; những lần xuất hiện sau chỉ là tái sử dụng phân tích cho cấu trúc lập luận, tổng hợp hoặc ra quyết định. Vì vậy sự lặp lại không làm tăng trọng lượng bằng chứng, và kết luận mạnh hơn cần thêm bằng chứng độc lập.

Vì cùng lý do, một vài bài đăng công khai không đủ để xác định trạng thái tâm lý của tác giả, mức độ mạnh của bản sắc nhóm, sự tồn tại của echo chamber, thay đổi lựa chọn công nghệ của người mới, hay tác động nhân quả đến quyết định áp dụng trong tổ chức. Những cách giải thích như vậy có thể là giả thuyết có thể kiểm chứng để diễn giải lập luận đã quan sát, nhưng không trở thành kết luận thực nghiệm của cuốn sách nếu thiếu dữ liệu phỏng vấn, thí nghiệm, dọc theo thời gian, phân tích mạng hoặc mẫu diễn ngôn được định nghĩa riêng. Nghiên cứu tổng quát cũng cho thấy phân bố của dữ liệu huấn luyện lấy từ Web có thể ảnh hưởng hành vi mô hình ngôn ngữ; tuy nhiên việc một diễn ngôn Rust cụ thể làm thiên lệch câu trả lời của LLM đến mức nào so với các lựa chọn như Ada/SPARK vẫn là câu hỏi chưa được đo lường, cần corpus và thí nghiệm mô hình riêng.116

Chương 8 phân tích, theo các quy tắc bằng chứng này, dạng lập luận mà cuốn sách gọi là “câu chuyện viên đạn bạc (silver-bullet narrative)”.117 Cụm từ này không chỉ lập trường chính thức của Rust Project và cũng không phải chẩn đoán tâm lý đối với toàn bộ người dùng Rust. Đây là nhãn phân tích cho một mẫu suy luận trong đó lợi thế kỹ thuật vốn có điều kiện áp dụng bị tước bỏ các điều kiện đó rồi được tăng cường thành những kết luận như “giải pháp duy nhất”, “lựa chọn tốt nhất trong mọi môi trường”, hoặc “các chiến lược thay đổi khác đều vô nghĩa”. Chương 9 và 10 sau đó tổng hợp các hàm ý đối với lựa chọn công nghệ và hệ sinh thái nhưng không lấy tần suất hay tác động nhân quả mà Chương 8 chưa xác lập làm tiền đề.

Mục tiêu của Phần 4 không phải đánh giá một công nghệ hay người dùng của nó, mà là làm rõ phạm vi của một tuyên bố thay đổi ở đâu và cần bằng chứng nào để xác lập sự thay đổi đó.

8. Sự hình thành của câu chuyện viên đạn bạc và cơ chế phòng vệ tập thể

Trong Chương 8, “cơ chế phòng vệ tập thể” không phải tên gọi chẩn đoán lâm sàng hay tâm lý. Đây là nhãn gom các mẫu lập luận công khai nhằm bảo vệ tuyên bố ban đầu bằng cách chuyển trọng tâm, thay đổi tiêu chí so sánh, phân loại lại phản ví dụ hoặc phán xét năng lực của đối phương khi có phê bình hay bằng chứng phản bác. Việc một mẫu như vậy tồn tại trong một ví dụ cụ thể và việc nó phổ biến trong toàn bộ cộng đồng Rust là hai câu hỏi khác nhau.

Chương này tách ba câu hỏi. Thứ nhất, các giá trị và bảo đảm mà Rust Project chính thức tuyên bố có phạm vi đến đâu? Thứ hai, nếu trong các ví dụ công khai xuất hiện sự phổ quát hóa, thay thế hoặc phán xét địa vị mạnh hơn, chính xác đã có tiền đề bổ sung nào được đưa vào? Thứ ba, nếu muốn nói đến tần suất của những lập luận đó, động cơ của tác giả, tác động lên người tiếp nhận hoặc tác động nhân quả lên lựa chọn công nghệ, cần thêm bằng chứng nào? Sự phân biệt này trực tiếp trả lời RQ5: làm thế nào tách sự kiện kỹ thuật khỏi khái quát hóa tu từ và phán xét địa vị.

Mục 8.1 thiết lập ranh giới bằng chứng và tiêu chí phân loại “viên đạn bạc”. Mục 8.2 xem xét các tuyên bố chiến lược thay đổi mạnh về “thay thế hoàn toàn” và “chỉ viết lại mới là cải tiến”; Mục 8.3 xem xét phạm vi sử dụng so sánh lịch sử; Mục 8.4 và 8.5 xem xét các mẫu cụ thể khi phản hồi phê bình và khi phán xét năng lực/địa vị. Mục 8.6 và 8.8 tách governance và hoạt động cải tiến chính thức khỏi diễn ngôn phi chính thức; Mục 8.7 hỏi các khuyến nghị của chính phủ và trường hợp doanh nghiệp thực sự hỗ trợ kết luận trong phạm vi nào.

8.1 Quá trình hình thành và tác động của câu chuyện viên đạn bạc

Dù tiêu đề mục nói đến “quá trình hình thành và tác động”, điều đó không có nghĩa bằng chứng hiện tại có thể tái dựng bằng thực nghiệm quá trình hình thành lịch sử hay tác động xã hội của diễn ngôn Rust trực tuyến. Cuốn sách thiếu corpus theo thời kỳ được định nghĩa trước, tiêu chí đưa vào/loại ra bài đăng, lượng phơi nhiễm theo nền tảng và dữ liệu về người tiếp nhận. Vì vậy trước hết mục này tách sự kiện đã xác nhận, ví dụ định tính, giả thuyết giải thích khả dĩ và các tác động chưa được đo, rồi thiết lập quy tắc phán định dùng ở các mục sau.58

Tách giá trị chính thức khỏi sự khái quát hóa phi chính thức

Tài liệu chính thức của Rust Project mô tả các mục tiêu như reliability/robustness, performance/resource consumption và long-term maintenance/extensibility; đồng thời project goals 2025 trình bày các dự án coi trọng “hai hoặc nhiều hơn” trong ba trục này là những nơi Rust có thể trở thành ứng viên mạnh. Cùng tài liệu đó nêu rõ các công việc chưa hoàn thành như ergonomics của async Rust, compiler/tooling cần cho dự án low-level và hợp tác với maintainer; project goals 2026 cũng liệt kê các vấn đề cụ thể cùng nguồn lực cần thiết. Quy trình RFC và project-goals cũng giả định việc đề xuất, xem xét trade-off, hỗ trợ của team và các giới hạn nguồn lực.118

Những nguồn này xác lập rằng Rust Project đưa ra các giá trị mạnh trong khi đồng thời xử lý điều kiện áp dụng và các công việc chưa hoàn tất. Vì vậy, muốn quy các câu như “Rust giải quyết mọi vấn đề lập trình hệ thống” hoặc “mọi hệ thống C/C++ đều nên được viết lại bằng Rust” cho lập trường chính thức của Rust Project thì cần bằng chứng chính thức riêng. Chương này không nhập cách diễn đạt mạnh trong bài đăng phi chính thức thành tuyên bố chính thức của toàn dự án khi không có bằng chứng đó.

Phân tích không thay thế lẫn nhau bốn tầng bằng chứng sau.

Tầng bằng chứng Dữ liệu có thể trực tiếp cho thấy Chỉ dữ liệu đó không thể cho thấy
Tài liệu Rust chính thức, RFC, project goals Giá trị chính thức, mô tả bảo đảm, công việc cải tiến và quy trình Thái độ của mọi người dùng Rust; tần suất diễn ngôn phi chính thức
Bài đăng và thảo luận công khai được chọn Sự tồn tại của một phát biểu hoặc dạng lập luận cụ thể và phản biện trong ngữ cảnh đó Tính đại diện toàn cộng đồng, ý kiến đa số, xu hướng dài hạn
Corpus và sampling được định nghĩa trước Tần suất, thay đổi theo thời gian và khác biệt nền tảng trong quần thể đã định nghĩa Động cơ nội tại của tác giả hoặc bản thân tác động nhân quả
Dữ liệu phỏng vấn, thực nghiệm, dọc thời gian hoặc mạng Tùy thiết kế, một phần động cơ, phơi nhiễm, thay đổi thái độ hoặc đường lan truyền Khái quát vô điều kiện sang quần thể và thời kỳ khác

Vì sự phân biệt này, ngay cả khi các mục sau trích dẫn câu chữ mạnh, ví dụ đó trước hết chỉ xác lập “dạng lập luận ấy tồn tại”. Dạng đó có phổ biến hay không, có đại diện cho bản sắc nhóm người dùng Rust hay không, hoặc có thay đổi quyết định áp dụng thực tế hay không vẫn là các câu hỏi riêng.

Dạng suy luận được phân loại là “viên đạn bạc”

Cuốn sách không coi việc nêu mạnh ưu điểm của Rust là vấn đề tự thân. Chừng nào cơ sở kỹ thuật và điều kiện áp dụng vẫn được giữ, những mệnh đề như “Safe Rust loại bỏ một số lớp lỗi memory-safety đã xác định ở thời điểm compile”, “dùng Rust cho một thành phần mới cụ thể có thể giảm rủi ro lỗi”, hay “workflow tích hợp của Cargo có thể có lợi cho một team cụ thể” đều là các mệnh đề kỹ thuật có thể kiểm chứng. Phân loại “viên đạn bạc” chỉ áp dụng khi từ những mệnh đề có điều kiện đó xuất hiện suy luận bổ sung như sau.

Mệnh đề có điều kiện Suy luận mạnh hơn Bằng chứng bổ sung cần có
Safe Rust cung cấp bảo đảm memory-safety trong phạm vi đã định nghĩa Vì vậy Rust là lựa chọn an toàn nhất hoặc duy nhất có trách nhiệm cho mọi hệ thống So sánh bao gồm các loại nguy cơ khác, workload, FFI/unsafe, điều kiện vận hành và assurance/certification
Kết quả tốt được quan sát trong mã Rust mới của một tổ chức cụ thể Vì vậy full rewrite hệ thống hiện có sang Rust nói chung là tốt nhất So sánh gồm chiến lược thay thế, chi phí migration, thay đổi đồng thời, bảo trì dài hạn và trường hợp thất bại
C/C++ và Rust thường được so sánh trong các ví dụ công khai được chọn Vì vậy các ngôn ngữ khác bị cố ý loại bỏ và agenda của diễn ngôn đã bị chiếm Corpus được định nghĩa, nguyên nhân chọn đối tượng so sánh, dữ liệu phơi nhiễm và người tiếp nhận
Một số bài đăng phán xét năng lực hoặc địa vị của người phê bình Vì vậy toàn bộ cộng đồng Rust loại trừ phê bình Mẫu đại diện, tần suất theo nền tảng và thời kỳ, phản ví dụ và ngữ cảnh moderation

Nếu chưa có bằng chứng ở cột phải, cuốn sách không chấp nhận kết luận mạnh hơn. Tiêu chuẩn này đối xứng: chọn vài ví dụ chỉ trích Rust rồi kết luận “Rust không có lợi thế thực chất” hoặc “người dùng Rust nói chung là phi lý trí” cũng mắc cùng lỗi.

“Quá trình hình thành” hiện là mô hình cần kiểm nghiệm

Như Mục 2.3 đã xác nhận, tài liệu sơ cấp cho thấy Rust Project nhiều lần trình bày safety, performance, concurrency, productivity và trải nghiệm tooling như các giá trị chính thức.30 Nhưng các thông điệp chính thức được lặp lại bao nhiêu trong diễn ngôn phi chính thức, điều kiện giới hạn mất đi bao nhiêu trong quá trình lặp lại, và việc đó có làm thay đổi tiêu chí đánh giá của người tiếp nhận hay không là những câu hỏi thực nghiệm riêng.29

Vì thế mục này coi đường đi “giá trị chính thức → lặp lại phi chính thức → mất điều kiện giới hạn → mệnh đề lựa chọn được phổ quát hóa → phản ứng phòng vệ trước phê bình” là mô hình có thể được kiểm nghiệm bằng phân tích corpus trong tương lai, không phải một sự kiện lịch sử đã được chứng minh. Mỗi mũi tên cần loại dữ liệu khác nhau. Chỉ phân tích tần suất tài liệu chính thức không chứng minh được sự lặp lại phi chính thức; sự lặp lại phi chính thức không chứng minh được tác động lên người tiếp nhận; và một câu phản bác mạnh không tự chứng minh động cơ tâm lý của tác giả.

Nguyên tắc tương tự áp dụng cho ấn tượng rằng C/C++ thường xuất hiện làm đối tượng so sánh còn Ada/SPARK xuất hiện ít hơn. Trong bối cảnh như các trường hợp công nghiệp ở Chương 7, nơi chiến lược thay đổi giữa mã C/C++ hiện có và mã Rust mới là vấn đề trực tiếp, so sánh với C/C++ có thể hoàn toàn tự nhiên về kỹ thuật. Ngược lại, muốn xác định khả năng tiếp cận thông tin, kinh nghiệm giáo dục, mức độ xuất hiện trên thị trường hay framing có chủ ý đóng góp bao nhiêu vào việc chọn đối tượng so sánh, cần dữ liệu diễn ngôn được định nghĩa cùng dữ liệu phơi nhiễm và nền tảng. Không xác định sự loại trừ có chủ ý hay “chiếm quyền dẫn dắt diễn ngôn” chỉ từ quan sát rằng một phương án khác được nhắc đến ít hơn.

Giải thích tâm lý và nhóm là giả thuyết cạnh tranh, không phải chẩn đoán

Lý thuyết cognitive dissonance mô tả khả năng có xung đột giữa các nhận thức và sự điều chỉnh thái độ; social identity theory mô tả khả năng phân loại nhóm và thiên lệch in-group. Nghiên cứu về echo chamber trên mạng xã hội cũng cho thấy cấu trúc tương tác theo nền tảng và các kết nối đồng dạng có thể ảnh hưởng lan truyền thông tin.119 Tuy nhiên, chỉ gắn tên các lý thuyết chung này vào một bài đăng Rust không chứng minh rằng cơ chế tương ứng đã vận hành trong trường hợp đó.

Ví dụ, ngay cả khi quan sát thấy một tác giả đã đầu tư nhiều thời gian học Rust và phản ứng mạnh với phê bình, những quan sát đó không đủ để xác định cognitive dissonance là nguyên nhân. Người đó có thể đang sửa một hiểu lầm kỹ thuật, bác bỏ một tiền đề sai, hoặc đơn giản có phong cách diễn đạt mạnh. Tương tự, vài cuộc thảo luận đồng nhất không đủ để kết luận toàn bộ không gian liên quan đến Rust là echo chamber. Tuyên bố như vậy cần đo kết nối giữa người dùng, thông tin họ tiếp xúc, tính đồng nhất của tương tác, thay đổi theo thời gian và các nền tảng so sánh.

Tách sự nhấn mạnh chính thức về memory safety khỏi tuyên bố “chiếm agenda”

Như Mục 2.3 đã xác nhận bằng nguồn sơ cấp, truyền thông chính thức của Rust đã đưa memory safety, reliability, performance và các giá trị liên quan ra vị trí nổi bật.30 Tuy nhiên, các câu như “Rust đã chiếm agenda memory-safety của lập trình hệ thống” hay “nhà phát triển coi memory safety là tiêu chí quan trọng vì Rust” là những tuyên bố mạnh hơn, bao gồm cả thay đổi về mức độ quan trọng trong nhận thức của người tiếp nhận. Nếu không có dữ liệu nối mức độ nhấn mạnh của thông điệp với nhận thức của người tiếp nhận như trong thiết kế agenda-setting gốc, cuốn sách chỉ có thể xác nhận sự nhấn mạnh chính thức và sự tồn tại của thông điệp đó.29

Vì vậy, ấn tượng rằng Ada/SPARK, ngôn ngữ GC hoặc C/C++ hiện đại hóa ít xuất hiện hơn trong thảo luận công khai không được diễn giải ngay thành hiệu ứng Rust “chiếm agenda”. Kiểm nghiệm mệnh đề đó cần corpus giới hạn theo thời kỳ và nền tảng, lượng phơi nhiễm theo ngôn ngữ và chủ đề, môi trường search/recommendation, cùng survey hoặc experiment với người tiếp nhận. Hiện tại đây là giả thuyết có thể nghiên cứu, không phải kết luận đã xác định của chương.

Ranh giới của hệ sinh thái thông tin và tác động LLM

Có bằng chứng tổng quát rằng phân bố và lọc dữ liệu huấn luyện có nguồn từ Web có thể ảnh hưởng phân bố đầu ra của mô hình ngôn ngữ.116 Nhưng không thể từ đó nhảy thẳng đến “có nhiều văn bản ủng hộ Rust nên LLM đánh giá Rust quá cao”. Trước hết cần đo tỷ lệ và ngữ cảnh thực của Rust, C/C++, Ada/SPARK cùng các công nghệ liên quan trong corpus; xác định mô hình đã học từ dữ liệu nào hoặc xây dựng corpus đánh giá thay thế; và chạy thí nghiệm lặp lại trong đó kiểm soát cách đặt câu hỏi và tiêu chí đánh giá.

Vì vậy, cuốn sách chỉ xem LLM là một đường truyền thông tin thứ cấp có thể có. Vài câu trả lời trong đó một mô hình nhắc Rust trước không chứng minh phân bố dữ liệu huấn luyện của mô hình đó hay tác động nhân quả của diễn ngôn cộng đồng. Ngược lại, cũng chưa có cơ sở ở đây để kết luận tác động ấy không tồn tại. Câu hỏi này phù hợp hơn với một nghiên cứu riêng khi có thể thiết lập mô hình, prompt và thiết kế đánh giá có khả năng tái lập.

Kết luận tạm thời

Từ dữ liệu hiện tại có thể xác nhận ba điểm. Thứ nhất, Rust Project chính thức đưa ra các giá trị mạnh về safety, performance, reliability, productivity đồng thời xử lý điều kiện áp dụng và các công việc cải tiến chưa hoàn tất. Thứ hai, các ví dụ được chọn ở những mục sau có thể dùng để xem xét sự tồn tại của các dạng lập luận trong đó một mệnh đề kỹ thuật có điều kiện được mở rộng thành phổ quát hóa, thay thế hoặc phán xét địa vị. Thứ ba, tần suất của các dạng đó, bản sắc của toàn cộng đồng, tâm lý tác giả và tác động lên người mới, tổ chức hoặc LLM không thể được xác định từ corpus và thiết kế nghiên cứu hiện tại.

Ranh giới này là trọng tâm của RQ5. Các bảo đảm và ưu điểm kỹ thuật thực tế được đánh giá theo chính điều kiện của chúng; những tiền đề bổ sung chuyển từ các ưu điểm đó sang “lựa chọn duy nhất” hoặc phán xét năng lực con người được làm rõ riêng; và các ví dụ được chọn không bị khái quát vượt quá điều chúng chứng minh. Mục 8.2 tiếp theo áp dụng tiêu chuẩn này cho các tuyên bố chiến lược thay đổi về “thay thế hoàn toàn” và “chỉ viết lại mới là cải tiến”.

8.2 Giới hạn của câu chuyện “thay thế hoàn toàn” và “chỉ viết lại mới là cải tiến”

Mục này không phải dự báo thị trường về việc Rust trong tương lai có chiếm tỷ trọng lớn hơn ở một số lĩnh vực C/C++ hay không. Nó cũng không đo mức độ phổ biến của các phát biểu dưới đây trong diễn ngôn công khai. Đối tượng phân tích là bước nhảy suy luận xuất hiện khi những mệnh đề khác nhau sau đây bị gộp thành một kết luận.

  • Rust cung cấp bảo đảm mặc định mạnh hơn đối với một số loại lỗi cụ thể.
  • Một số hệ thống hiện có có thể hưởng lợi từ việc áp dụng Rust.
  • Trong một số lĩnh vực, tỷ lệ sử dụng Rust có thể tăng về dài hạn.
  • Vì vậy, mọi hệ thống C/C++ hiện có đều nên được viết lại hoàn toàn bằng Rust.
  • Vì vậy, refactoring, modernization và hardening trong cùng ngôn ngữ đều vô nghĩa.

Ba câu đầu lần lượt là các mệnh đề riêng về so sánh bảo đảm, chiến lược thay đổi có điều kiện và dự báo áp dụng trong tương lai. Hai câu sau là các chỉ dẫn mạnh hơn nhiều, áp dụng cho mọi hệ thống và mọi chiến lược thay đổi. Ngay cả khi các mệnh đề đầu đúng, những kết luận sau không tự động suy ra. Các cụm “thay thế hoàn toàn” và “chỉ viết lại mới là cải tiến” trong mục này không phải trích dẫn trực tiếp từ một cá nhân hay Rust Project; chúng là mệnh đề tổng hợp dùng để kiểm tra cấu trúc logic đã bị phổ quát hóa như vậy. Nếu muốn bàn về tần suất hoặc tính đại diện của chúng trong các ví dụ công khai, vẫn phải đáp ứng riêng tiêu chuẩn corpus của Mục 8.1.58

1. Đổi tên chiến lược thay đổi làm mất không gian lựa chọn

Mục 3.3 định nghĩa maintenance và defect hardening, refactoring, modernization, selective replacement, áp dụng Rust cho component mới và full rewrite là các đơn vị thay đổi khác nhau. Theo nghĩa hẹp, refactoring thay đổi cấu trúc bên trong nhưng giữ hành vi quan sát được; tạo một implementation mới bằng ngôn ngữ khác có thể thuộc selective replacement hoặc rewrite.45

Vì vậy, mệnh đề tổng hợp “refactoring thực sự duy nhất của C/C++ là rewrite bằng Rust” trước hết thay đổi phạm trù của thuật ngữ. Nếu mở rộng refactoring thành mọi hình thức cải tiến rồi lại định nghĩa language replacement, vốn chỉ là một chiến lược trong số đó, thành refactoring duy nhất đúng nghĩa, kết luận đã được đặt sẵn trong định nghĩa. Khi đó các câu hỏi sau biến mất trước khi được so sánh:

  • Cần giữ lại bao nhiêu hành vi và tính tương thích hiện có?
  • Rủi ro phân bố khắp hệ thống hay tập trung ở một số boundary?
  • Có thể cải thiện ownership, interface, testability và observability trong cùng ngôn ngữ không?
  • Có thể chỉ viết chức năng mới bằng Rust hoặc chỉ thay module rủi ro cao không?
  • Architecture hiện có có cản trở requirement đến mức cần redesign rộng hay không?

Nếu câu trả lời khác nhau, ngay trong cùng một codebase các chiến lược khác nhau vẫn có thể hợp lý. Gộp tên chiến lược trước không thay thế được phép so sánh đó.

2. “Không phải bảo đảm hoàn chỉnh” và “không có tác dụng” là hai mệnh đề khác nhau

Guideline, RAII, smart pointer, static analysis, sanitizer, fuzzing, isolation và hardening trong C/C++ không cung cấp language-level memory-safety contract giống Safe Rust. Như Mục 3.3 đã xác nhận, một số biện pháp phụ thuộc convention và cấu hình toolchain; dynamic analysis chỉ phát hiện lỗi trên các path đã chạy; instrumentation còn có chi phí tài nguyên và giới hạn dùng trong production.46

Nhưng không cung cấp bảo đảm giống Safe Rust không có nghĩa hiệu quả kỹ thuật bằng 0. Thu hẹp phạm vi raw pointer, làm rõ ownership boundary, phát hiện lỗi sớm hơn trong CI, cô lập code rủi ro, cải thiện rollback và observability đều có thể giảm xác suất xảy ra hoặc phạm vi tác động của rủi ro mục tiêu. Các hiệu quả đó đã đủ hay chưa phải được đo riêng theo threat model và assurance requirement tương ứng.

Chiều ngược lại cũng cần tiêu chuẩn đối xứng. Safe Rust ngăn chặn mạnh các lỗi memory-safety và data race nhất định trong một safe boundary sound, nhưng bản thân việc thay ngôn ngữ không loại bỏ lỗi logic, resource exhaustion, deadlock, regression hiệu năng, hành vi bị thiếu, lỗi contract ở unsafe/FFI, lỗi deployment hay rollback. Nếu yêu cầu cải tiến C/C++ phải “loại bỏ mọi rủi ro” nhưng lại coi chỉ sự tồn tại của một bảo đảm ngôn ngữ là đủ chứng minh toàn hệ thống sẽ thành công sau Rust rewrite, ta đã áp dụng chuẩn bằng chứng bất đối xứng.

Trọng tâm không phải cuộc thi về tính hoàn chỉnh, mà là dùng cùng metric để đánh giá, với cùng defect model và mục tiêu vận hành, mỗi chiến lược ngăn chặn, phát hiện hay giảm nhẹ rủi ro nào, ở mức nào, đồng thời tạo ra rủi ro chuyển đổi mới nào.

3. Bảo đảm ngôn ngữ và phương thức thay đổi là hai trục độc lập

Việc một bảo đảm ngôn ngữ mạnh có giá trị và việc dự án nên thay đổi phạm vi nào, bằng phương thức nào để nhận bảo đảm đó là hai câu hỏi khác nhau. Khi áp dụng Rust, dự án có thể chỉ viết component mới bằng Rust, selective replacement một module hẹp, hoặc chọn rewrite rộng hơn. Ngược lại, dự án giữ C/C++ vẫn có thể modernization architecture, ownership discipline, test, analysis và isolation.

Chiến lược memory-safety chính thức của Android là ví dụ thực tế sử dụng đồng thời hai trục này. Android ưu tiên memory-safe language cho native code mới, đồng thời tiếp tục áp dụng sanitizer, memory tagging và hardening cho C/C++ hiện có, và đầu tư vào interoperability giữa Rust với code hiện hữu.47 Các trường hợp firmware cũng ghi nhận áp dụng Rust tăng dần, ưu tiên code mới và các component hiện có có rủi ro bảo mật cao.112

Những trường hợp này không chứng minh quy luật “áp dụng tăng dần luôn là tốt nhất”. Nhưng chúng là bằng chứng về khả năng rằng cải thiện memory safety không đòi hỏi phải loại bỏ toàn bộ hệ thống hiện có trước tiên. Ở chiều ngược lại, như ví dụ bounded rewrite trong Mục 3.3, rewrite cấp component có thể hợp lý khi boundary hẹp, requirement và phạm vi validation có thể kiểm soát, còn lợi ích bảo đảm của implementation mới đủ lớn. Chiến lược thay đổi là các lựa chọn có điều kiện, không phải thang bậc trưởng thành.

4. Interoperability không phải “định mệnh phải cùng tồn tại” cũng không phải “mệnh lệnh rewrite toàn bộ”

Bản cũ từng mô tả khá rộng rằng hệ điều hành, driver và library dùng C ABI làm interface chuẩn, vì vậy Rust buộc phải cùng tồn tại lâu dài với hệ sinh thái C. Phạm vi đó quá rộng. Trong nhiều migration nối Rust với code C/C++ hiện có, OS API và library, các representation contract tường minh như C ABI và repr(C) thực sự là boundary quan trọng. Tuy nhiên, không phải mọi system interface đều quy về một C ABI, và riêng sự thật này cũng không quyết định thời gian cùng tồn tại hoặc hình thức migration cuối cùng.102

FFI thực sự tạo ra các chi phí riêng. Ownership transfer, allocator, lifetime của buffer/string, error mapping, callback, cancellation, thread affinity và unwind/panic boundary phải được quy định; crossing hạt mịn lan khắp hot path có thể tăng chi phí hiệu năng, debugging và maintenance. Nhưng kết luận vẫn có điều kiện:

  • Nếu boundary hẹp và ổn định, selective replacement và coexistence có thể hiệu quả về chi phí.
  • Nếu boundary quá phức tạp hoặc architecture hiện có cản trở yêu cầu mới, rewrite rộng hơn đôi khi đơn giản hơn.
  • Nếu là component mới, có thể dùng Rust mà không cần tái tạo behavior hiện có.

Vì vậy, “cần FFI nên Rust không thể thay thế hệ sinh thái hiện có” và “FFI phiền phức nên full rewrite là câu trả lời duy nhất” đi theo hai hướng đối lập nhưng đều bỏ qua điều kiện cần. Như Mục 7.3 đã nêu, đơn vị phán định thực tế là crossing volume, boundary stability, ownership contract, latency/resource budget, chi phí duy trì dual-toolchain và rollback capability.

5. Đánh giá legacy bằng rủi ro và tài sản trong tương lai, không phải tuổi

Từ “legacy” cũng dễ chuyển từ mô tả thành phán xét giá trị. Một implementation cũ có thể tích lũy technical debt và rủi ro hết support, nhưng cũng có thể tích lũy tài sản đã được validation và implicit specification như regression test, quy trình deployment, data format, tương thích khách hàng/thiết bị, operational workaround và kiến thức incident response. Nghiên cứu về software sustainment chỉ ra rằng software không phải vật thể bị hao mòn vật lý; chi phí maintenance phát sinh khi execution environment, requirement, defect và điều kiện performance thay đổi.110

Do đó cả “cũ nên phải bỏ” lẫn “đã được kiểm chứng lâu nên không được thay đổi” đều không đủ. Chi phí phát triển đã chi có thể là sunk cost, nhưng behavior phải bảo tồn trong tương lai, chi phí migration và parallel operation, data conversion, retraining, outage risk và rollback risk là chi phí tương lai thực tế. Nghiên cứu legacy modernization cũng so sánh incremental modernization, coexistence và replacement theo điều kiện dự án trong các hệ thống lớn, phức tạp.111

Vì thế không nên đạo đức hóa legacy thành “thứ xấu” hay “thứ phải giữ”, mà phải đặt defect và trạng thái support hiện tại cùng với chi phí maintenance và transition tương lai trong cùng decision record. Phán xét năng lực hay trách nhiệm của một người dựa trên tuổi của ngôn ngữ họ dùng không cung cấp bằng chứng cần thiết cho so sánh kỹ thuật. Các mẫu phán xét qualification/status cụ thể được phân tích riêng ở Mục 8.5.

6. “Thay thế hoàn toàn” phải phân biệt dự báo, chỉ dẫn và kết quả đo

Tùy ngữ cảnh, câu “Rust sẽ thay C/C++” có ít nhất ba chức năng.

Chức năng của câu Bằng chứng cần thiết Tiêu chuẩn phán định trong chương này
Dự báo thị trường/hệ sinh thái: tỷ lệ sử dụng Rust sẽ tăng về dài hạn Population được định nghĩa, adoption data theo chuỗi thời gian, phân chia domain, mô hình dự báo và bất định Không xác định thị phần tương lai của toàn thị trường chỉ từ vài case doanh nghiệp hoặc nhiệt tình trên mạng
Chỉ dẫn cho dự án: hệ thống này nên thay rộng sang Rust So sánh defect distribution, assurance goal, specification/test asset, interop, migration/rollback, performance/resource, staffing/lifecycle cost Phải so với các chiến lược thay thế trong điều kiện của chính dự án đó
Mệnh đề phổ quát: cải tiến có ý nghĩa duy nhất là Rust full rewrite Bằng chứng so sánh cực mạnh bao quát thực chất mọi workload liên quan và chiến lược thay thế Bằng chứng hiện tại không hỗ trợ; đây là khái quát quá mức vì đóng khả năng phản ví dụ

Các trường hợp Android, Windows và AWS ở Mục 7.3, 7.4 cho thấy Rust có thể được dùng thực tế trong các điều kiện production khác nhau; Android còn ghi lại chiến lược new-code-first và interoperability. Nhưng production feasibility, observed outcome trong một tổ chức, adoption scale, language-only causation và future market dominance là những mệnh đề khác nhau. Việc doanh nghiệp lớn áp dụng thành công không tạo ra chỉ dẫn phổ quát cho full rewrite; tương tự, khó khăn của một legacy migration cũng không bác bỏ triển vọng áp dụng Rust dài hạn.

Trong môi trường quy mô lớn, chạy dài hạn và cực đoan, đặc biệt cần theo dõi theo từng chiến lược: thời gian migration, chi phí chạy song song old/new, p95/p99 latency, peak memory, build/CI capacity, incident recovery, security-patch latency, FFI crossing volume, duplicated tooling, expert bus factor, rollback time và multi-year support cost. Thay vì chỉ hỏi “bao nhiêu phần trăm là Rust”, dữ liệu trực tiếp hơn có thể là rủi ro nào được giảm ở đơn vị thay đổi nào và chi phí thất bại của quá trình chuyển đổi là bao nhiêu.

Kết luận tạm thời

Đối với RQ4, maintenance, refactoring, modernization, Rust cho component mới, selective replacement và full rewrite là các chiến lược có điều kiện, không phải những bậc phủ định lẫn nhau. Bảo đảm memory-safety mạnh của Safe Rust có thể là căn cứ quan trọng cho selective replacement hoặc rewrite, nhưng tự nó không tự động quyết định phạm vi thay đổi hay phương thức migration.

Đối với RQ5, khi phân tích “thay thế hoàn toàn” hoặc “chỉ viết lại mới là cải tiến”, cần làm lộ rõ các tiền đề bổ sung khi đi từ mệnh đề bảo đảm sang chiến lược thay đổi, từ một case cụ thể sang chỉ dẫn phổ quát, hoặc từ đánh giá công nghệ sang phán xét địa vị con người. Khi dùng các ví dụ công khai được chọn, ban đầu chúng chỉ cho thấy sự tồn tại của dạng lập luận đó; nếu không có corpus được định nghĩa, không suy ra tần suất hay ý định của toàn bộ cộng đồng Rust.

Vì vậy, kết luận của mục này không phải “full rewrite là sai” cũng không phải “Rust adoption là không cần thiết”. Kết luận hẹp hơn được bằng chứng hiện tại hỗ trợ là phải tách bảo đảm ngôn ngữ khỏi chiến lược thay đổi và so sánh các phương án bằng cùng defect model, metric vận hành và chi phí chuyển đổi. Mục 8.3 tiếp theo xem xét những điểm tương đồng nào hữu ích và phép loại suy nên dừng ở đâu khi so sánh câu chuyện cạnh tranh của cộng đồng kỹ thuật với các trường hợp lịch sử.

8.3 Tiền lệ lịch sử của diễn ngôn kỹ thuật: cạnh tranh hệ điều hành những năm 1990–2000

So sánh lịch sử trong mục này không nhằm chứng minh rằng “cộng đồng Linux những năm 1990–2000 và cộng đồng Rust hiện nay lặp lại cùng một hành vi nhóm”. Hacker culture, phong trào GNU/free software, phong trào open-source, người dùng và nhà phát triển Linux, cùng các không gian trực tuyến liên quan đến Unix có phần chồng lấn nhưng không phải cùng một quần thể. Hệ sinh thái Rust hiện nay cũng không thể gộp project chính thức, người dùng doanh nghiệp, library maintainer và nhiều không gian trực tuyến thành một tâm lý nhóm duy nhất. Vì vậy mục này chỉ dùng các trường hợp lịch sử làm tư liệu so sánh để nhận diện cấu trúc lập luận tương tự, không dùng bản thân sự tương tự làm bằng chứng về tần suất, nguyên nhân hay tác động của diễn ngôn Rust hiện tại.58

Tư liệu lịch sử trước hết cho thấy khác biệt nội bộ, không phải một bản sắc duy nhất

Ngay cả khi chỉ xét free software và open source vào cuối những năm 1990, framing về giá trị cũng không đồng nhất. GNU/Free Software Foundation đặt software freedom và community ở trung tâm như các giá trị chuẩn tắc. Ngược lại, lịch sử chính thức của Open Source Initiative ghi rằng khi tạo tên “open source” năm 1998, một mục tiêu là truyền đạt hiệu quả hơn các lợi ích thực dụng và business-case của source-sharing, đồng thời tách framing đó khỏi nhãn “free software” mang hàm ý triết học và chính trị mạnh hơn.120 Ngay trong thế giới phát triển hợp tác source-available rộng hơn, đã có khác biệt về việc giá trị nào nên được đặt ở trung tâm.

The Cathedral and the Bazaar của Eric S. Raymond cũng không mô tả Linux community như một tiếng nói duy nhất; tác phẩm dùng ẩn dụ bazaar cho một thế giới phát triển nơi nhiều agenda và approach khác nhau cùng tồn tại.121 Điều này không có nghĩa diễn ngôn công khai thời đó không có narrative hay ngôn ngữ identity mạnh. Nó có nghĩa cách đọc an toàn hơn từ nguồn đương thời là không thể chỉ dùng nhãn “Linux community” để đại diện cho một giá trị, thái độ hay lập luận duy nhất.

M$RTFM là các dấu hiệu văn hóa có tài liệu ghi nhận, nhưng tính đại diện là câu hỏi riêng

The Jargon File 4.2.2 (2000), như một historical snapshot của hacker slang, ghi M$ là network abbreviation chỉ Microsoft và RTFM là biểu đạt có thể được dùng trong Unix hacker context để gạt đi các câu hỏi bị xem là quá đơn giản hoặc gây phiền. Phần mở đầu của cùng tài liệu mô tả hacker culture như một tập hợp các subculture kết nối lỏng lẻo nhưng có chung roots và values, đồng thời giải thích rằng slang có thể là dấu hiệu của inclusion và exclusion.122

Phạm vi suy luận được nguồn này hỗ trợ là có giới hạn. Có thể ghi nhận rằng các biểu đạt như M$RTFM thực sự tồn tại trong một phần văn hóa kỹ thuật thời đó và ngôn ngữ kỹ thuật có thể biểu đạt sự thuộc về và ranh giới. Nhưng từ đó không thể suy ra các mệnh đề ở cấp quần thể như “đa số người dùng Linux coi Microsoft là kẻ thù đạo đức”, “loại trừ người mới là chuẩn mực chung của cộng đồng Linux”, hay “người dùng CLI có hệ thống coi người dùng GUI thấp kém hơn”. Những mệnh đề đó cần corpus lịch sử và sampling được định nghĩa cho mailing list, Usenet, forum hoặc nguồn tương đương.

Điều phép loại suy lịch sử có thể so sánh là sự biến đổi của mệnh đề, không phải tính cách của con người

Khi so sánh diễn ngôn Rust hiện nay với diễn ngôn hệ điều hành và FOSS trước đây, đơn vị so sánh tương đối an toàn không phải tính cách của một nhóm mà là cách một mệnh đề kỹ thuật có điều kiện được biến thành mệnh đề rộng hơn về giá trị, identity hoặc status. Các cấu trúc sau vẫn có thể được phân tích dù thời kỳ và công nghệ khác nhau.

Cấu trúc lập luận có thể so sánh Tư liệu lịch sử có thể cho thấy Điều không thể tự động chuyển sang diễn ngôn Rust
Ngôn ngữ giá trị gắn với thuộc tính kỹ thuật Nhiều value frame thực sự đi cùng lựa chọn công nghệ, gồm freedom, community và pragmatic development model Kết luận rằng người dùng Rust có cùng cấu trúc giá trị hoặc identity
Shorthand trong nhóm biểu đạt sự thuộc về hoặc ranh giới Hacker slang ghi nhận chức năng inclusion/exclusion và cách dùng như M$, RTFM Kết luận rằng gatekeeping với cùng cường độ hoặc tần suất tồn tại trong không gian Rust hiện nay
Công nghệ cạnh tranh được dùng làm đối tượng so sánh trong narrative Có các trường hợp documented framing đối lập như proprietary/open development và Microsoft/open source Kết luận rằng so sánh Rust với C/C++ hình thành từ cùng nguyên nhân hay động cơ lịch sử
Triển vọng tương lai có thể trộn với đánh giá kỹ thuật hiện tại Có tài liệu cho thấy phong trào và tổ chức lịch sử theo đuổi adoption và diffusion một cách rõ ràng Future market share của Rust hay mức độ lạc quan trên toàn cộng đồng hiện nay

Do đó tư liệu lịch sử có thể giúp xây dựng các mechanism lập luận khả dĩ và tiêu chí phân loại. Nhưng suy luận “trước đây đã vậy, nên Rust cũng vậy” biến phép loại suy thành loại bằng chứng mà nó không thể cung cấp.

Phải dừng phép loại suy ở nơi khác biệt lớn

Cạnh tranh hệ điều hành/FOSS trong những năm 1990–2000 khác với Rust adoption hiện nay ngay từ đơn vị kỹ thuật. Cạnh tranh hệ điều hành là cạnh tranh platform kết hợp kernel, userspace, driver, application ecosystem, distribution và hardware support. Rust là programming language có thể được đưa từng phần vào nhiều hệ điều hành và dùng bên cạnh ngôn ngữ, library hiện có, vì vậy selective replacement và new-component adoption như Mục 8.2 là khả thi. Chi phí chuyển từ một desktop OS sang OS khác không cùng đơn vị với chi phí triển khai một phần module của codebase bằng ngôn ngữ khác.

Cấu trúc tổ chức và môi trường media cũng khác. Usenet, mailing list và hacker lexicon của thập niên 1990 có cấu trúc exposure và moderation khác Reddit, social media, corporate engineering blog và Foundation governance hiện nay. Và cũng như GNU, OSI, Linux kernel và các distribution community là những tổ chức khác nhau, Rust Foundation, governance của Rust Project, Rust adoption trong doanh nghiệp và phát biểu ở từng online forum cũng là các đơn vị bằng chứng khác nhau. Ánh xạ một biểu đạt lịch sử thành lập trường Rust chính thức hoặc văn hóa của toàn bộ người dùng hiện nay sẽ xóa các khác biệt đó.

Vì vậy mục này không “chuyển” các psychological mechanism như cognitive dissonance hay social identity từ trường hợp lịch sử sang hiện tại. Ngay cả khi thấy cách diễn đạt giống nhau trong quá khứ và hiện tại, việc chúng phát sinh từ cùng nguyên nhân tâm lý hay tạo cùng community-level effect vẫn là câu hỏi nghiên cứu riêng.

Kết luận tạm thời

Đối với RQ5, vai trò của tiền lệ lịch sử có giới hạn nhưng hữu ích. Nguồn đương thời cho thấy các technical claim, value frame, group shorthand và competitive narrative thực sự cùng tồn tại quanh các thế giới hacker, free-software, open-source và Linux trong những năm 1990–2000. Cùng các nguồn đó cũng cho thấy thế giới này chia thành nhiều subculture cùng các frame triết học và thực dụng khác nhau.

Do đó, cuốn sách không dùng trường hợp quá khứ để suy ra tâm lý hay prevalence của cộng đồng Rust hiện nay. Chúng chỉ được dùng như công cụ so sánh để tìm nơi phạm vi mệnh đề chuyển đổi, chẳng hạn sự kiện kỹ thuật → mệnh đề giá trị → mệnh đề lựa chọn phổ quát → phán xét status đối với con người. Khi ranh giới lịch sử này đã rõ, các ví dụ thảo luận công khai trong Mục 8.4 tiếp theo cũng phải được đọc như tư liệu định tính để xem xét từng cấu trúc lập luận và khả năng phản biện, chứ không phải bằng chứng của “cùng một hành vi nhóm như trong quá khứ”.

8.4 Phân tích các mẫu lập luận khi đáp lại phê bình

Theo các quy tắc bằng chứng đã thiết lập ở Mục 8.1, mục này không suy đoán tần suất phản ứng hay tâm lý của toàn bộ cộng đồng Rust từ một số ít ví dụ công khai. Đơn vị phân tích là liệu phản hồi B có thực sự bác bỏ cùng mệnh đề mà phát biểu A đưa ra hay không, hay nó chuyển sang phạm vi khác, tiêu chí so sánh khác, hoặc đánh giá người phát biểu. Khi xác định được một trường hợp công khai, chúng tôi tách sự kiện có thể kiểm chứng khỏi đánh giá của người tham gia; các câu không có nguồn trực tiếp được ghi rõ là ví dụ tổng hợp dùng để kiểm tra cấu trúc lập luận chứ không phải trích dẫn của một cá nhân cụ thể.58

Không phải mọi sự thu hẹp phạm vi đều là né tránh vấn đề. Chẳng hạn, câu “đây không phải là memory-safety vulnerability” là một hiệu chỉnh phạm vi trực tiếp nếu mệnh đề ban đầu là “memory-safety contract của Rust có bị phá vỡ hay không?”. Nhưng nếu mệnh đề ban đầu là “safe API này có thể tạo ra một security flaw nghiêm trọng hay không?”, câu đó một mình chưa trả lời tác động bảo mật. Vì vậy, trước khi gắn tên một ngụy biện, chúng tôi tách mệnh đề ban đầu, mệnh đề mà phản hồi thực sự xử lý, và những mệnh đề còn chưa được giải quyết.

8.4.1 Tỷ lệ Rust trong Linux 7.2.1: tách số đo khỏi đánh giá về tầm quan trọng

Phép đo lại stable mới nhất ở Mục 7.1 cho thấy source tree Linux 7.2.1 có 114.481 Rust SLOC, khoảng 0,375% trong tổng 30.518.591 SLOC. Điều con số này trực tiếp chứng minh chỉ là source-tree composition của tarball đó theo quy trình cloc v2.04 đã nêu.106

Do đó hai phát biểu sau có thể đồng thời đúng:

  • “Footprint định lượng của Rust trong stable kernel source hiện tại dưới 1%.”
  • “Một source footprint nhỏ vẫn có thể quan trọng về kỹ thuật trong một driver hoặc security boundary cụ thể.”

Trả lời phát biểu thứ nhất bằng “Rust code nằm trong subsystem quan trọng nên SLOC vô nghĩa” có liên quan tới tầm quan trọng, nhưng không bác bỏ chính số đo SLOC. Ngược lại, suy từ 0,375% rằng “Rust không quan trọng trong kernel” hoặc “Rust không thể phát triển trong tương lai” cũng vượt quá phạm vi của phép đo.

Nguyên tắc tương tự áp dụng khi đưa ra các deployment Rust khác của Google, Microsoft và AWS. Các trường hợp production đó hỗ trợ mệnh đề riêng rằng Rust có thể được vận hành trong production; chúng không làm thay đổi tỷ lệ source của Rust trong Linux 7.2.1. Nếu câu hỏi ban đầu là Rust có được dùng trong production hay không, chúng có thể là phản chứng hợp lệ. Nếu câu hỏi là bao nhiêu phần trăm snapshot kernel này là Rust, chủ đề đã thay đổi.

Tấn công ngôn ngữ ưa thích hoặc động cơ của người đo cũng không cho thấy lỗi trong phương pháp đo. Một ví dụ tổng hợp như “người đo dùng Ada nên không thể tin con số này” vẫn chỉ là đánh giá người phát biểu nếu không chỉ ra lỗi ở artifact, checksum, tool version hoặc counting rule. Ngược lại, một kết quả tái lập khác hoặc bằng chứng rằng cloc phân loại sai các file liên quan là phê bình phương pháp chính đáng.

8.4.2 Memory leak: tách ranh giới bảo đảm khỏi mức độ nghiêm trọng trong vận hành

Rust Reference nêu rõ memory/resource leak và việc destructor không chạy là hành vi không được xem là unsafe, và std::mem::forget là một safe function. Rust Book cũng cho thấy strong-reference cycle dùng Rc<T>RefCell<T> có thể gây leak trong Safe Rust.41 Vì vậy phát biểu “leak này không vi phạm memory-safety contract của Rust” có thể đúng về kỹ thuật.

Nhưng câu hỏi vận hành — liệu retained object có thể gây OOM, tăng latency, restart và giảm availability trong một service chạy lâu hay không — là một câu hỏi khác. Mở rộng thành “memory-safe nên không phải vấn đề” sẽ trộn lẫn phạm vi bảo đảm với mức độ nghiêm trọng trong vận hành. Ngược lại, khả năng xảy ra leak cũng không làm cho các bảo đảm của Safe Rust đối với use-after-free hay invalid access trở nên vô nghĩa.

Lập luận “developer lẽ ra phải dùng Weak<T>” cũng cần tách thành hai tầng. Có thể đúng rằng application design là nguyên nhân trực tiếp của một reference cycle cụ thể. Nhưng API có khiến cycle dễ hình thành hay không, observability·quota·restart policy có đủ hay không, và library design có thể giảm rủi ro hay không là những câu hỏi system design riêng. Quy trách nhiệm không làm rủi ro vận hành biến mất.

8.4.3 rav1d/dav1d: ba câu hỏi riêng về phạm vi an toàn, quy thuộc hiệu năng và bảo trì

rav1d không phải ví dụ giả định mà là một trường hợp tranh luận công khai có thể truy vết. Năm 2023, Prossimo của ISRG cùng Immunant bắt đầu rav1d, một bản port sang Rust của AV1 decoder dav1d viết bằng C của VideoLAN. Mục tiêu chính thức là chuyển C code của dav1d sang Rust để tăng memory safety, đồng thời giữ lại native assembly hiện có vì hiệu năng, duy trì drop-in C API compatibility với dav1d, và giúp việc đồng bộ thường xuyên assembly cùng thay đổi upstream trở nên thực tế.123

Các báo cáo kỹ thuật Prossimo/Immunant năm 2024 nói rõ rằng nhiều thao tác low-level quan trọng về hiệu năng trong dav1d được viết bằng native assembly và được tái sử dụng. Đồng thời, ngay cả khi bật toàn bộ assembly khả dụng, Rust code vẫn chiếm khoảng một nửa decoding runtime; các báo cáo cũng mô tả quá trình chuyển dần output unsafe của C2Rust thành Rust safe và idiomatic trong khi phân tích chi phí bounds check, threading model và buffer ownership.123 Vì vậy cả “toàn bộ hiệu năng rav1d là do Rust tạo ra” lẫn “phần Rust không đóng góp gì cho hiệu năng” đều mạnh hơn bằng chứng chính thức.

Năm 2025, Prossimo báo cáo rav1d vượt cùng các test như dav1d và có thể chạy trong Chromium, nhưng khi đó chậm hơn khoảng 5%, tùy benchmark, input và platform; họ công bố $20,000 bounty để thu hẹp khoảng cách. Cùng năm, rav1d 1.1.0 cũng ghi rõ việc đồng bộ bằng cách backport các cải tiến hiệu năng từ dav1d 1.5.1.124

Trong thảo luận công khai quanh cấu trúc này, ba nhóm phê bình đã thực sự được nêu: thứ nhất, khi tái sử dụng native assembly qua unsafe boundary thì cụm từ “memory-safe decoder” nên áp dụng đến phạm vi nào; thứ hai, mô hình bảo trì phải liên tục backport cải tiến từ dav1d sang rav1d có bền vững lâu dài hay không; thứ ba, một fork riêng có thể duy trì codec expertise và tốc độ upstream bug response tương đương trong thời gian dài hay không.125 Trường hợp công khai này chỉ chứng minh những câu hỏi đó thực sự đã được nêu ra; nó không chứng minh đồng thuận của toàn bộ developer FFmpeg/VideoLAN hay của cộng đồng C hoặc Rust nói chung.

Điểm quan trọng nhất là không gộp ba câu hỏi. Câu hỏi an toàn hỏi parser·control code chuyển sang Rust và các assembly/FFI boundary còn lại có những memory-safety invariant nào. Câu hỏi quy thuộc hiệu năng hỏi Rust, reused assembly, algorithm, compiler, threading và optimization đóng góp bao nhiêu vào kết quả. Câu hỏi bảo trì hỏi chi phí đồng bộ upstream, fork ownership, codec expertise và support horizon.

Vì vậy, kết luận “tái sử dụng assembly nên Rust port không có giá trị an toàn” bỏ qua tác dụng của việc chuyển parser và higher-level C code sang safe Rust. Ngược lại, cũng không nên đọc “memory-safe Rust decoder” như một bảo đảm vô điều kiện bao phủ assembly và mọi boundary bên ngoài. Chính Prossimo nói rõ assembly vẫn được giữ dưới dạng unsafe native routine; mô tả chính xác hơn là một bản port giảm đáng kể vùng memory-unsafe C nhưng vẫn giữ native-assembly boundary cần thiết cho hiệu năng.123

Tương tự, phê bình về quy thuộc thành quả upstream và đạo đức hợp tác nằm ở tầng khác với đo lường hiệu năng và an toàn. Việc rav1d dựa trên dav1d và tái sử dụng upstream assembly cùng các thay đổi là điều được công khai rõ ràng. Việc tái sử dụng đó có được ghi nhận công lao thỏa đáng hay không, attribution có đủ hay không, và funding/maintenance model có đáng mong muốn về lâu dài hay không còn cần các phán đoán governance và giá trị. Các nhãn như “cấu trúc đóng góp bất đối xứng” hay “tính trung thực trí tuệ” phải nêu rõ tiền đề; bản thân nhãn không thay thế benchmark hay bằng chứng memory safety.

8.4.4 CVE của std::process::Command: tách memory safety khỏi security

CVE-2024-24576 do Rust Security Response WG công bố năm 2024 liên quan đến việc std::process::Command trên Windows escape argument của batch file không đầy đủ, có thể dẫn tới thực thi shell command tùy ý khi attacker kiểm soát argument. Vấn đề ban đầu được sửa trong Rust 1.77.2; sau đó một vấn đề bypass mitigation riêng, CVE-2024-43402, được báo cáo và bổ sung sửa trong Rust 1.81.0.44

Câu “đây không phải memory-safety vulnerability” là đúng khi dùng để phân loại defect. Đây không phải buffer overflow hay use-after-free mà là lỗi logic trong command argument/API contract. Nhưng nếu câu hỏi là “Safe Rust API có thể chứa security bug nghiêm trọng hay không”, chỉ nhắc lại memory-safety boundary chưa trả lời toàn bộ câu hỏi.

Ngược lại, một CVE như vậy cũng không chứng minh memory-safety contract của Rust đã thất bại. Bài học chính xác là memory safety là một tập con của security, và safe API vẫn có thể triển khai sai các contract khác như shell escaping, authorization, protocol hoặc state-machine logic.

8.4.5 CVE Linux Rust Binder: unsafe boundary và quy trách nhiệm

CVE-2025-68260 là trường hợp thực tế trong đó unsafe list removal khi xử lý death_list của Linux Rust Binder không phù hợp với điều kiện concurrent access, dẫn tới data race và pointer corruption. Defect này ảnh hưởng Linux 6.18 và được sửa trong 6.18.1 cùng dòng 6.19.107

Hai phát biểu “đặc tả ngôn ngữ không tự biến data race thành hành vi safe” và “unsafe proof obligation của một Rust abstraction đã thất bại trong implementation” có thể đồng thời đúng. unsafe không phải nhãn miễn trừ để bỏ defect ra khỏi đánh giá language/library design; nó đánh dấu boundary nơi con người phải thiết lập những invariant mà compiler không kiểm tra trực tiếp.

Nếu chỉ quy vấn đề cho một developer rồi kết thúc bằng “vì vậy không liên quan đến Rust design”, các câu hỏi system-level về reviewability, abstraction boundary, synchronization contract và regression test vẫn còn. Ngược lại, khái quát từ một CVE rằng “Rust kernel code cũng unsafe như C” đòi hỏi matched workload và defect denominator. Cả hai hướng đều vượt quá điều case trực tiếp chứng minh.

8.4.6 “Không có lựa chọn nào ngoài Rust”: bỏ sót tập ứng viên và yêu cầu

Phần sau không phải trích dẫn trực tiếp của một cá nhân cụ thể mà là một mệnh đề tổng hợp cô đọng cấu trúc có thể xuất hiện trong thảo luận kỹ thuật công khai:

Ví dụ tổng hợp: “Trong một project thực tế nơi không thể tự do chọn deployment environment, không thể dùng C++. Vì vậy không có lựa chọn nào ngoài Rust.”

Tiền đề đầu có thể đủ để loại C++ trong một project cụ thể. Nhưng loại một ứng viên không có nghĩa mọi ứng viên khác cũng đã bị loại. Để chứng minh “lựa chọn duy nhất”, tối thiểu phải nêu workload, yêu cầu latency·memory·real-time, việc GC/VM có được phép hay không, điều kiện binary·deployment, certification, ABI/library hiện có, support platform, staffing và lifecycle, rồi áp dụng cùng tiêu chí cho một tập ứng viên thực tế.

Backend hay business system cho phép managed runtime, low-level software cần native executable không GC, và safety system yêu cầu run-time check mạnh hoặc formal proof có các tập ứng viên khác nhau. Với system có nhiều C/C++ asset hiện hữu, same-language modernization, selective Rust replacement ở high-risk module và mixed-language architecture cũng là ứng viên. Vì vậy “project thực tế” không phải yêu cầu mà là một phạm trù tu từ có thể che khuất các domain khác nhau.

Mệnh đề chính xác hơn phải có điều kiện. Nếu một project đồng thời cần native execution không GC, static memory safety mạnh, target-platform support và năng lực bảo trì dài hạn của tổ chức, đồng thời không ứng viên thực tế nào khác đáp ứng các điều kiện đó, Rust có thể là lựa chọn mạnh nhất. Nhưng trước khi chứng minh phép so sánh này, phải phân biệt ứng viên mạnh với lựa chọn duy nhất.

8.4.7 Quy trình chung để đánh giá phản hồi

Thay vì gom các trường hợp trên thành một “mẫu phòng vệ Rust” rồi suy đoán prevalence, có thể đánh giá từng phản hồi theo thứ tự có tính tái lập hơn dưới đây.

Bước Câu hỏi Ví dụ phán định
1. Cố định mệnh đề ban đầu Thực tế đã khẳng định điều gì? Tách source share, memory-safety contract, overall security, operational severity, migration suitability, v.v.
2. Xác định mệnh đề phản hồi Phản hồi có xử lý cùng mệnh đề không? Phân biệt scope correction, nêu một ưu điểm khác, và đánh giá người phát biểu
3. Xác định đơn vị bằng chứng Đó là artifact, official advisory, benchmark, case hay opinion? Tách measurement khỏi interpretation, official fact khỏi value judgment của người tham gia
4. Kiểm tra tính đối xứng của tiêu chí Hai phía có dùng cùng denominator và tiêu chuẩn không? Phát hiện bất đối xứng như đòi total security ở C/C++ nhưng chỉ đánh giá Rust theo memory safety
5. Ghi lại mệnh đề còn bỏ ngỏ Sau phản hồi còn gì chưa được trả lời? Operational impact, causal attribution, external validity, maintenance cost, v.v.

Trong mục này, các nhãn như red herring, ad hominem và genetic fallacy là nhãn tóm tắt sau khi phân tích, không phải giả định xuất phát. Có những lĩnh vực chuyên môn mà mức hiểu biết của người phát biểu thực sự liên quan đến evidence quality, và deployment ở một công ty khác cũng có thể là phản ví dụ trực tiếp cho một mệnh đề phổ quát ban đầu. Tuyên bố một ngụy biện chỉ từ một cụm từ tách khỏi ngữ cảnh sẽ lặp lại chính sự khái quát quá mức mà cuốn sách này phê bình.

Kết luận tạm thời

Đối với RQ5, điều quan trọng không phải phản ứng với phê bình mạnh hay yếu mà là phạm vi lập luận thay đổi như thế nào. 0,375% của Linux là source composition; memory leak là operational risk khác với memory-safety UB; tranh luận rav1d/dav1d cần tách safety scope, performance attribution và fork maintenance; còn các CVE Command và Binder lần lượt cho thấy ranh giới của logical security contract và unsafe proof obligation.

Các trường hợp này không phủ nhận ưu điểm của Rust, cũng không chứng minh cộng đồng Rust nói chung có tính phòng vệ. Ngược lại, việc xuất hiện những câu như “memory-safe theo định nghĩa”, “các công ty lớn cũng dùng”, hay “đó là lỗi developer” cũng không tự động làm phê bình ban đầu sai. Cần phân rã xem phản hồi thực sự bác bỏ phần nào của mệnh đề ban đầu và chuyển phần nào sang một tầng khác.

Mục 8.5 tiếp theo xem xét riêng những trường hợp sự dịch chuyển này vượt ra ngoài bản thân công nghệ và trở thành phán xét về tư cách, tính bình thường hoặc trí tuệ của người phát biểu.

8.5 Địa vị hóa lựa chọn công nghệ: tư cách, tính bình thường, thứ bậc trí tuệ và loại trừ diễn ngôn

Trong thảo luận kỹ thuật, kinh nghiệm và chuyên môn của người phát biểu có thể liên quan đến việc xác định phạm vi mà bằng chứng thực sự hỗ trợ. Đánh giá một ngôn ngữ mạnh hơn trong điều kiện nào và một người có đủ năng lực sử dụng ngôn ngữ đó trong thực tế hay không cũng là phán đoán kỹ thuật chính đáng. Tuy nhiên, khi ưu điểm của công nghệ được chuyển thành sự ưu việt chung của người lựa chọn nó và được dùng làm căn cứ hạ thấp trí thông minh, tư cách hoặc tính bình thường của người không sử dụng, cuộc thảo luận chuyển từ đánh giá kỹ thuật sang phán định địa vị của con người và nhóm.

Cuốn sách này gọi sự chuyển dịch đó là địa vị hóa lựa chọn công nghệ. Đây không phải tên của một khái niệm tâm lý học hay ngụy biện hình thức duy nhất được đồng thuận rộng rãi, mà là một phạm trù mô tả để phân rã chuỗi chuyển đổi sau có thể xuất hiện trong diễn ngôn kỹ thuật. Hiện cuốn sách không có corpus được xác định trước để ước lượng tần suất hay tính đại diện của chuỗi này, vì vậy các bước dưới đây là khung phân loại lập luận, không phải mô hình trình tự thực nghiệm của toàn cộng đồng.

  1. Ưu điểm có điều kiện của một công nghệ được mở rộng thành tính ưu việt phổ quát.
  2. Việc hiểu hoặc lựa chọn công nghệ đó được dùng như dấu hiệu cho sự ưu việt trí tuệ hoặc nghề nghiệp của người dùng.
  3. Người không sử dụng không còn được xem đơn giản là người đưa ra lựa chọn khác trong điều kiện khác, mà bị phân loại thành nhóm ngoài thiếu hiểu biết hoặc lạc hậu.
  4. Phản luận kỹ thuật được giải thích bằng sự thấp kém, sợ hãi, chi phí chìm hoặc thiếu hiểu biết của người phát biểu, thay vì bằng nội dung của phản luận.
  5. Khi cả sự phản đối và khó chịu cũng bị hấp thụ thành bằng chứng xác nhận phân loại địa vị sẵn có, lập luận mang cấu trúc tự đóng kín.

Mục này không suy đoán tính cách, trạng thái tinh thần hay đặc điểm lâm sàng của một cá nhân cụ thể. Đối tượng phân tích là các tiêu chí phân loại, gánh nặng chứng minh và cấu trúc lập luận có thể nhận diện trong phát ngôn công khai. Những câu trình bày theo dạng trích dẫn không phải lời nguyên văn của một cá nhân cụ thể mà là ví dụ tổng hợp (composite example) được tái dựng để làm rõ bước chuyển logic. Vì vậy, ví dụ tổng hợp không phải bằng chứng về tần suất thực tế, tính đại diện hay thái độ của toàn bộ người dùng Rust. Khi dùng một trường hợp công khai thực tế, ranh giới sampling của Mục 8.1 vẫn được áp dụng.58

1. Phân biệt xem xét chuyên môn với loại trừ người phát biểu

Chỉ ra sự thiếu chuyên môn không phải lúc nào cũng là gác cổng. Với những vấn đề đòi hỏi kiến thức chuyên sâu—chẳng hạn tính đúng đắn của một đoạn unsafe cụ thể, triển khai trình biên dịch hay giao diện kernel hệ điều hành—việc kiểm tra kinh nghiệm liên quan và chất lượng bằng chứng là chính đáng. Tuy vậy, việc xem xét chuyên môn có thể biến thành công cụ loại trừ người phát biểu thay vì đánh giá luận điểm trong các trường hợp sau:

  • bác bỏ một tuyên bố chỉ dựa vào tổ chức, ngôn ngữ quen dùng hay chức danh của người nói, dù các yếu tố đó không liên quan nội dung phê bình;
  • kết luận người nói không đủ tư cách mà không xem xét dữ liệu hoặc kết quả có thể tái hiện;
  • chỉ sau khi phản ví dụ xuất hiện mới đặt ra tiêu chuẩn mới về “lập trình viên thực thụ” hay “lập trình hệ thống thực thụ”;
  • áp dụng tiêu chuẩn chuyên môn khác nhau cho bên ủng hộ và bên phê bình dù chất lượng bằng chứng tương đương.

Ví dụ tổng hợp: “Dự án của anh không tự triển khai event loop hay scheduler, nên đó không phải lập trình hệ thống thực thụ. Vì vậy kinh nghiệm của anh về hệ sinh thái và năng suất không có giá trị đánh giá.”

Phản ứng này loại bỏ sức nặng của lời phê bình bằng cách đẩy công việc của người phát biểu ra ngoài phạm vi liên quan mà không giải thích trước loại kinh nghiệm nào thực sự cần thiết để đánh giá vấn đề. Tuy nhiên, không phải mọi sự phân định phạm vi đều là ngụy biện Không phải người Scotland thực thụ (No True Scotsman Fallacy). Thông thường, ngụy biện này đòi hỏi trước hết có một khái quát về một nhóm, sau đó xuất hiện phản ví dụ trái với khái quát đó, rồi định nghĩa của nhóm bị thu hẹp tùy tiện để loại phản ví dụ.126 Nếu không xác định được khái quát ban đầu và sự tái định nghĩa về sau, phát biểu vẫn có thể bị phê bình là gác cổng hoặc giới hạn phạm vi không chính đáng, nhưng không nên tự động gắn nhãn ngụy biện Không phải người Scotland thực thụ.

2. Kết hợp tính ưu việt kỹ thuật với địa vị người dùng

Phán đoán rằng một ngôn ngữ an toàn hơn hoặc có năng suất cao hơn các lựa chọn khác trong điều kiện nhất định không bao hàm trí thông minh chung hay giá trị con người của người dùng. Mệnh đề về công nghệ và mệnh đề về người đã chọn công nghệ đó đòi hỏi các bằng chứng khác nhau. Ví dụ tổng hợp sau kiểm tra bước chuyển từ ưu thế kỹ thuật có điều kiện → ưu thế chung của người dùng.

Ví dụ tổng hợp: “Lập trình viên có khả năng hiểu các nguyên lý nền tảng của ngôn ngữ này cuối cùng sẽ chọn nó. Người cố chấp với lựa chọn khác có trình độ tư duy thấp hơn hoặc bị mắc kẹt trong sự nghiệp quá khứ.”

Trong cấu trúc này, tính ưu việt của công nghệ và sự ưu việt của người dùng bảo chứng cho nhau theo vòng tròn. Một người được phân loại là ưu việt vì đã chọn công nghệ ưu việt, còn công nghệ được xem là ưu việt vì những người ưu việt lựa chọn nó. Tuy nhiên, lựa chọn ngôn ngữ có thể thay đổi theo yêu cầu, mã hiện có, nhân lực, công cụ, chứng nhận, môi trường triển khai, ràng buộc thời gian thực, chi phí chuyển đổi và mức chấp nhận rủi ro của tổ chức. Các lập trình viên hiểu cùng một sự kiện vẫn có thể đi đến kết luận khác nhau trong những điều kiện khác nhau.

Khi công nghệ bắt đầu hoạt động như dấu hiệu địa vị của người dùng, ý nghĩa của phê bình kỹ thuật cũng thay đổi. Phê bình hiệu năng, bảo đảm an toàn hoặc hệ sinh thái của một ngôn ngữ có thể bị diễn giải không phải là xem xét phạm vi của một tuyên bố cụ thể, mà là phủ nhận sự sáng suốt, tính tiên phong hoặc giá trị nghề nghiệp của người dùng và nhóm trong đã chọn ngôn ngữ đó. Với cách diễn giải đó, phản hồi có thể chuyển từ việc trả lời phản luận kỹ thuật sang đánh giá tư cách hoặc tâm lý của người phê bình. Dữ liệu hiện có không ước lượng tần suất của bước chuyển này và cũng không chứng minh nó đang tăng trong diễn ngôn Rust.

Phân tích này không coi bản thân sự ưa thích kỹ thuật mạnh mẽ hay cảm giác thuộc về cộng đồng là vấn đề. Nếu công nghệ được khuyến nghị mạnh nhưng vẫn nêu rõ điều kiện áp dụng và phản ví dụ, đồng thời năng lực và giá trị của người không sử dụng được đánh giá riêng, thì tuyên bố kỹ thuật và địa vị người dùng vẫn tách biệt. Vấn đề phát sinh khi một lựa chọn công nghệ được dùng như chỉ báo thay thế để xếp hạng toàn bộ con người.

3. Quy định tính bình thường và cấu thành nhóm trong–nhóm ngoài

Cuốn sách này dùng cụm quy định tính bình thường (defining normality) như một phạm trù mô tả cho kiểu tu từ biến thực hành của một hệ sinh thái thành chuẩn mực phổ quát mà không có căn cứ độc lập. Đây không phải tên của một ngụy biện hình thức duy nhất đã được đồng thuận rộng rãi.

Các từ “bình thường”, “tiêu chuẩn” hay “phổ biến” tự thân không sai. Chúng có thể là mô tả kỹ thuật hữu ích nếu phạm vi được giới hạn bằng tiêu chuẩn quốc tế, quy tắc tổ chức được công bố, thị phần, yêu cầu tương thích hoặc tần suất sử dụng đã đo lường. Vấn đề nảy sinh khi tiêu chí và quần thể đánh giá không được nêu rõ, còn cách làm quen thuộc với người phát biểu lại được trình bày như mặc định mà mọi ngôn ngữ và tổ chức đều phải tuân theo.

Ví dụ tổng hợp: “Một ngôn ngữ bình thường phải cung cấp công cụ build, quản lý gói, phân tích mã và hỗ trợ trình soạn thảo theo một cách duy nhất đã định sẵn. Lập trình viên không thể chấp nhận tiêu chuẩn mới đã thuộc về một thế hệ lạc hậu.”

Ví dụ này kết hợp tính bình thường của cấu hình kỹ thuật với tính bình thường của người dùng trong cùng một phát biểu. Câu đầu đưa ra tiêu chí về cấu hình công cụ, còn câu sau phân loại những người không tuân theo tiêu chí đó thành nhóm ngoài lạc hậu. Khi ấy, các từ như “bình thường”, “hiện đại”, “thực thụ” và “có trách nhiệm” không chỉ mô tả thuộc tính kỹ thuật mà còn quy định tư cách của nhóm trong và khuyết điểm của nhóm ngoài.

Môi trường phát triển thực tế đồng thời có mô hình xoay quanh IDE tích hợp, language server độc lập, công cụ dòng lệnh và nền tảng nội bộ của tổ chức. Mỗi mô hình có chi phí khác nhau về mức dễ cài đặt, khả năng tự động hóa, khả năng thay thế, vận hành ngoại tuyến, hỗ trợ dài hạn và quyền kiểm soát của tổ chức. Vì vậy, cần so sánh lựa chọn nào phù hợp với người dùng và điều kiện vận hành nào, thay vì tuyên bố một cấu hình hay ngôn ngữ cụ thể chứng minh phổ quát rằng người dùng của nó hiện đại hoặc bình thường.

4. Phân biệt mức thành thạo ngôn ngữ, hiệu quả nhận thức và hiệu suất công việc

Ví dụ tổng hợp sau xem xét một mệnh đề liên kết trực tiếp khả năng hoặc lựa chọn học một ngôn ngữ cụ thể với trí thông minh chung và tư cách nghề nghiệp của lập trình viên.

Ví dụ tổng hợp: “Người không đủ thông minh để học Rust, hoặc không chịu học Rust, cuối cùng cũng không đủ tư cách làm lập trình viên chuyên nghiệp.”

Tuyên bố này gộp bốn vấn đề khác nhau thành một.

  1. Học tập và chuyển giao sang nhiệm vụ nhận thức: Giáo dục lập trình bao gồm việc học khái niệm, công cụ của ngôn ngữ và một số chiến lược giải quyết vấn đề. Một phân tích gộp 105 nghiên cứu với 539 kích thước hiệu ứng báo cáo hiệu ứng chuyển giao tổng thể ở mức vừa (g = 0.49) và hiệu ứng chuyển giao xa ở mức vừa (g = 0.47) từ việc học lập trình. Kết quả này ủng hộ khả năng giáo dục lập trình tác động tích cực đến một số nhiệm vụ nhận thức.127
  2. Trí thông minh chung và thứ bậc con người: Thành tích tốt hơn ở một nhiệm vụ cụ thể hoặc hiệu ứng chuyển giao học tập tự nó không chứng minh sự gia tăng toàn diện của trí thông minh chung theo đo lường tâm lý, cũng không thiết lập thứ bậc con người hay nghề nghiệp giữa người học và người không học. Những kết luận mạnh hơn cần phép đo và thiết kế nghiên cứu riêng.
  3. Hiệu quả riêng của Rust và hiệu ứng lựa chọn: Phân tích gộp trên tổng hợp nhiều ngôn ngữ lập trình và môi trường giáo dục, không kiểm chứng hiệu quả nhận thức riêng của Rust. Tương tự, dù nhóm tự nguyện chọn Rust có kiến thức trước hoặc mức quan tâm kỹ thuật cao hơn, cần kiểm soát cơ hội giáo dục, kinh nghiệm công việc và tự lựa chọn trước khi kết luận việc học ngôn ngữ gây ra khác biệt.
  4. Liên quan công việc: Khi viết và bảo trì mã Rust là nhiệm vụ cốt lõi, mức thành thạo Rust hoặc khả năng học Rust có thể là tiêu chí tuyển chọn trực tiếp. Với các vai trò ở ngôn ngữ, miền hay chức năng khác, cần đánh giá riêng các năng lực thực tế như thiết kế, gỡ lỗi, kiểm thử, vận hành, bảo mật, cộng tác và kiến thức miền. Như một ví dụ phương pháp luận, Uniform Guidelines on Employee Selection Procedures của Hoa Kỳ gắn tính hợp lệ của tiêu chí tuyển chọn với những nhiệm vụ quan trọng của công việc cùng kiến thức, kỹ năng và năng lực cần thiết, thay vì giả định tính hợp lệ chỉ từ danh tiếng hay giai thoại.128

Vì vậy, thành thạo Rust có thể là bằng chứng cho một số năng lực liên quan đến Rust, nhưng tự nó không đại diện cho hiệu suất trong mọi công việc phát triển phần mềm hoặc trí thông minh chung. Ngược lại, chưa học Rust hoặc gặp khó khăn khi học cũng không tự động phủ nhận tiềm năng làm lập trình viên của một người.

5. Tâm lý hóa phản luận kỹ thuật và suy đoán động cơ

Những giải thích tâm lý và xã hội như bất hòa nhận thức, bản sắc xã hội và chi phí chìm có thể đóng vai trò giả thuyết cạnh tranh khi diễn giải lựa chọn công nghệ. Tuy nhiên, như Mục 8.1 đã phân biệt, sự tồn tại của lý thuyết chung không chứng minh động cơ của một người phát biểu Rust cụ thể hay một cơ chế ở cấp cộng đồng.119 Muốn nói rằng đầu tư vào giáo dục, mã nguồn, sự nghiệp hoặc sự bất định về công nghệ mới đã ảnh hưởng đến một quyết định cụ thể, cần dữ liệu riêng về con người và tình huống đó. Suy đoán động cơ tự nó cũng không bác bỏ nội dung phản luận.

Ví dụ tổng hợp: “Họ không thể thừa nhận giới hạn của ngôn ngữ cũ vì sợ rằng sự nghiệp và mã nguồn đã đầu tư sẽ trở nên vô giá trị. Họ đưa ra lý do kỹ thuật, nhưng động cơ thật sự là chống đối để bảo vệ địa vị của mình.”

Phản ứng này thay thế các vấn đề về hiệu năng, năng suất, hệ sinh thái, chứng nhận, tuyển dụng và tích hợp với hệ thống hiện có bằng động cơ bị suy đoán của người phát biểu. Ngay cả khi chi phí chìm hoặc sự phòng vệ địa vị tồn tại một phần, điều đó không làm cho tuyên bố kỹ thuật rằng hệ thống hiện có nên được duy trì hoặc chuyển đổi từng bước trở thành sai. Sự tồn tại của động cơ và tính đúng sai của tuyên bố phải được đánh giá riêng.

Suy đoán động cơ cũng phải được áp dụng đối xứng. Nếu không thể bác bỏ lập luận của người phê bình chỉ vì họ đã đầu tư vào công nghệ hiện hữu, thì cũng không thể bác bỏ lập luận của người ủng hộ chỉ vì họ đã đầu tư vào việc học ngôn ngữ mới, dự án, danh tiếng hoặc bản sắc nhóm. Trong cả hai trường hợp, cần xem xét trước mã nguồn, kết quả đo, chi phí, rủi ro và phạm vi áp dụng.

6. Phổ quát hóa công nghệ ưa thích và sự xác nhận lặp lại

Khi lựa chọn công nghệ gắn với địa vị người dùng, ưu điểm thực tế của công nghệ có thể bị mở rộng vượt quá phạm vi ban đầu. Điểm mạnh về an toàn bộ nhớ có thể chuyển thành kết luận rằng công nghệ đó phải là ngôn ngữ mặc định cho mọi phần mềm; thành công của một dịch vụ hoặc thành phần mới có thể chuyển thành kết luận rằng mọi hệ thống hiện có phải được viết lại. Khi ấy, công nghệ được ưa thích không còn được đối xử như một công cụ kỹ thuật trong nhiều công cụ, mà như đáp án mặc định được áp dụng lặp lại cho nhiều vấn đề khác nhau.

Ví dụ tổng hợp: “Các vấn đề về bảo mật, hiệu năng, năng suất, khả năng bảo trì và trình độ lập trình viên cuối cùng đều có cùng nguyên nhân. Đặt ngôn ngữ này làm mặc định có thể đồng thời thay thế công nghệ lỗi thời và cách tư duy lỗi thời.”

Các vấn đề khác nhau đòi hỏi tiêu chuẩn so sánh và bằng chứng khác nhau. An toàn bộ nhớ, thông lượng, độ trễ, khả năng chứng nhận, năng suất phát triển, nhân lực và tích hợp hệ thống kế thừa không thể quy về một chỉ số duy nhất. Chuyển kết quả mạnh ở một lĩnh vực thành tuyên bố ưu việt ở lĩnh vực khác cần thêm bằng chứng. Phạm vi áp dụng của trường hợp công nghiệp và tài liệu chính sách được xem xét riêng trong mục 8.7.

Nếu giả định cùng một tuyên bố và phân loại địa vị được xác nhận lặp lại trong một không gian nào đó, ta có thể phân tích khả năng sự lặp lại bị tiếp nhận như bằng chứng cho chính tuyên bố. Tuy nhiên, cuốn sách này chưa đo network homophily, exposure hay mức độ echo chamber trong các không gian liên quan đến Rust.119 Vì vậy, chúng tôi không giả định quy mô đồng thuận nội bộ thực tế hay tần suất lặp lại; chỉ áp dụng quy tắc rằng sự đồng ý quan sát được phải được phân biệt với kiểm chứng kỹ thuật độc lập.

7. Lập luận tự đóng kín

Trong cuốn sách này, lập luận tự đóng kín (self-sealing argument) là cấu trúc hấp thụ cả bằng chứng trái ngược và phản ứng của người khác thành bằng chứng tiếp tục ủng hộ kết luận sẵn có, khiến không quan sát nào có thể làm kết luận yếu đi. Thuật ngữ được dùng ở đây theo nghĩa mô tả để phân tích; nó không có nghĩa mọi suy đoán về động cơ tâm lý tự động đều mang cùng cấu trúc.

Ví dụ tổng hợp: “Lập trình viên có trí thông minh bình thường sẽ công nhận tính ưu việt và giá trị học Rust. Người phản đối thiếu khả năng hiểu, còn việc khó chịu trước đánh giá này chứng minh họ biết sự thấp kém của chính mình.”

Lập luận này có cấu trúc đóng như sau.

  1. Tiền giả định kết luận: Tính ưu việt phổ quát của Rust và tính bình thường của người ủng hộ được coi là tiền đề phân loại, thay vì kết luận cần kiểm chứng. Đồng ý trở thành bằng chứng bình thường, còn phản đối thành bằng chứng thấp kém.
  2. Bảo chứng vòng tròn giữa công nghệ và địa vị người dùng: Một người được cho là chọn Rust vì họ ưu việt, đồng thời được cho là ưu việt vì đã chọn Rust. Không vế nào được kiểm chứng bằng phép đo độc lập.
  3. Tâm lý hóa phản luận kỹ thuật: Phản luận về hiệu năng, năng suất, hệ sinh thái, chứng nhận, tuyển dụng hoặc tích hợp hệ thống hiện có bị thay bằng động cơ suy đoán như tự ti, sợ hãi, chi phí chìm hay chống đối.
  4. Loại bỏ khả năng bác bỏ: Nếu phản đối, khó chịu, thờ ơ và cố gắng giải thích đều được diễn giải thành bằng chứng cho cùng một kết luận, không quan sát nào có thể khiến tuyên bố được sửa đổi.
  5. Gánh nặng chứng minh bất đối xứng: Người phê bình bị buộc phải công nhận mọi ưu điểm của ngôn ngữ và vượt qua rào cản học tập, trong khi bên tuyên bố ưu việt không phải đưa ra dữ liệu so sánh, phạm vi áp dụng hay điều kiện thất bại.
  6. Nhầm phán đoán kỹ thuật có điều kiện với thứ bậc con người: Rust có thể là lựa chọn mạnh ở nơi an toàn bộ nhớ và hiệu năng đồng thời quan trọng, và trong các điều kiện đó chi phí học tập có thể xứng đáng. Nhưng điều này không suy ra mọi lập trình viên phải chọn cùng một công nghệ, hoặc lựa chọn khác chứng minh trí thông minh thấp hơn.

8. Tiêu chí xem xét tuyên bố địa vị hóa

Khi đánh giá tuyên bố về tư cách, tính bình thường hoặc địa vị người dùng trong thảo luận kỹ thuật, cần tách biệt các câu hỏi sau:

  • Chuyên môn nào thực sự cần thiết để xác định luận điểm đúng hay sai?
  • Tiêu chuẩn chuyên môn đó có được nêu trước khi phản luận xuất hiện không?
  • Mã nguồn, dữ liệu, kết quả đo và quy trình tái hiện có được xem xét độc lập với lý lịch người phát biểu không?
  • Bằng chứng về ưu điểm của công nghệ có thực sự đo cả trí thông minh chung hoặc sự ưu việt nghề nghiệp của người dùng không?
  • Lựa chọn của người không sử dụng có bị giải thích chỉ bằng sự thiếu hiểu biết, thấp kém, sợ hãi hoặc chi phí chìm, thay vì yêu cầu và chi phí không?
  • Bên ủng hộ và bên phê bình có chịu cùng tiêu chuẩn về bằng chứng, chuyên môn và suy đoán động cơ không?
  • Có bằng chứng bổ sung để mở rộng thành công trong một lĩnh vực sang các vấn đề khác và mọi hệ thống hiện có không?
  • Sự đồng ý lặp lại trong nhóm trong có được phân biệt với kiểm chứng kỹ thuật độc lập không?
  • Phản ví dụ hoặc kết quả nào sẽ khiến phán đoán hiện tại được sửa đổi?
  • Nếu đánh giá mức thành thạo ngôn ngữ, nó liên hệ thế nào với các nhiệm vụ quan trọng của công việc cụ thể?

Tóm lại, chuyên môn, tiêu chuẩn, mức thành thạo ngôn ngữ và khuyến nghị kỹ thuật đều có thể là yếu tố đánh giá chính đáng, nhưng phạm vi áp dụng và bằng chứng phải được nêu rõ. Diễn ngôn chuyển ưu điểm của một ngôn ngữ thành sự ưu việt chung của người dùng, phân loại người không sử dụng thành nhóm ngoài thấp kém và chỉ giải thích ý kiến phản đối bằng khuyết điểm của người phát biểu sẽ quyết định địa vị con người trước khi xem xét sự kiện kỹ thuật và mức liên quan công việc.

Công nghệ không phải là dấu hiệu thay thế để đo trí thông minh hay giá trị con người của người dùng. Công nhận kết quả kỹ thuật mạnh mẽ hoàn toàn tương thích với việc không mở rộng kết quả đó thành mọi vấn đề, mọi tổ chức và thứ bậc của mọi lập trình viên. Mục đích tách riêng hiện tượng địa vị hóa lựa chọn công nghệ không phải để hạ thấp một cộng đồng cụ thể, mà để đưa phán đoán kỹ thuật có điều kiện trở lại thành những tuyên bố có thể kiểm chứng.

8.6 Tranh luận chính sách nhãn hiệu năm 2023 và quản trị

Tranh luận về chính sách nhãn hiệu Rust năm 2023 không thể được tóm tắt chính xác chỉ bằng câu “Foundation đơn phương áp đặt chính sách rồi rút lại vì cộng đồng phản đối.” Theo trình tự trong các nguồn chính thức, soạn draft, consultation công khai, feedback và phê bình quy trình, revision kéo dài, và approval cuối cùng là những giai đoạn khác nhau. Mục này không coi khối lượng phản ứng công khai là kết quả bỏ phiếu đại diện cho toàn cộng đồng, mà xem xét tổ chức nào chịu trách nhiệm gì ở từng giai đoạn và chính các tổ chức liên quan đã thừa nhận điều gì.

8.6.1 Tài liệu năm 2023 là consultation draft, không phải policy đã được áp dụng

Rust Foundation bắt đầu review và survey chính sách nhãn hiệu từ năm 2022, rồi ngày 6 tháng 4 năm 2023 công bố draft Rust Trademark Policy cập nhật cùng feedback form công khai. Theo giải thích của Foundation ngày 17 tháng 4, cả draft lẫn consultation mười ngày đều được xây dựng với sự hợp tác của Rust Foundation, Rust Project Directors, Trademark Working Group và legal counsel có kinh nghiệm về chính sách open source. Vì vậy, mô tả draft như một văn bản do Foundation staff tự viết rồi đơn phương áp đặt lên Rust Project không phù hợp với hồ sơ chính thức.129

Đồng thời, những người tham gia cũng tự thừa nhận vấn đề trong quy trình. Ngày 12 tháng 4, Project Directors và các bên tham gia khác nói rằng wider Rust Project chưa được đưa vào đầy đủ và process cùng communication đáng lẽ phải tốt hơn. Sau khi consultation kết thúc, Foundation cũng xin lỗi vì thiếu minh bạch và nói initial draft có nhiều phê bình hợp lệ cần được xử lý.129 Do đó, cả “Foundation đơn phương cưỡng ép” lẫn “quy trình không có vấn đề gì” đều mạnh hơn bằng chứng.

Các nguồn chính thức cũng xác nhận draft tháng 4 năm 2023 nhận được nhiều phê bình công khai và phản hồi qua feedback form. Tuy nhiên, người trả lời không phải mẫu ngẫu nhiên; feedback form là kênh consultation tự nguyện của những người quan tâm đến policy. Vì vậy không thể dùng nó để khẳng định “đa số người dùng Rust phản đối” hay ước lượng tỷ lệ phản đối. Feedback summary mà Foundation công bố năm 2024 chỉ hỗ trợ kết luận hẹp hơn: trong các phản hồi gửi vào, những lo ngại lặp lại gồm hậu quả của misuse ngoài ý muốn, thuật ngữ pháp lý và độ rõ ràng, cùng phạm vi đối với blog, talk, crate name, merchandise và logo modification.130

8.6.2 Không phải “rút lại”, mà là revision kéo dài rồi approval cuối cùng

Sau khi consultation năm 2023 kết thúc, Foundation không thông báo draft sẽ có hiệu lực. Thay vào đó, họ nói feedback sẽ được xem xét chung, một draft mới sẽ được chuẩn bị, và không policy nào được áp dụng trước khi cả Foundation lẫn Rust Project leadership đều hài lòng.129 Công việc này không kết thúc nhanh. Năm 2023 Rust Leadership Council đưa việc cải thiện interaction với Foundation và làm rõ vai trò Project Directors thành ưu tiên; board minutes của Foundation tháng 6 năm 2024 ghi rằng trademark work bị chậm do availability của legal counsel.131

Tháng 11 năm 2024, Leadership Council và Foundation lại công bố revised draft để nhận final feedback. Theo Foundation, các thay đổi dựa trên phản hồi năm 2023 gồm bỏ package-name restriction, đồng thời làm các quy tắc về đổi màu logo và một số merchandise, event, publication phi thương mại trở nên permissive hoặc rõ ràng hơn.130 Phiên bản này vẫn là draft cho final feedback, chưa phải policy cuối cùng đã áp dụng.

Ngày 23 tháng 1 năm 2025, Rust Foundation thông báo Foundation Board, bao gồm Project Directors, đã approve policy cập nhật. Rust Language Trademark Policy hiện tại nói Foundation sở hữu và bảo vệ trademarks/logos Rust và Cargo, đồng thời tách riêng Rust programming-language project là project được govern bởi Leadership Council. Policy hiện tại cho phép nhiều cách sử dụng không cần approval trước, như mô tả chính xác compatibility với Rust, dùng Rust trong tên crate/repository, event phi lợi nhuận nhỏ, book, blog và publication; trong khi các cách dùng hàm ý official affiliation cùng một số commercial hoặc modified distribution cần permission.132

8.6.3 Không đồng nhất Foundation governance với Rust Project governance

Tài liệu governance hiện tại của Rust xác định Leadership Council là top-level body chịu trách nhiệm về thành công và điều phối tổ chức của toàn Rust Project, còn major technical decision được thực hiện qua RFC deliberation và các Project team liên quan. Rust Foundation, ngược lại, là nonprofit độc lập đảm nhận stewardship như trademark, công việc pháp lý và hành chính, tài chính và infrastructure support. Project Directors là kênh để Rust Project được đại diện trên Foundation Board và, theo mô tả hiện tại, là elected group chịu trách nhiệm cho mối quan hệ giữa Project và Foundation.131

Vì vậy, nếu gom language feature decision, moderation và legal responsibility của Foundation trong tranh luận trademark vào một trục quyền lực duy nhất, ta sẽ đọc sai cấu trúc tổ chức.

Vấn đề Đơn vị thể chế chính Phạm vi trường hợp này trực tiếp cho thấy
Sở hữu/bảo vệ trademark Rust/Cargo và permission sử dụng Rust Foundation và Foundation Board Legal trademark stewardship và final policy approval
Hướng tổ chức Rust Project và cross-team coordination Leadership Council Project-level governance và điều phối Foundation relationship
Technical decision về language, compiler, library, v.v. Các Rust Project team liên quan và RFC process Technical trade-off và consensus procedure; tách khỏi trademark policy
Đại diện Project interests trên Foundation Board Project Directors Kênh thể chế nối Project perspective với Foundation-related decision
Thực thi chuẩn hành vi và hòa giải xung đột Rust Project Moderation team Miền Code of Conduct và community standard; tách khỏi trademark ownership

8.6.4 Tranh luận này có thể được dùng làm governance evidence đến đâu

Điều trường hợp này hỗ trợ mạnh là chính các tổ chức liên quan đã thừa nhận rằng không chỉ nội dung policy mà cả policy-making process cũng có thể ảnh hưởng đến trust và acceptability, rồi thay đổi process để đáp lại. Năm 2023, phía Project và Foundation thừa nhận thiếu sót về communication và wider-project inclusion; sau đó Leadership Council coi việc làm rõ Foundation interaction và Project Director role là ưu tiên. Revision năm 2024 phản ánh những concern cụ thể trong public feedback, và policy cuối cùng năm 2025 đi qua Board approval.129130132

Những kết luận mạnh hơn cần thêm ranh giới. Khối lượng feedback không đo được trust level hay opposition rate của toàn bộ Rust users. Sự tồn tại của thảo luận protest fork như Crab-lang cũng không tự nó ước lượng xác suất ecosystem fragmentation thực tế. Việc thừa nhận vấn đề quy trình cũng không chứng minh một psychological hay political motive rằng Foundation hoặc Project participant cố ý mở rộng community control.

Ngược lại, việc final policy được approve năm 2025 cũng không khiến criticism năm 2023 trở nên vô căn cứ. Trong revision thực tế, nhiều vấn đề như crate/package naming, logo modification, publication, merchandise và non-endorsement đã được thay đổi hoặc làm rõ.130 Tính hợp lệ của phê bình draft, mức cải thiện của revision process, và tính phù hợp của current policy là những đối tượng đánh giá khác nhau.

Kết luận tạm thời

Từ góc nhìn RQ5, trademark controversy năm 2023 không phải trường hợp để chẩn đoán tính cách Rust community mà là trường hợp để phân biệt institutional authority, public consultation, phạm vi criticism và policy revision. Initial draft không phải final policy đã được áp dụng và cũng không phải sản phẩm riêng của Foundation, nhưng việc thiếu wider Project involvement và communication đã được chính thức thừa nhận. Quá trình sau đó đi qua revised draft và final feedback năm 2024, rồi Foundation Board approval năm 2025; current policy quy định một số lĩnh vực từng gây tranh luận theo cách khác hoặc rõ ràng hơn.

Bài học rộng hơn cũng phải có điều kiện. Cần phân biệt Foundation nắm legal assets, Project govern technical work, Project Directors nối Project với Foundation Board, cùng moderation và technical teams, đồng thời tách draft·feedback·adoption theo thời gian. Nhờ vậy, ta tránh cả việc biến một tranh luận công khai thành power narrative đơn giản “Foundation đối đầu community” lẫn việc xóa bỏ những vấn đề quy trình ban đầu chỉ vì về sau đạt được agreement.

8.7 Phạm vi trích dẫn khuyến nghị của chính phủ và trường hợp thành công công nghiệp

Guidance của chính phủ và case công nghiệp có thể là bằng chứng mạnh, nhưng chúng hỗ trợ các loại mệnh đề khác nhau. Cần giảm memory-safety vulnerability, memory-safe language là một phương tiện quan trọng, Rust là một trong các ngôn ngữ đó, Rust phù hợp nhất cho một project cụ thể, và Rust nên là default cho mọi system không phải cùng một khẳng định. Mục này không ước lượng những kết luận ấy xuất hiện thường xuyên đến đâu trong online discourse; thay vào đó, nó phân tích cần thêm tiền đề nào khi các mệnh đề bị gộp lại.

8.7.1 Khuyến nghị NSA/CISA giả định nhiều memory-safe language và adoption có điều kiện

Software Memory Safety của NSA được phát hành lần đầu năm 2022 và cập nhật thành Version 1.1 vào tháng 4 năm 2023. Bản v1.1 hiện được công bố khuyến nghị, khi có thể, cân nhắc chuyển dịch chiến lược từ các ngôn ngữ có ít inherent memory protection như C/C++ và assembly sang memory-safe language. Tài liệu nêu Python, Java, C#, Go, Delphi/Object Pascal, Swift, Ruby, Rust và Ada như các ví dụ; đồng thời lưu ý mức bảo vệ giữa các MSL khác nhau và hardening bằng compiler option, analysis tool hay OS configuration vẫn có giá trị.133

Báo cáo chung NSA/CISA năm 2025, Memory Safe Languages: Reducing Vulnerabilities in Modern Software Development, làm ranh giới này rõ hơn. Báo cáo nêu Ada, C#, Delphi/Object Pascal, Go, Java, Python, Ruby, Rust và Swift như các ví dụ, đồng thời nói language choice phụ thuộc vào điều kiện như concurrency và performance. Tài liệu cũng nói rõ MSL adoption không thực tế trong mọi circumstance hay solution area, và large existing codebase cùng mission-critical system có thể chịu chi phí chuyển đổi đáng kể.134

Quan trọng là guidance năm 2025 không yêu cầu rewrite toàn bộ existing code. Nó mô tả incremental integration qua interoperability và cả cách harden non-MSL code khi MSL adoption không thực tế.134 Vì vậy, điều các tài liệu này hỗ trợ mạnh là policy/engineering direction nâng memory safety thành mục tiêu thiết kế quan trọng và chủ động xem xét MSL adoption, chứ không phải kết luận rằng chính phủ đã chỉ định Rust là ngôn ngữ duy nhất được phê chuẩn.

8.7.2 Báo cáo ONCD 2024 nêu Rust như một ví dụ đồng thời ghi rõ giới hạn áp dụng

Back to the Building Blocks năm 2024 của Office of the National Cyber Director Hoa Kỳ trình bày memory-safe language adoption như một high-leverage measure của secure-by-design. Báo cáo nói sản phẩm mới có thể chọn MSL ngay từ đầu, còn existing codebase có thể dùng hybrid approach, di chuyển trước các function hay library có risk cao hơn. Cùng tài liệu nói rõ không có “one-size-fits-all solutions” và memory-safe language không thể loại bỏ mọi cybersecurity risk.135

Phần về space system đặc biệt hữu ích để xác định ranh giới của việc viện dẫn Rust. Báo cáo mô tả một edge case cần close-to-kernel control, deterministic timing, và không có garbage collector hoặc có thể override GC, rồi đưa Rust như một ví dụ về memory-safe language có ba đặc tính đó. Tuy nhiên, ngay sau đó tài liệu nói Rust lúc ấy chưa được chứng minh đầy đủ trong space systems và cần thêm toolchain development, workforce education cùng fielded case study; memory-safe hardware và formal methods cũng được bàn như complementary approach.135

Vì vậy, câu “White House đã chỉ định Rust làm standard cho systems programming” mạnh hơn báo cáo. Tài liệu trực tiếp hỗ trợ memory safety như một security objective, giá trị lớn của MSL adoption, Rust như một ví dụ có triển vọng cho một số constrained native workload, và yêu cầu xem xét cả workload lẫn maturity khi đánh giá applicability.

8.7.3 Từ guidance của chính phủ đến “Rust là lựa chọn thực tế duy nhất” cần một phép so sánh riêng

Phần sau không phải trích dẫn trực tiếp của cơ quan hay cá nhân nào, mà là một mệnh đề tổng hợp để kiểm tra suy luận có thể được tạo ra khi kết hợp các nguồn chính phủ khác nhau.

  1. Cơ quan chính phủ khuyến nghị giảm phụ thuộc vào memory-unsafe language và mở rộng MSL adoption.
  2. Rust là một trong các MSL xuất hiện trong tài liệu chính phủ, và DARPA cũng tài trợ nghiên cứu tự động dịch C sang Rust.
  3. Vì vậy Rust là lựa chọn thực tế duy nhất cho systems programming.

Hai tiền đề đầu có thể được tài liệu hỗ trợ, nhưng kết luận thứ ba thiếu candidate comparison. Các ngôn ngữ NSA/CISA nêu ra khác nhau về runtime model, deterministic behavior, FFI, platform coverage và ecosystem; danh sách còn có các ứng viên như Ada có thể hỗ trợ GC-free native execution và high-assurance domain. Ngược lại, với một low-level workload cụ thể, tổ hợp ecosystem, interoperability, performance và memory-safety model của Rust thực sự có thể là lựa chọn mạnh nhất. Kết luận đúng phải dựa vào project requirement và candidate-specific evidence, không chỉ dựa vào việc tên ngôn ngữ có mặt trong danh sách.

Danh sách ngôn ngữ của chính phủ cũng không nên được đọc như exhaustive standard. NSA và NSA/CISA trình bày nhiều ngôn ngữ dưới dạng “examples” hoặc “such as”.133134 Vì vậy, ngôn ngữ không có trong danh sách không tự động trở thành memory-unsafe hay bị policy cấm, và việc có tên trong danh sách cũng không phải chứng nhận phù hợp cho một workload cụ thể.

Để biện minh cho lựa chọn độc quyền ở project level, tối thiểu cần so sánh threat/defect model, latency và worst-case timing, memory/resource budget, việc GC/runtime có được chấp nhận hay không, target/toolchain support, certification/assurance requirement, existing code và ABI, interoperability cost, staffing và multi-year lifecycle. Nếu các ứng viên thực tế khác không đáp ứng những yêu cầu đó, Rust có thể trở thành lựa chọn de facto duy nhất của project; nhưng kết luận ấy đến từ phép so sánh, không phải từ thẩm quyền chính phủ tự thân.

4. Quy kết nhân quả và giá trị ngoại suy của trường hợp thành công công nghiệp

Trường hợp công nghiệp là bằng chứng quan trọng cho hiệu quả lựa chọn kỹ thuật. Nhưng trước và sau đổi ngôn ngữ, cấu trúc dữ liệu, kiến trúc, mô hình đồng thời, tái sử dụng kết nối, triển khai, phần cứng, kỹ năng nhóm và chỉ số quan sát cũng có thể đổi. Muốn quy toàn bộ kết quả cho một ngôn ngữ phải nêu workload và baseline giống nhau, các yếu tố thay đồng thời, thời gian so sánh và phương án phản thực tế.

  1. Kết quả bảo mật Android: Google báo tỷ lệ lỗ hổng an toàn bộ nhớ Android giảm từ 76% năm 2019 xuống 24% năm 2024 và lần đầu dưới 20% năm 2025. Phân tích 2025 dựa trên khoảng năm triệu dòng Rust Android và một lỗ hổng tiềm năng được phát hiện, sửa trước phát hành, ước tính mật độ thấp hơn dữ liệu lịch sử C/C++ trên 1.000 lần.136 137 Đây là bằng chứng mạnh trong mã mới, đang phát triển và ranh giới rủi ro cao. Tuy nhiên, toàn bộ mức giảm còn có chiến lược ngôn ngữ an toàn gồm Java/Kotlin, mã cũ trưởng thành, sandbox và lớp phòng vệ; không thể quy hết cho Rust.
  2. Trường hợp độ trễ Discord: Discord báo sau khi viết lại dịch vụ Read States cụ thể từ Go sang Rust, spike độ trễ định kỳ biến mất và chỉ số độ trễ, CPU, bộ nhớ cải thiện. Nguồn mô tả điều kiện cụ thể: Go 1.9.2, cache LRU khổng lồ, GC cưỡng bức mỗi hai phút; đồng thời nói rõ không khuyến nghị viết lại mọi hệ thống. Nguồn không đưa số P99 giảm 50%.138
  3. Tiết kiệm tài nguyên Pingora: Cloudflare so cùng lưu lượng và báo Pingora dùng ít hơn khoảng 70% CPU, 67% bộ nhớ so dịch vụ NGINX/OpenResty. Giải thích chính thức nêu không chỉ hiệu quả mã Rust mà cả kiến trúc đa luồng, loại bản sao qua ranh giới C–Lua, tăng tái sử dụng kết nối. Cải thiện độ trễ chủ yếu từ pool kết nối dùng chung của kiến trúc mới, không phải tốc độ thực thi mã.139 Đây là thành quả tái thiết kế dùng Rust, không phải thí nghiệm chỉ đổi ngôn ngữ.
  4. Thời gian khởi động Firecracker: Dưới 125 ms do AWS công bố là thành quả hệ thống Firecracker trên i3.metal, kích thước microVM mặc định và mô hình thiết bị tối thiểu. AWS thực sự chọn Rust vì an toàn bộ nhớ và luồng, nhưng dữ liệu không tách ngôn ngữ làm nguyên nhân hiệu năng độc lập.140
  5. Tiếp nhận liên tục trong kernel Linux: Sau hội nghị maintainer 2025, Miguel Ojeda nói thí nghiệm hỗ trợ Rust kết thúc và Rust sẽ ở lại. Cùng giải thích nói nhiều cấu hình kernel, kiến trúc và tổ hợp toolchain chưa hoàn tất, còn nhiều việc và tổ hợp thử nghiệm.141 Điều đó chứng minh hỗ trợ tiếp tục, không có nghĩa ngôn ngữ triển khai mặc định của toàn kernel đã thành Rust.

5. Truy nguồn số liệu, lỗ hổng và roadmap

Tuyên bố định lượng trông thuyết phục hơn khi số lớn hoặc cụ thể, nhưng kết luận thay đổi nếu năm khảo sát, quần thể, mẫu số, mô tả lỗ hổng hoặc trạng thái roadmap đổi.

  1. Quy mô hệ sinh thái: Ước tính 2,267 triệu là JetBrains dựa trên dữ liệu Developer Ecosystem 2024 về người dùng Rust trong 12 tháng trước.142 State of Rust Survey 2025 thu 7.156 phản hồi và tự cảnh báo không ngoại suy quá mức toàn cộng đồng từ khoảng 7 nghìn người.143 Hai nguồn có mục đích và quần thể khác nhau, không thể trích như một thống kê chung.
  2. Quy kết CVE: Mô tả chính thức CVE-2025-30388 là tràn bộ đệm heap Windows Win32K-GRFX cần thực thi cục bộ và tương tác người dùng. Không có quy kết mã Rust nên không thể dùng làm “lỗ hổng RCE đầu tiên trong mã Rust kernel Windows”.144 CVE-2025-68260 thì liên quan truy cập đồng thời thao tác xóa danh sách unsafe của Linux Rust Binder gây data race và hỏng con trỏ.145 Nó đòi hỏi audit hợp đồng unsafe và trạng thái chia sẻ, nhưng không hỗ trợ kết luận bảo đảm Safe Rust không tồn tại hay tác động tự động giới hạn trong khối unsafe.
  3. Trạng thái tính năng async: Roadmap Rust 2026 nói hiện tại chỉ có destructor đồng bộ, nêu nhu cầu dọn dẹp bất đồng bộ và đặt nền tảng destructor được bảo đảm cùng async drop là đối tượng khám phá 2026–2027.146 Đây là hướng nghiên cứu, không phải lời hứa đưa vào một “edition 2027” cụ thể.

6. Phân biệt security guidance, research program Rust-specific và tuyên bố “standard”

Guidance chung NSA/CISA năm 2025 khuyến nghị mạnh MSL adoption nhưng nói rõ ngôn ngữ và chiến lược chuyển đổi phù hợp phụ thuộc hoàn cảnh, complete rewrite không bắt buộc, và non-MSL hardening vẫn cần khi MSL adoption không thực tế.134 Vì vậy, đây là security guidance ưu tiên memory safety, không phải procurement standard hay language mandate chỉ định riêng Rust.

TRACTOR của DARPA là bằng chứng hẹp hơn và thực sự Rust-specific. Mục tiêu program là nghiên cứu tự động dịch legacy C thành safe, idiomatic Rust ở chất lượng tương đương code do skilled Rust developer viết.147 Điều này trực tiếp chứng minh C-to-Rust translation là một khoản đầu tư defense research cụ thể của Hoa Kỳ. Tuy nhiên, mục tiêu research program không phải deployment result cho thấy mọi C code đã có thể được dịch tự động chính xác và kinh tế, cũng không phải policy decision cấm các MSL khác.

Do đó, khi nói một công nghệ “đã thành standard” hoặc “được chính phủ chọn”, cần phân biệt ít nhất ba tầng:

  • Security objective và guidance: nhiều nguồn chính phủ Hoa Kỳ nhất quán ủng hộ giảm memory-safety vulnerability và lập kế hoạch MSL adoption ở nơi thực tế.
  • Lựa chọn research, procurement hoặc project cụ thể: program như TRACTOR chỉ rõ Rust, nhưng phạm vi của lựa chọn bị giới hạn bởi mission và evaluation criteria của program đó.
  • Universal language mandate: guidance được trích dẫn không quy định mọi software producer phải dùng Rust hay mọi lựa chọn non-Rust đều phải được biện minh như một ngoại lệ. Muốn khẳng định nghĩa vụ như vậy cần statute, procurement rule, contract term hoặc domain-specific standard áp dụng với scope rõ ràng.

Quy tắc tương tự áp dụng cho kết quả công nghiệp. Android, Pingora, Firecracker, Discord và Linux có thể chứng minh production feasibility và observed outcome trong môi trường tương ứng, nhưng kết hợp các case đó với government policy vẫn không tự động tạo universal Rust mandate. Một policy direction mạnh hướng tới memory safety, các thành công thực tế quan trọng của Rust, và Rust-first choice cho một project cụ thể có thể cùng đúng; dù vậy, lựa chọn ngôn ngữ trên toàn software domain vẫn là một câu hỏi so sánh riêng.

8.8 Phía sau diễn ngôn: nỗ lực cải tiến chính thức và quản trị cộng đồng

Các mục trước đã phân tích sự phóng đại, lựa chọn công nghệ mang tính loại trừ và phán xét về năng lực hay địa vị trong một số diễn ngôn phi chính thức. Không nên khái quát những ví dụ đó thành thái độ của toàn bộ Rust Project. Dự án chính thức có các quy trình riêng để đề xuất và xem xét thay đổi đối với ngôn ngữ, thư viện, tooling và governance; đây là một đơn vị phân tích khác với thảo luận trực tuyến phi chính thức.

Quy trình RFC (Request for Comments) tạo một con đường công khai cho các thay đổi đáng kể như semantics của ngôn ngữ hay thay đổi lớn trong standard library: đề xuất được review, nhược điểm và phương án thay thế được thảo luận, rồi các team liên quan ra quyết định. Như kho RFC mô tả, không phải mọi thay đổi đều cần RFC, và RFC được merge cũng không tự động bảo đảm implementation hay stabilization. Vì vậy, sự tồn tại của RFC chỉ chứng minh có một con đường đề xuất và review chính thức; nó không chứng minh mọi phê bình đều được chấp nhận hay mô tả thái độ của mọi người tham gia.118

Project Goals và hồ sơ công việc của các team cho thấy cùng một ranh giới. Tài liệu chính thức 2025-2026 công khai các vấn đề chưa hoàn tất về async ergonomics, hiệu năng build/editor, debugging, hỗ trợ dự án low-level và cải tiến borrow checker, đồng thời đề cập hỗ trợ của team, nguồn lực sẵn có và độ khó implementation.118 Điều này là bằng chứng rằng dự án thừa nhận công việc chưa hoàn tất, nhưng goal document không phải là outcome đã hoàn thành; cải tiến thực tế phải được đánh giá riêng bằng trạng thái implementation và kết quả đo lường.

Khi đánh giá governance chính thức cần tách ít nhất bốn tầng: 1) vấn đề có được dự án chính thức thừa nhận hay không; 2) RFC, project goal, issue hay team decision có tồn tại và thực sự vận hành hay không; 3) đề xuất có được implementation và đi tới stable release hay không; 4) các chỉ số mục tiêu như compile time, error rate, usability hay maintenance cost có thực sự cải thiện trong môi trường vận hành hay không. Không thể suy ra tầng sau chỉ từ sự tồn tại của tầng trước; ngược lại, công việc còn dang dở cũng không làm toàn bộ quy trình cải tiến trở nên vô nghĩa.

Sự phân biệt này giúp Chương 8 không trở thành phê bình một chiều. Lập luận phòng thủ trong không gian phi chính thức nên được đánh giá như chính lập luận đó, còn hoạt động cải tiến của dự án chính thức phải được đánh giá bằng hồ sơ chính thức và kết quả thực tế. Hai phía có thể ảnh hưởng lẫn nhau, nhưng không có cơ sở để coi ví dụ của một phía là mẫu đại diện cho toàn bộ phía kia.

Vì vậy kết luận của Chương 8 có giới hạn rõ ràng. Trong diễn ngôn quanh Rust có thể xuất hiện lập luận biến ưu thế kỹ thuật có điều kiện thành ưu thế phổ quát hoặc phán xét địa vị cá nhân. Đồng thời Rust Project có các cơ chế thể chế để ghi nhận vấn đề chưa giải quyết và review thay đổi. Vế trước không tự động chứng minh ngôn ngữ có lỗi, và vế sau không tự động chứng minh thành công kỹ thuật hay văn hóa cộng đồng lành mạnh. Claim, process, implementation và measured outcome phải được đánh giá ở đúng tầng bằng chứng của chúng.


Phần V: Tổng hợp và kết luận

Phần V tổng hợp các phân tích đã được kiểm toán ở các chương trước mà không bổ sung các causal claim mạnh mới. Chương 9 đưa ra kết luận cho năm research question trong phạm vi mà bằng chứng hiện tại hỗ trợ; Chương 10 xây dựng các nhiệm vụ cải tiến và khung lựa chọn công nghệ trên nền đó.

9. Đánh giá lại Rust: lợi ích, ràng buộc và chiến lược lựa chọn công nghệ

Vai trò của Chương 9 không phải là ca ngợi hay bác bỏ Rust thêm lần nữa, mà là kết hợp ranh giới guarantee, cost, industrial case, change strategy và discourse đã được xác lập trong Chương 1-8 thành một bài toán lựa chọn.

9.1 Phân tích đặc tính kỹ thuật và lĩnh vực áp dụng của Rust

Một ưu điểm kỹ thuật quan trọng của Rust là, trong phạm vi mà quy tắc Safe Rust và các abstraction tầng dưới sound, nó biến một số lớp memory error và data race thành ràng buộc ở compile time. Nhờ đó các lỗi như use-after-free, lifetime tham chiếu không hợp lệ và các aliasing pattern bị quy tắc tham chiếu của Safe Rust cấm có thể bị chặn trước khi chạy. Đây là lý do lựa chọn mạnh đối với component đồng thời cần low latency, kiểm soát trực tiếp resource use, native-code performance và memory safety. Tuy vậy latency và resource bound thực tế vẫn phải được đo hoặc chứng minh riêng cho allocator, đồng bộ, hệ điều hành và workload đang dùng.

Tuy nhiên ranh giới guarantee phải được nói rõ. Soundness của implementation unsafe, FFI contract, library và OS interface tạo thêm nghĩa vụ riêng; Safe Rust cũng không loại bỏ logic error, deadlock, resource exhaustion, memory leak, authorization check sai hay service interruption do panic. Biến “compile thành công” thành “program an toàn” hoặc “không có security vulnerability” là vượt quá guarantee.

Các case Android, Pingora, Firecracker, Discord và Linux cho thấy Rust có thể thực dụng trong một số production workload. Một số case báo cáo lợi ích về memory safety, loại bỏ GC, resource use, latency hoặc maintenance. Nhưng rewrite thường đi kèm thay đổi architecture, algorithm, workload, hardware, deployment, testing và staffing, nên không thể quy toàn bộ kết quả quan sát được cho riêng ngôn ngữ.

Mức phù hợp của Rust vì thế phụ thuộc defect model và điều kiện vận hành. Nó có thể được ưu tiên cao cho system component mới, networking, storage, virtualization và security boundary khi memory safety và low-level control đều quan trọng. Ngược lại, legacy asset đã ổn định, ràng buộc hard real-time hay certification, platform ecosystem hiện hữu phong phú, hoặc business application nơi GC cost không đáng kể có thể có lifecycle cost thấp hơn với lựa chọn khác. Câu hỏi chính xác hơn không phải “đây có phải ngôn ngữ tốt không?” mà là “muốn giảm loại failure nào và sẵn sàng trả cost nào?”.

9.2 Hiện thực hệ sinh thái và mô hình năng lực lập trình viên đa chiều

Giá trị kỹ thuật của ngôn ngữ và giá trị của cá nhân lập trình viên không phải cùng một biến. Rust proficiency liên quan trực tiếp tới role cần Rust, nhưng không có cơ sở dùng sở thích hay mức thành thạo một ngôn ngữ làm proxy chung cho intelligence, professionalism hay moral worth.

Software engineering bao gồm requirements, design, implementation, testing, security, performance, operations, maintenance, collaboration và domain knowledge. Vì vậy hiring và capability assessment nên tập trung vào work sample và structured criteria gắn với role thực tế. Rust role có thể đánh giá trực tiếp ownership, borrowing, async, FFI và ecosystem experience; các tiêu chí đó có thể không phải trọng tâm ở role khác. Vượt qua độ khó của một ngôn ngữ, hay không dùng ngôn ngữ đó, đều không đủ để giải thích tổng thể engineering ability.

Market evidence và preference evidence cũng phải tách biệt. Rust satisfaction cao trong survey, adoption bởi một công ty cụ thể và quy mô job-posting market đo các population và variable khác nhau. Muốn nối chúng cần labor-market data riêng cùng sampling definition rõ ràng. Vì vậy cả “ngôn ngữ phổ biến nên career market chắc chắn lớn” lẫn “ít việc nên công nghệ yếu” đều không hợp lệ.

Giáo dục cũng vậy. Ownership và borrow checking có thể dạy cách suy nghĩ hữu ích về memory và aliasing, nhưng không thay thế toàn bộ nền tảng về data structure, OS, network, concurrency, compiler hay manual memory management. Ngược lại, cũng chưa có bằng chứng rằng bắt buộc phải tự trải nghiệm pointer bug trong C/C++ mới hiểu systems. Nên kết hợp abstraction và low-level experience tùy learning objective.

9.3 Cộng đồng kỹ thuật, đánh giá tổ chức và tính bền vững của hệ sinh thái

Tính bền vững không chỉ do language design quyết định. Maintainer capacity, kinh phí và thời gian, release/security response, documentation, onboarding, decision procedure và năng lực đầu tư dài hạn của tổ chức đều quan trọng. RFC và project-goals ở Chương 8 cho thấy có cơ chế thể chế để điều phối, nhưng bản thân cơ chế không bảo đảm outcome tốt.

Online discourse có cùng giới hạn suy luận. Một số thảo luận thay technical rebuttal bằng phán xét qualification, intelligence hay morality của đối phương, hoặc gọi lựa chọn ngoài Rust là vô trách nhiệm. Những ví dụ này có thể dùng để phân tích cấu trúc lập luận, nhưng nếu không có sampling design thì không thể ước lượng xu hướng hay tần suất của toàn bộ Rust user population. Ngược lại, sự tồn tại của Code of Conduct hay RFC process cũng không chứng minh mọi interaction đều lành mạnh.

Ở cấp tổ chức, cần xem technology choice cùng evaluation system. Preventive work, testing, documentation, refactoring và observability thường kém dễ thấy hơn short-term feature output. Nếu đánh giá dựa quá nhiều vào lines of code, overtime hay emergency recovery, mọi người sẽ có incentive tối ưu những tín hiệu đó. Các pattern này có thể kiểm chứng tốt hơn qua goal, incentive, authority/responsibility, resource allocation, psychological safety và labor-market condition hơn là qua intelligence hay nationality.

Kết luận tổng hợp của Chương 9 vì thế có giới hạn. Rust là một systems-programming tool quan trọng chặn mạnh một số memory error và data race trong ranh giới Safe Rust sound. Các case trong nhiều môi trường công nghiệp xác nhận production feasibility của Rust, và một số case ghi nhận lợi ích có điều kiện xuất hiện cùng Rust adoption. Đồng thời guarantee không tự động mở rộng qua unsafe, FFI, logic/resource/operational boundary, và compile-time, tooling, learning, integration, transition cost vẫn tồn tại. Có project hợp lý với Rust implementation mới hoặc selective adoption; project khác có thể tốt hơn với modernization, hardening, partial replacement hoặc tiếp tục dùng ngôn ngữ hiện có.

Do đó câu trả lời chung cho năm research question không phải language ranking mà là quy trình lựa chọn với ranh giới được nêu rõ. Hãy xác định failure class cần kiểm soát, so sánh guarantee và failure condition của các candidate technology, rồi tính cả existing asset, transition risk, operations, staffing và ecosystem cost. Dùng adoption case như bằng chứng về feasibility và điều kiện, nhưng kiểm tra causal effect và universal suitability riêng; đồng thời không biến technical preference thành phán xét địa vị con người. Trong các ranh giới đó, điểm mạnh của Rust đã đủ đáng kể và không cần được biến thành mệnh đề phổ quát.

10. Kết luận: Thách thức và triển vọng cho tính bền vững của hệ sinh thái

Vai trò của Chương 10 không phải là bổ sung một tuyên bố mới về tính ưu việt của công nghệ, mà là chuyển các kết luận kỹ thuật, công nghiệp và tổ chức đã được kiểm tra trong Chương 1-9 thành các khuyến nghị có điều kiện được nêu rõ. Những giá trị được ưu tiên trong các khuyến nghị này gồm giảm các lỗi nghiêm trọng, khả năng dự đoán hiệu năng và mức sử dụng tài nguyên, khả năng phục hồi dịch vụ, khả năng bảo trì dài hạn, tính đảo ngược của thay đổi, an ninh chuỗi cung ứng và khả năng truy vết căn cứ của quyết định. Không có giả định rằng một giá trị luôn phải lấn át các giá trị khác.

Vì vậy, chương này không dự đoán “Rust có trở thành ngôn ngữ thống trị trong tương lai hay không”. Thay vào đó, dựa trên các ranh giới bảo đảm và chi phí thực tế đã được xác lập, chương đề xuất Rust Project và các tổ chức áp dụng Rust nên xử lý vấn đề nào và đánh giá chúng bằng loại bằng chứng nào.

10.1 Các thách thức cải thiện cấu trúc của hệ sinh thái

Cải thiện cấu trúc không đồng nghĩa với việc tăng số lượng tính năng. Trong các hệ thống vận hành lâu dài, ranh giới tương tác, tài liệu bảo đảm, độ trễ của vòng phản hồi phát triển, năng lực chuỗi cung ứng và bảo trì, cũng như khả năng truy vết kết quả quản trị đều có thể trở thành nút thắt. Các vấn đề có thể xác nhận trong tài liệu chính thức hiện nay cũng trải trên nhiều tầng như vậy.

1. Tương tác và ABI: phân rã câu “không có ABI ổn định” thành vấn đề thực tế

Rust Reference nêu rõ ABI native extern "Rust" không cung cấp stability guarantee, còn repr(Rust) mặc định chỉ cung cấp các bảo đảm bố trí hạn chế cần thiết cho soundness. Đồng thời Rust hỗ trợ các đầu ra liên kết động như dylib, cdylib và các ranh giới tương tác tường minh như extern "C", repr(C).102 Vì vậy, mô tả vấn đề thành “Rust không thể dynamic linking” là không chính xác.

Câu hỏi thực tế là ranh giới nào phải được duy trì như một hợp đồng tương thích, và trong bao lâu. Khi binary compatibility quan trọng, chẳng hạn plugin được triển khai độc lập lâu dài, system library hoặc code Rust/C/C++ hỗn hợp, cần thiết kế tường minh ABI, representation, allocator ownership, error và unwind, lifetime, cũng như version negotiation. Ngược lại, với ứng dụng được build và deploy cùng nhau bằng một toolchain, độ ổn định dài hạn của Rust-native ABI có thể có mức ưu tiên thấp hơn.

2026 Rust Project Goals bao gồm công việc tiếp tục lập bản đồ không gian vấn đề C++/Rust interoperability, và tài liệu chính thức liên quan không giả định rằng việc viết lại toàn bộ lượng tài sản C++ hiện có trong thời gian ngắn là khả thi hoặc nên làm.148 Do đó, thay vì cố định việc cải thiện hệ sinh thái vào một mục tiêu duy nhất như stable ABI cho libstd, hợp lý hơn là chia các ranh giới migration thực tế thành các hợp đồng tương tác và vấn đề tooling có thể đo lường.

2. Lĩnh vực cần mức bảo đảm cao: nối khoảng cách giữa bảo đảm của ngôn ngữ và safety case có thể kiểm chứng

Safe Rust cung cấp các bảo đảm mạnh, nhưng hệ thống đòi hỏi mức bảo đảm cao phải truy vết được các bảo đảm đó phụ thuộc vào implementation unsafe, compiler, library, target và toolchain nào. Các mục tiêu chính thức của Rust năm 2026 bao gồm tài liệu quy phạm cho các pattern unsafe sound, duy trì Formalized Language Specification, hỗ trợ sanitizer, MC/DC coverage và công việc compiler cho Rust-for-Linux—những hoạt động nhằm củng cố hạ tầng bảo đảm và kiểm chứng.149

Đáng chú ý, chính tài liệu goal chính thức ghi nhận khoảng trống hiện tại trong tài liệu có thẩm quyền về unsafe. Điều này không chứng minh Rust không phù hợp với lĩnh vực cần bảo đảm cao, cũng không chứng minh vấn đề đã được giải quyết chỉ vì goal đã được đăng ký. Project có yêu cầu assurance level cao phải đối chiếu trạng thái qualification của compiler và library dự kiến dùng, normative contract, coverage, static/dynamic analysis, traceability và phạm vi hỗ trợ dài hạn với điều kiện chứng nhận và vận hành thực tế. Ada/SPARK, tooling kiểm chứng cho C/C++ và các memory-safe language khác cũng nên được so sánh theo cùng yêu cầu.

3. Chi phí build, IDE và debugging: đo feedback loop của workload mục tiêu thay vì gán một cấp độ chung cho toàn hệ sinh thái

Như Chương 5 và 6 đã cho thấy, 2025 compiler-performance survey có cả phản hồi hài lòng với build/editor latency và phản hồi coi chúng là blocker nghiêm trọng. Đặc biệt, mẫu self-selected và câu hỏi yêu cầu chọn “project gây khó khăn nhiều nhất” không thể được khái quát thành trải nghiệm trung bình của mọi Rust workload.93 Khoảng trống capability khi debugging cũng khác nhau theo debugger và hệ điều hành.98

Vì vậy, thay vì gán cho Rust tooling một nhãn duy nhất như “trưởng thành” hay “chưa trưởng thành”, repository dự định áp dụng Rust nên đo clean build, incremental build, CI queue, rust-analyzer latency và memory, link time, khả năng debugger và artifact size. Nếu các chi phí này vi phạm mục tiêu phát triển hoặc vận hành thực tế, có thể thử cải tiến compiler/Cargo/IDE, tái cấu trúc dependency, lựa chọn profile và linker, build cache rồi đo lại. Project goal chính thức có thể làm bằng chứng về hướng cải tiến, nhưng không thay thế được kết quả đã được đo sau khi hoàn thành.118

4. Chuỗi cung ứng và bảo trì: xây dựng chuỗi tin cậy có thể vận hành thay vì dùng số crate hay version làm proxy

Tính bền vững của package ecosystem khó có thể đánh giá chỉ bằng số lượng crate hay việc version đã vượt 1.0 hay chưa. Đối với vận hành dài hạn, các câu hỏi trực tiếp hơn là ai duy trì dependency cần thiết, release provenance và update path có truy vết được không, có khả năng phản ứng với vulnerability và maintainer succession hay không, và có phục hồi được khi registry hoặc hạ tầng phân phối gặp sự cố hay không.

Rust Foundation mô tả ecosystem security là một mục tiêu luôn thay đổi và tiến hành audit, threat modeling cùng phát triển security tool. 2026 Rust Project Goals cũng bao gồm verifiable mirroring prototype cho Rustup/Cargo và công việc ổn định Cargo SBOM precursor.150 Các dữ kiện này không chứng minh supply chain hiện tại nhìn chung là không an toàn, cũng không bảo đảm tool mới sẽ giải quyết mọi risk. Tổ chức nên xây dựng dependency inventory, lock/update policy, provenance, SBOM, advisory response, private/official mirror policy, maintainer continuity và rollback procedure phù hợp với threat model của mình.

5. Quản trị: tăng khả năng nối từ kế hoạch công khai đến implementation và effect

Như Mục 8.8 đã trình bày, RFC và Project Goals là các cơ chế thể chế công khai vấn đề và đề xuất, đồng thời nối chúng với team review và cam kết tài nguyên. Quy trình goals 2026 cũng nêu cấu trúc bottom-up, trong đó contributor đề xuất goal còn các team liên quan cung cấp champion và review support.118 Cấu trúc như vậy có thể tăng khả năng cải tiến, nhưng sự tồn tại của goal không tự nó có nghĩa là completion, adoption hay effect.

Do đó, governance bền vững cần cho phép truy vết công khai vấn đề → quyết định → implementation/stabilization → effect quan sát được. Ghi lại goal bị chậm, dừng và thiếu resource có thể hữu ích cho ưu tiên tương lai không kém việc ghi goal hoàn thành. Ngược lại, cũng không nên khái quát một hay hai goal thất bại thành sự bất lực của toàn project. Chất lượng của formal process được đánh giá tốt hơn qua so sánh dài hạn về lý do quyết định, phân bổ resource, implementation result và effect người dùng quan sát được, thay vì chỉ dựa trên sự tồn tại của tài liệu.

Mức ưu tiên giữa năm nhóm vấn đề này thay đổi theo domain. Sản phẩm có plugin ABI là ranh giới chính khác với một appliance chỉ có một static binary; safety-critical controller cũng cần assurance case khác với web service thông thường. Vì vậy, thứ tự cải tiến gắn với failure condition và lifecycle của workload mục tiêu có khả năng kiểm chứng cao hơn một roadmap phổ quát kiểu “Rust ecosystem phải giải quyết X trước mới được coi là trưởng thành”.

10.2 Tổng hợp: Khung tư duy xem xét đồng thời công nghệ, chiến lược thay đổi, năng lực, đo lường và môi trường tổ chức

Cần phân biệt các kết luận thực nghiệm của Chương 1-9 với khuyến nghị trong chương này. Kết luận thực nghiệm mô tả ranh giới bảo đảm của Safe Rust, feasibility đã được chứng minh trong ứng dụng công nghiệp thực tế, build/tooling và migration cost, các vấn đề chưa hoàn tất mà project chính thức thừa nhận, cùng phạm vi diễn ngôn thực sự được quan sát. Khuyến nghị là phán đoán chuẩn tắc về giá trị nào nên được ưu tiên trên nền các dữ kiện đó.

Các khuyến nghị của cuốn sách ưu tiên các giá trị sau: giảm defect nghiêm trọng và security risk; thỏa performance và resource constraint; có thể phục hồi sau service interruption và change failure; không loại bỏ asset hiện có đã được kiểm chứng nếu không có lý do; tính cả maintenance, staffing và supply-chain cost dài hạn; giữ khả năng đảo ngược transition thất bại; và không biến preference công nghệ thành phán xét địa vị con người. Nếu project ưu tiên các giá trị khác, kết luận hợp lý cũng có thể khác.

Từ các tiền đề giá trị này, có thể đề xuất các mặc định có điều kiện sau.

Tình huống Chiến lược nên xem xét trước Giá trị và ràng buộc giả định
Component low-level, security-sensitive mới Xem Rust và các memory-safe native language khác là ứng viên mạnh Việc giảm memory-safety defect phải quan trọng, đồng thời GC/runtime constraint, yêu cầu performance/resource và ecosystem fit phải phù hợp
Hệ thống C/C++ quy mô lớn đang vận hành ổn định So sánh hardening, modernization, component Rust mới, selective replacement và full rewrite Phải giữ regression risk, implicit specification, ABI, rollback và chi phí coexistence dài hạn trong quyết định
Hệ thống safety/mission-critical So sánh assurance evidence và toolchain thực tế thay vì tên ngôn ngữ certification, normative contract, timing/resource bound, traceability và hỗ trợ dài hạn phải đáp ứng assurance level yêu cầu
Application thông thường chấp nhận GC và managed runtime Không đặt Rust làm automatic default; so sánh cả productivity, ecosystem và operation model Ngoài memory-safety guarantee, development speed, staffing, framework, fault isolation và operating cost có thể chi phối
Tổ chức muốn mở rộng công nghệ mới trên phạm vi lớn Chỉ mở rộng sau bounded pilot và kết quả đo Cần tách language effect khỏi redesign effect và bảo đảm training, tooling, operation, supply-chain capacity bền vững

Chiến lược new-code-first và interoperability của Android, cùng guidance về memory-safe language của NSA/CISA, cho thấy cách tiếp cận có điều kiện và từng bước là lựa chọn thực tế, thay vì buộc phải full rewrite hoặc áp đặt một ngôn ngữ duy nhất.112 134 Điều này vẫn không chứng minh incremental migration là tốt nhất cho mọi project.

Quy trình ra quyết định

  1. Xác định vấn đề và thứ tự ưu tiên giá trị. Xác định đâu là constraint thực sự trong latency, throughput, worst-case timing, memory, security, availability, certification, development speed và maintainability.
  2. Đo baseline và defect model. Ghi lại defect class hiện tại, incident impact, repair time, build/CI feedback, performance, resource usage và operational burden. Không có baseline, rất khó tách effect của cải tiến khỏi redesign effect.
  3. Viết ranh giới bảo đảm của từng ứng viên theo cùng một dạng. Nêu rõ Safe Rust, unsafe, FFI, GC, runtime, static analysis, formal proof và các cơ chế ứng viên khác bảo đảm gì và không bảo đảm gì.
  4. So sánh change strategy tách biệt với language choice. Xem xét tiếp tục maintenance, hardening, same-language refactoring/modernization, component Rust mới, selective replacement và full rewrite, kể cả specification recovery, interop, rollout và rollback cost.
  5. Pilot trên workload đại diện và ghi attribution. Đo không chỉ runtime performance mà cả defect discovery, build/IDE latency, memory và binary footprint, development time, incident, maintenance cost; đồng thời ghi thay đổi về architecture, algorithm, hardware và staffing.
  6. Xem xét lifecycle và năng lực tổ chức. Kiểm tra dependency và supply-chain management, security response, maintainer continuity, toolchain support, hiring/training, dual-language operation, on-call load và knowledge concentration có bền vững trong suốt project lifetime hay không.
  7. Đặt trước điều kiện mở rộng và dừng. Xác định target metric, rollout stage, observability, rollback boundary và failure budget; chỉ mở rộng khi đạt objective. Nếu kết quả xấu, tổ chức phải có khả năng dừng, sửa hoặc quay lại thay vì tái diễn giải thất bại để bảo vệ language identity.
  8. Ghi lại bằng chứng sẽ buộc quyết định phải xem xét lại. Compiler, ecosystem, standard, competing technology và điều kiện tổ chức đều thay đổi. Ghi trong decision record measurement hoặc event nào sẽ thay đổi quyết định hiện tại để lựa chọn công nghệ luôn là một giả thuyết có thể bác bỏ.

Quy trình này cụ thể hóa khuyến nghị cuối cùng của sách cho RQ3-RQ5. Với RQ3, case công nghiệp chứng minh feasibility và outcome có điều kiện, chứ không phải effect size phổ quát quy cho một ngôn ngữ. Với RQ4, maintenance, modernization, selective replacement và rewrite không phải thứ hạng mà là các strategy có risk profile khác nhau. Với RQ5, lợi thế kỹ thuật có điều kiện có thể biện minh cho quyết định áp dụng mạnh, nhưng không tạo ra kết luận về trí tuệ, tư cách hay giá trị đạo đức của người không sử dụng.

Tính bền vững của Rust không đòi hỏi che giấu điểm yếu, cũng không đòi biến chính điểm yếu thành identity. Bảo đảm mạnh cần được mô tả cùng ranh giới chính xác; công việc chưa hoàn tất phải phân biệt plan với result; adoption effect phải được kiểm chứng bằng measurement và attribution; và lựa chọn thất bại phải có khả năng đảo ngược. Khi các điều kiện đó được duy trì, Rust có thể được đánh giá là lựa chọn kỹ thuật rất mạnh trong một số domain, đồng thời kết luận rằng ngôn ngữ hoặc change strategy khác hợp lý hơn ở domain khác cũng có thể được chấp nhận theo cùng tiêu chuẩn bằng chứng.


Lời kết

Câu hỏi mà cuốn sách theo đuổi đến cuối không phải là “Rust là ngôn ngữ tốt hay xấu”. Câu hỏi chính xác hơn là ta đang cố giảm loại thất bại nào, một bảo đảm thực sự có hiệu lực đến ranh giới nào, ta chấp nhận chi phí và rủi ro thay đổi nào để có được bảo đảm đó, và bằng chứng nào sẽ khiến ta sửa lại quyết định hiện tại.

Thứ nhất, giá trị kỹ thuật mạnh nhất của Rust nằm ở chỗ: trong phạm vi hợp đồng của Safe Rust và khi các triển khai tầng dưới vẫn sound, một số lớp lỗi bộ nhớ và data race trở thành các ràng buộc do compiler cưỡng chế. Bảo đảm này quan trọng và thực dụng. Tuy nhiên, nó không tự động loại bỏ nghĩa vụ của unsafe, FFI và các hợp đồng bên ngoài, lỗi logic, deadlock, resource exhaustion, memory leak, kiểm tra quyền sai, panic hay sự cố vận hành. Nêu rõ ranh giới này không làm giảm giá trị của Rust; nó làm chính xác phạm vi mà giá trị đó thực sự tồn tại.

Thứ hai, bảo đảm đó không xếp mọi công nghệ khác vào một thứ bậc duy nhất. Modernization và hardening của C/C++, runtime model của garbage-collected language, cùng các hợp đồng mạnh và công cụ xác minh của Ada/SPARK có mô hình thất bại và cấu trúc chi phí khác nhau. Mức độ phù hợp phụ thuộc vào hiệu năng và worst-case timing, giới hạn tài nguyên, yêu cầu assurance, tài sản và ABI hiện có, ecosystem, staffing và lifecycle. Vì vậy mục tiêu của so sánh không phải chọn người thắng cuộc mà là tìm tổ hợp giữa mức bảo đảm cần thiết và chi phí có thể gánh chịu.

Thứ ba, các trường hợp công nghiệp cho thấy Rust có thể được dùng trong môi trường production thực tế và có thể mang lại lợi ích có ý nghĩa trong những điều kiện nhất định. Nhưng thay đổi ngôn ngữ thường diễn ra đồng thời với thay đổi architecture, algorithm, hardware, deployment, testing và năng lực tổ chức, nên không thể quy toàn bộ kết quả quan sát được thành một hiệu ứng nhân quả phổ quát của riêng ngôn ngữ. Một case study là bằng chứng về tính khả thi và điều kiện áp dụng, không phải chứng nhận bảo đảm trước kết quả của dự án khác.

Thứ tư, chiến lược thay đổi cho hệ thống hiện có cũng không phải lựa chọn nhị phân. Tiếp tục bảo trì, hardening, refactoring và modernization trong cùng ngôn ngữ, viết thành phần mới bằng Rust, thay thế chọn lọc vùng rủi ro cao và full rewrite là các chiến lược riêng với rủi ro khác nhau. Quyết định tốt đến từ việc so sánh trên cùng cơ sở các lỗi hiện tại, đặc tả ngầm, rủi ro hồi quy, interoperability, rollout và rollback, cùng chi phí vận hành dài hạn—không phải từ cảm xúc với đầu tư quá khứ hay kỳ vọng dành cho công nghệ mới.

Thứ năm, lựa chọn công nghệ không phải công cụ để xếp hạng con người. Thành thạo Rust có thể là năng lực quan trọng trong công việc cần Rust, nhưng không phải đại diện cho trí thông minh chung, năng lực kỹ nghệ phần mềm tổng thể hay trách nhiệm đạo đức. Các trường hợp trực tuyến được phân tích trong sách cũng chỉ là dữ liệu định tính về những cấu trúc lập luận cụ thể, không phải mẫu đại diện để ước lượng đặc điểm hay tần suất thái độ của toàn bộ người dùng Rust. Quản trị chính thức của dự án và diễn ngôn phi chính thức cũng không nên bị coi là cùng một đối tượng.

Cuối cùng, điểm mạnh của Rust đã đủ mạnh mà không cần phóng đại. Với một số dự án, chủ động áp dụng Rust có thể là kết luận hợp lý nhất; với dự án khác, modernization hệ thống hiện có, chọn ngôn ngữ khác hoặc hoãn chuyển đổi có thể hợp lý hơn. Điều quan trọng là kết luận phải xuất phát từ yêu cầu được nêu rõ, bằng chứng có thể kiểm chứng và chiến lược thay đổi có thể quay lui khi thất bại, đồng thời vẫn có thể sửa đổi khi xuất hiện bằng chứng mới.

Mục đích của cuốn sách không phải chấm dứt tranh luận kỹ thuật, mà là giúp nói chính xác hơn một cuộc tranh luận đã chứng minh điều gì và chưa chứng minh điều gì. Đặt mô hình thất bại trước tên ngôn ngữ, phép đo trước khẩu hiệu và lựa chọn có thể kiểm chứng trước cạnh tranh địa vị—đó là tiêu chuẩn cuối cùng mà cuốn sách đề xuất.


Phụ lục: Phân tích các mẫu ngụy biện quan sát trong tranh luận kỹ thuật

Mục đích của phụ lục này không phải là đánh giá một cộng đồng hay cá nhân cụ thể, mà là luyện cách nhận diện cấu trúc lập luận có thể làm mờ tính hợp lệ của một tuyên bố trong tranh luận kỹ thuật. Mọi câu đáp dưới đây đều là ví dụ tổng hợp được tạo ra để minh họa; chúng không phải trích dẫn trực tiếp từ bài đăng có thật, không tái hiện lời của một người dùng cụ thể, không phải khảo sát tần suất và cũng không phải mẫu đại diện. Vì vậy, không thể dùng sự tồn tại của các ví dụ này để suy đoán đặc tính của toàn bộ người dùng Rust hay cộng đồng kỹ thuật khác.

Việc nhận ra một ngụy biện cũng không làm kết luận của phía kia tự động trở thành sai. Kết luận có thể đúng trong khi lý do được đưa ra chưa đủ để hỗ trợ nó. Mỗi trường hợp dưới đây vì thế tách riêng: (1) mệnh đề thực sự cần kiểm tra, (2) mệnh đề mà câu trả lời thực tế xử lý, (3) tiền đề hoặc bằng chứng còn thiếu, và (4) cách đặt lại câu hỏi theo dạng có thể kiểm chứng.

Trường hợp 1: Biến phê bình kỹ thuật thành đánh giá năng lực người nói — công kích cá nhân

  • Bối cảnh: Một nhà phát triển cho rằng Rust async có chi phí học tập hoặc làm tăng chi phí năng suất trong một codebase cụ thể.
  • Phản hồi tổng hợp: “Nếu bạn thấy tính năng đó khó thì vấn đề nằm ở năng lực của bạn, không phải ở ngôn ngữ.”
  • Phân tích: Kinh nghiệm của người nói có thể liên quan khi diễn giải trải nghiệm sử dụng, nhưng tự nó không bác bỏ được các tuyên bố về độ phức tạp API, rủi ro lỗi hay thời gian phát triển. Mệnh đề kỹ thuật đã bị thay bằng đánh giá con người.
  • Tái cấu trúc có thể kiểm chứng: Xác định workload, kinh nghiệm nhóm, thời gian triển khai, defect, latency và chi phí bảo trì; sau đó so sánh với mô hình thực thi khác hoặc bản triển khai trước. Kinh nghiệm có thể là một biến, nhưng không phải chính kết luận.

Trường hợp 2: Bác bỏ xuất thân hoặc động cơ thay vì nội dung — ngụy biện nguồn gốc và suy đoán động cơ

  • Bối cảnh: Một người có kinh nghiệm C++ cho rằng borrow checker đòi hỏi tái cấu trúc bổ sung trong một thiết kế cụ thể.
  • Phản hồi tổng hợp: “Bạn gọi đó là ràng buộc chỉ vì bám vào thói quen C++ và sợ mô hình mới.”
  • Phân tích: Kinh nghiệm trước đây có thể ảnh hưởng sở thích, nhưng động cơ được suy đoán không phải bằng chứng về ràng buộc và lợi ích mà borrow checker tạo ra trong thiết kế đang xét. Nội dung tuyên bố bị thay bằng giải thích tâm lý về người nói.
  • Tái cấu trúc có thể kiểm chứng: Trình bày quan hệ ownership và aliasing liên quan bằng code hoặc ví dụ tối thiểu, rồi so sánh việc tái thiết kế Rust yêu cầu, bảo đảm thu được và chi phí triển khai.

Trường hợp 3: Biến phê bình có điều kiện thành một tuyên bố mạnh hơn — người rơm

  • Bối cảnh: Có người cho rằng xử lý lỗi của Rust dài dòng hoặc kém thuận tiện hơn trong một thiết kế API cụ thể.
  • Phản hồi tổng hợp: “Vậy ý bạn là xử lý lỗi của Rust hoàn toàn vô dụng?”
  • Phân tích: “Có chi phí trong điều kiện này” và “toàn bộ tính năng vô dụng” là hai mệnh đề khác nhau. Bác bỏ mệnh đề mạnh hơn không giải quyết được so sánh ban đầu.
  • Tái cấu trúc có thể kiểm chứng: Giữ nguyên điều kiện và đối tượng so sánh của tuyên bố ban đầu, rồi đánh giá trade-off của Result, exception, panic hoặc chính sách khác trong error model liên quan.

Trường hợp 4: Gộp refactoring và viết lại thành một loại — sai phạm trù, lưỡng phân giả và ngụy biện hoàn hảo

  • Bối cảnh: Một nhóm thảo luận cách giảm lỗi trong hệ thống C/C++ cũ.
  • Phản hồi tổng hợp: “Refactoring thật sự là viết lại bằng Rust; mọi cải tiến khác đều vô nghĩa.”
  • Phân tích: Refactoring cùng ngôn ngữ, hardening, selective replacement và full rewrite có phạm vi thay đổi và kiểu thất bại khác nhau. Việc một chiến lược không loại bỏ mọi memory-safety defect ở cấp ngôn ngữ không làm giá trị giảm lỗi một phần hay cải thiện khả năng bảo trì trở thành số không.
  • Tái cấu trúc có thể kiểm chứng: So sánh nhiều chiến lược thay đổi trong cùng decision record theo phân bố defect hiện tại, test và đặc tả ngầm, rủi ro migration/rollback, FFI/ABI, hiệu năng, staffing và lifecycle cost.

Trường hợp 5: Biến trạng thái legacy thành thuộc tính đạo đức — so sánh sai và bước nhảy giá trị

  • Bối cảnh: Nhóm phải quyết định duy trì, hiện đại hóa hay thay thế một hệ thống cũ.
  • Phản hồi tổng hợp: “Legacy tự nó là xấu, vì vậy giữ công nghệ cũ là phi lý.”
  • Phân tích: Tuổi hệ thống có thể tương quan với hết hỗ trợ, technical debt hoặc rủi ro nhân sự, nhưng không phải thước đo chất lượng độc lập. Ngược lại, đầu tư đã bỏ ra trong quá khứ cũng không đủ để chứng minh nên giữ hệ thống. Điều cần so sánh là chi phí và rủi ro tương lai.
  • Tái cấu trúc có thể kiểm chứng: Đo defect rate hiện tại, độ ổn định vận hành, trạng thái supply chain và hỗ trợ, khả năng sửa đổi, chi phí thay thế, regression risk và chi phí bảo trì dự kiến; rồi so sánh duy trì, modernization, thay thế một phần và thay thế toàn bộ.

Trường hợp 6: Đồng nhất thành thạo ngôn ngữ với trí thông minh chung hoặc năng lực tổng thể — nhầm lẫn cấu trúc đo lường

  • Bối cảnh: Cuộc thảo luận nói về tiêu chí tuyển dụng cho vị trí Rust hoặc năng lực nhà phát triển nói chung.
  • Phản hồi tổng hợp: “Người học Rust tốt thông minh hơn, nên thành thạo Rust phải là tiêu chí trung tâm để đánh giá nhà phát triển.”
  • Phân tích: Thành thạo Rust có thể liên quan trực tiếp đến công việc Rust, nhưng không tự động đo trí thông minh chung, phân tích yêu cầu, thiết kế, debugging, vận hành, hợp tác hay tri thức miền. Việc đặc điểm của người học là do học công nghệ hay do self-selection cũng là câu hỏi riêng.
  • Tái cấu trúc có thể kiểm chứng: Xác định trước hành vi và kết quả mà công việc thực sự đòi hỏi. Đánh giá trực tiếp kiến thức Rust khi vai trò cần nó; các năng lực khác dùng work sample và tiêu chí có cấu trúc riêng.

Trường hợp 7: Biến vấn đề tổ chức thành bản chất của toàn bộ nhân sự — khái quát quá mức và nguyên nhân đơn

  • Bối cảnh: Thảo luận về workload quá cao, đánh giá không công bằng, tập trung tri thức và nghỉ việc.
  • Phản hồi tổng hợp: “Người giỏi đều rời đi và chỉ người kém ở lại, nên vấn đề của ngành được giải thích bằng năng lực thấp của người làm việc trong ngành.”
  • Phân tích: Giả thuyết rằng điều kiện làm việc và cấu trúc đánh giá ảnh hưởng retention và performance có thể kiểm tra. Nhưng suy từ vài trải nghiệm sang selection effect của toàn ngành và trí thông minh của thành viên bỏ qua định nghĩa quần thể, giải thích thay thế và biến đo lường.
  • Tái cấu trúc có thể kiểm chứng: Thu thập dữ liệu về tỷ lệ nghỉ việc, workload, lương thưởng, tiêu chí đánh giá, incident burden, team tenure, bus factor, tuyển dụng và performance; phân tích điều kiện tổ chức tách biệt với năng lực cá nhân.

Trường hợp 8: Hấp thụ mọi ý kiến phản đối thành bằng chứng cho niềm tin hiện có — lập luận tự phong kín

  • Bối cảnh: Có bất đồng về lợi ích của Rust hoặc nhu cầu áp dụng nó.
  • Phản hồi tổng hợp: “Người đồng ý là người hiểu công nghệ; người phản đối hoặc không hiểu, hoặc cảm thấy tự ti.”
  • Phân tích: Nếu cả đồng ý lẫn phản đối đều là bằng chứng cho cùng một kết luận, không quan sát nào có thể làm tuyên bố yếu đi. Điều kiện phản chứng biến mất và chỉ còn suy đoán động cơ của người khác.
  • Tái cấu trúc có thể kiểm chứng: Ghi trước benchmark, defect data, migration cost hoặc thay đổi ecosystem nào sẽ khiến quyết định hiện tại thay đổi. Đánh giá phản biện theo các điều kiện và bằng chứng đó, tách khỏi suy đoán tâm lý.

Trường hợp 9: Đồng nhất proxy dễ quan sát với thuộc tính của cả nhóm — lạm dụng chỉ số đại diện và khái quát mẫu

  • Bối cảnh: Một tổ chức thưởng cho làm thêm giờ, lượng code hoặc việc xử lý sự cố khẩn cấp dễ thấy.
  • Phản hồi tổng hợp: “Vì có kiểu đánh giá này nên nhà phát triển của một quốc gia nhìn chung có năng lực kỹ thuật và trí thông minh thấp.”
  • Phân tích: Phê bình code volume hay làm thêm giờ là thước đo chất lượng không đầy đủ là một mệnh đề; đánh giá năng lực của cả quần thể quốc gia là mệnh đề khác. Một số công ty hoặc ví dụ trên mạng không phải mẫu đại diện và cũng không cung cấp biến cần thiết cho giải thích nhân quả cấp quốc gia.
  • Tái cấu trúc có thể kiểm chứng: Ở cấp tổ chức, đo phòng ngừa, sự cố lặp lại, change failure rate, review quality, maintainability và kết quả công việc thực tế. Nếu thật sự cần so sánh quần thể, phải định nghĩa quần thể và mẫu, đồng thời thiết kế riêng các biến nhiễu như cơ cấu nghề, giáo dục và cấu trúc ngành.

Trường hợp 10: Gộp nhiều ca thành công thành một chuẩn phổ quát — trộn quy kết và mở rộng phạm vi khái quát

  • Bối cảnh: Cuộc thảo luận đưa cùng lúc các loại bằng chứng Rust khác nhau: Android, dịch vụ mạng, hạ tầng đám mây, Linux và khuyến nghị của chính phủ về memory-safe language.
  • Phản hồi tổng hợp: “Mọi bằng chứng đều chỉ cùng một hướng, nên trong mọi hệ thống, phía không chọn Rust giờ phải chứng minh mình là ngoại lệ.”
  • Phân tích: Nhiều trường hợp độc lập có thể hỗ trợ mạnh tính thực dụng và một số lợi thế của Rust. Nhưng workload, metric và denominator khác nhau không thể gộp thành một effect size duy nhất; rewrite cũng có thể đồng thời thay architecture, algorithm, hardware và vận hành. Chính sách khuyến nghị memory-safe language cũng khác với mệnh lệnh chỉ dùng Rust.
  • Tái cấu trúc có thể kiểm chứng: Đánh dấu riêng mỗi trường hợp hỗ trợ tính khả thi, kết quả quan sát trong một tổ chức, hiệu ứng nhân quả hay tính phù hợp phổ quát. Sau đó so sánh defect model, yêu cầu assurance, ràng buộc runtime/resource, tài sản hiện có, migration risk và các công nghệ ứng viên thực tế của dự án mục tiêu theo cùng tiêu chí.

Cách sử dụng phụ lục này

Trong tranh luận kỹ thuật, thường hữu ích hơn nếu kiểm tra lần lượt các câu hỏi sau thay vì vội gắn tên một ngụy biện.

  1. Mệnh đề mà người kia thực sự đưa ra là gì, điều kiện và phạm vi của nó đến đâu?
  2. Phản hồi có trực tiếp xử lý mệnh đề đó hay thay nó bằng mệnh đề mạnh hơn hoặc khác đi?
  3. Các tiền đề nối và bằng chứng cần thiết để đi đến kết luận có được nêu rõ không?
  4. case study, survey, benchmark hoặc policy document có thật sự hỗ trợ tính đại diện, quan hệ nhân quả hay tính phổ quát không?
  5. Quan sát nào xuất hiện thì phán đoán hiện tại phải được sửa đổi?

Quy trình này phải áp dụng như nhau cho lập luận ủng hộ lẫn phê bình Rust. Tranh luận kỹ thuật tốt không phải cuộc thi xếp hạng tư cách hay bản sắc của người tham gia, mà là quá trình làm cho phạm vi tuyên bố, ranh giới bảo đảm, bằng chứng có thể so sánh và điều kiện phản chứng trở nên chính xác hơn.


  1. Một kỹ thuật quản lý bộ nhớ trong đó runtime theo dõi khả năng tiếp cận của đối tượng và các trạng thái liên quan để tự động thu hồi bộ nhớ không còn được sử dụng. 

  2. Rust Core Team, Laying the foundation for Rust’s future; Aaron Turon, Abstraction without overhead: traits in Rust. Tài liệu thứ nhất giải thích lịch sử Rust bắt đầu như một dự án của Mozilla Research rồi chuyển thành dự án độc lập; tài liệu thứ hai mô tả các trục thiết kế gồm an toàn bộ nhớ, ngăn chặn tranh chấp dữ liệu và chi phí trừu tượng. 

  3. The Rust Reference, Behavior considered undefinedBehavior not considered unsafe; The Rustonomicon, How Safe and Unsafe Interact. Tài liệu chính thức cũng nêu rõ trách nhiệm về tính soundness của hợp đồng unsafe, việc các quy tắc ngữ nghĩa chưa hoàn chỉnh, và sự phân biệt giữa mất an toàn bộ nhớ với bế tắc, rò rỉ tài nguyên và lỗi logic.  2

  4. Aaron Turon, Abstraction without overhead: traits in Rust. Bài viết giải thích trừu tượng hóa không chi phí như một nguyên tắc cốt lõi trong thiết kế Rust, nhưng không bảo đảm phổ quát kết quả hiệu năng của một chương trình cụ thể. 

  5. The Rustonomicon, Data Races and Race Conditions; The Rust Programming Language, Using Threads to Run Code Simultaneously. Tài liệu chính thức phân biệt việc Safe Rust ngăn chặn tranh chấp dữ liệu với các vấn đề riêng biệt là điều kiện tranh đua nói chung và bế tắc. 

  6. The Rust Programming Language, Understanding Ownership, References and Borrowing, Validating References with Lifetimes. Tài liệu chính thức phân biệt vai trò của quyền sở hữu, quyền truy cập và hiệu lực tham chiếu, đồng thời giải thích rằng chú thích vòng đời không thay đổi thời gian sống thực tế của tham chiếu.  2 3

  7. Rust Project Goals, Stabilize and model Polonius AlphaThe Borrow Checker Within. Các mục tiêu chính thức năm 2026 giải thích rằng mượn có điều kiện và lending iterator bị phân tích NLL hiện tại từ chối sẽ được chấp nhận, trong khi một số mẫu cần độ nhạy luồng hoàn toàn vẫn là công việc tương lai. 

  8. The Rust Programming Language, Rc<T>, the Reference-Counted Smart Pointer, RefCell<T> and the Interior Mutability Pattern, Reference Cycles Can Leak Memory, Shared-State Concurrency. Các tài liệu này mô tả kiểm tra mượn khi chạy, đếm tham chiếu, rò rỉ do chu trình, chi phí hiệu năng của đếm tham chiếu nguyên tử, khóa và khả năng bế tắc. 

  9. Standard C++ Foundation, What is the zero-overhead principle?; Aaron Turon, Abstraction without overhead: traits in Rust. Hai tài liệu mô tả nguyên tắc này như một nguyên tắc thiết kế của C++ và mục tiêu trừu tượng hóa liên quan của Rust; chúng không quy định kết quả hiệu năng phổ quát cho một chương trình cụ thể.  2

  10. Rust Compiler Development Guide, Monomorphization; The Cargo Book, Profiles; The rustc book, Codegen Options; Richard Uhlig et al., Instruction Fetching: Coping with Code Bloat. Các nguồn này mô tả chi phí thời gian biên dịch và kích thước tệp nhị phân của đơn hình hóa, các đánh đổi liên quan đến tối ưu, đơn vị sinh mã và LTO, cùng ảnh hưởng có thể có của kích thước mã đến việc nạp lệnh.  2 3

  11. The Rust Reference, Trait object types; tài liệu từ khóa thư viện chuẩn Rust, dyn; thư viện chuẩn Rust, Box<T>, Vec<T>String; The Rust Reference, Panic. Các tài liệu phân biệt điều phối runtime qua trait object, cấp phát và cấp phát lại trên heap, cùng hành vi panic khi đánh chỉ mục vượt phạm vi.  2

  12. The Rust Programming Language, Performance in Loops vs. Iterators. Ví dụ chính thức quan sát hiệu năng tương tự trong một khối lượng công việc và nêu rằng so sánh rộng hơn cần nhiều đầu vào và điều kiện khác nhau. 

  13. The Rust Programming Language, Defining an EnumRecoverable Errors with Result; thư viện chuẩn Rust, OptionResult; The Rust Reference, Pointer types. Tài liệu chính thức phân biệt việc mô hình hóa trạng thái bằng OptionResult, cảnh báo must_use khi bỏ qua Result, cùng ranh giới giữa tham chiếu khác null và con trỏ thô có thể là null.  2 3

  14. The Rust Reference, match expressions, Patterns, The non_exhaustive attribute. Các tài liệu mô tả cách pattern guard hoạt động có điều kiện, kiểm tra tính đầy đủ, nhánh wildcard và quy tắc tiến hóa API đối với kiểu được đánh dấu #[non_exhaustive] từ crate bên ngoài. 

  15. The Rust Reference, Behavior considered undefined. Tài liệu tham chiếu xếp việc tạo enum với discriminant không hợp lệ, tham chiếu không hợp lệ hoặc giá trị vi phạm yêu cầu hợp lệ của kiểu vào hành vi không xác định; đồng thời giải thích rằng người triển khai phải duy trì tiền đề về tính hợp lệ qua ranh giới unsafe và FFI. 

  16. The Rust Reference, Type layoutPanic; thư viện chuẩn Rust, Option representation, Option::unwrapResult::unwrap. Các nguồn phân biệt các bảo đảm hạn chế của bố trí enum mặc định, tối ưu hóa con trỏ null cho một số kiểu, cùng hành vi panic và chiến lược panic của nhóm hàm unwrap 2

  17. The Cargo Book, Why Cargo Existscargo. Tài liệu chính thức định nghĩa Cargo là trình quản lý gói kiêm công cụ xây dựng của Rust và mô tả phạm vi mà hệ thống lệnh chung cung cấp việc tải phụ thuộc, xây dựng, kiểm tra, kiểm thử, tạo tài liệu, đóng gói và xuất bản. 

  18. The Cargo Book, Dependency Resolution, Features, FAQ — Why have Cargo.lock in version control?, SemVer Compatibility, Rust Versioncargo. Các tài liệu phân biệt phạm vi tính xác định của tệp khóa, khác biệt khi phân giải ngoại tuyến, phiên bản trùng, hợp nhất feature, tiền đề SemVer và giới hạn của rust-version/MSRV.  2 3 4 5

  19. The Cargo Book, Build ScriptsSpecifying Dependencies; The Rust Reference, Procedural macros. Tài liệu chính thức mô tả việc thực thi build.rs, liên kết thư viện native, phụ thuộc theo target và build dependency, cùng các ranh giới bảo mật như procedural macro được chạy lúc biên dịch và có thể truy cập tệp.  2 3 4

  20. The Cargo Book, Registry Index, Publishing on crates.io, cargo ownerThe Manifest Format. Các nguồn mô tả phạm vi của checksum SHA-256 cho tệp .crate, việc lưu giữ lâu dài và yank phiên bản đã xuất bản, quản lý owner và metadata giấy phép.  2

  21. The Cargo Book, Cargo Homecargo vendor; RustSec, cargo auditRustSec Advisory Database; CMake, cmake(1); Meson, Overview; Microsoft, vcpkg overview; Conan, Conan 2 documentation. Các nguồn này hỗ trợ ranh giới so sánh về cache, vendoring, công cụ kiểm toán lỗ hổng và sự tồn tại của các công cụ xây dựng, quản lý gói thực tế trong hệ sinh thái C/C++.  2 3

  22. The Rust Programming Language, What Is Ownership?, References and BorrowingReference Cycles Can Leak Memory; The Rust Reference, Behavior considered undefined; The Rustonomicon, Data Races and Race Conditions. Các nguồn này phân biệt quản lý bộ nhớ dựa trên sở hữu không cần GC, ranh giới của data race và hành vi không xác định, cùng việc race condition nói chung và rò rỉ bộ nhớ vẫn nằm ngoài phạm vi bảo đảm.  2

  23. C++ Core Guidelines, C++ Core Guidelines. Hướng dẫn này mô tả các thực hành an toàn tài nguyên của C++ hiện đại gồm RAII và resource handle, quản lý tài nguyên tự động qua smart pointer và container, và giảm dùng raw owning pointer cùng new/delete trực tiếp. Nguồn này được dùng để tránh so sánh như thể C++ không có kỹ thuật quản lý tài nguyên an toàn hơn; điều đó không có nghĩa các khuyến nghị này cung cấp cùng mức bảo đảm như việc trình biên dịch Rust bắt buộc kiểm tra các quy tắc. 

  24. Oracle Java SE, Garbage Collector ImplementationAvailable Collectors. Tài liệu chính thức xem throughput và latency là các chỉ số garbage-collection riêng biệt, đồng thời cho thấy sự đánh đổi giữa thời gian tạm dừng, throughput, mức dùng bộ nhớ và điều kiện áp dụng khác nhau theo collector. 

  25. The Cargo Book, Why Cargo Existscargo; The rustup book, Components, ProfilesOverrides; The Rust Programming Language, Useful Development Tools. Các nguồn này mô tả phạm vi của quy trình làm việc chung trong Cargo, quản lý toolchain/component của rustup, rustfmt và Clippy trong profile mặc định, rust-analyzer có thể cài đặt, và việc chỉ định toolchain theo từng dự án bằng rust-toolchain.toml

  26. Rust Compiler Performance Working Group, Rust compiler performance survey 2025 results; Rust Survey Team, 2025 State of Rust Survey Results. Nguồn thứ nhất báo cáo việc sử dụng lệnh Cargo và chi phí chờ build/CI dựa trên hơn 3.700 câu trả lời; nguồn thứ hai bàn về các vấn đề hạn chế năng suất dựa trên 7.156 câu trả lời hoàn chỉnh. Cả hai khảo sát đều dựa trên nhóm người liên quan đến Rust tự nguyện tham gia, vì vậy không dùng chúng làm so sánh có kiểm soát với ngôn ngữ khác hay để trực tiếp ước lượng hiệu ứng nhân quả của Cargo. 

  27. CMake, cmake(1)CMake Presets; Meson, Overview; Microsoft, vcpkg overviewManifest mode; Conan, Introduction. Các nguồn này cho thấy hệ sinh thái C/C++ cũng có các công cụ thực tế cho xây dựng, kiểm thử, đóng gói, quản lý phụ thuộc và phiên bản dựa trên manifest, gói nhị phân và kho riêng. 

  28. The rustup book, Cross-compilation; The Rust Programming Language, Installation. Tài liệu chính thức giải thích rằng rustup target add có thể cung cấp thư viện chuẩn cho target nhưng vẫn có thể cần linker hoặc SDK bên ngoài; các bản dựng Rust thông thường cần linker và một số crate có thể cần trình biên dịch C. 

  29. Maxwell E. McCombs and Donald L. Shaw, The Agenda-Setting Function of Mass Media, Public Opinion Quarterly 36(2), 1972, pp. 176-187. Nghiên cứu gốc so sánh khảo sát cử tri Chapel Hill trong cuộc bầu cử tổng thống Hoa Kỳ năm 1968 với phân tích nội dung của các phương tiện truyền thông họ sử dụng, qua đó xem xét mối quan hệ giữa mức độ truyền thông nhấn mạnh vấn đề và nhận thức của người tiếp nhận về tầm quan trọng của vấn đề. Vì vậy, khi áp dụng “thiết lập chương trình nghị sự” cho diễn ngôn Rust trong cuốn sách này, cần có dữ liệu diễn ngôn có thể so sánh, khoảng thời gian xác định, phép đo mức độ quan trọng ở phía người tiếp nhận và giới hạn suy luận nhân quả, thay vì chỉ dựa vào sự lặp lại của cách diễn đạt.  2 3 4

  30. Rust Core Team, Announcing Rust 1.0 Alpha; The Rust Programming Language, Fearless Concurrency; Rust Core Team, A new look for rust-lang.org; Rust Project, Rust Programming Language. Các nguồn này cho thấy những đề xuất giá trị ban đầu về an toàn, hiệu năng và đồng thời; cách diễn đạt chính thức “fearless concurrency”; việc sửa đổi thông điệp và khẩu hiệu của website năm 2018; cùng cấu trúc Performance, Reliability và Productivity trên trang đầu tại thời điểm sửa đổi cuốn sách này. Chúng ghi lại nội dung và sự thay đổi của thông điệp chính thức, không đo hiệu ứng đối với người tiếp nhận hay tần suất diễn ngôn trên toàn cộng đồng.  2 3

  31. Rust Core Team, Laying the foundation for Rust’s futureNext steps for the Foundation Conversation; Rust Foundation, Hello World!; Rust Project, Governance. Các nguồn năm 2020 mô tả sự hỗ trợ tài chính và pháp lý của Mozilla, mục đích thành lập Foundation và ranh giới nhằm duy trì quyền ra quyết định của phần lớn các nhóm Rust; nguồn ra mắt năm 2021 ghi lại các thành viên sáng lập và cơ cấu hội đồng quản trị tại thời điểm đó. Trang Governance cho thấy cơ cấu quản trị riêng của Dự án Rust tại thời điểm sửa đổi cuốn sách này. Các nguồn này xác nhận hỗ trợ và cấu trúc thể chế, không đo độc lập hiệu ứng đối với niềm tin hay việc áp dụng từ bên ngoài.  2 3 4

  32. Rust Project, Code of conductLearn Rust; The Rust Programming Language, The Rust Programming Language. Bộ quy tắc ứng xử nêu các chuẩn mực hành vi và thủ tục moderation áp dụng cho không gian Rust chính thức, còn trang học tập và Book cho thấy sự tồn tại và phạm vi của các tài nguyên học tập chính thức. Chỉ riêng sự tồn tại của chúng không được xem là phép đo cho hành vi của toàn bộ cộng đồng, việc giảm rào cản gia nhập, kết quả học tập hay khả năng duy trì người đóng góp. 

  33. The Rust Reference, Influences; The Rust Programming Language, What Is Ownership?References and Borrowing; C++ Core Guidelines, C++ Core Guidelines. Rust Reference liệt kê references, RAII, smart pointers và move semantics của C++ như ảnh hưởng trực tiếp, đồng thời liệt kê riêng region-based memory management của ML Kit và Cyclone. Rust Book giải thích quan hệ giữa mẫu giải phóng tài nguyên bằng drop khi kết thúc scope với RAII của C++, còn C++ Core Guidelines định nghĩa quản lý tài nguyên tự động bằng RAII và resource handle. Các nguồn này được dùng để xác nhận ảnh hưởng lịch sử và vị trí cưỡng chế của từng kỹ thuật, không dùng để quy phát minh đầu tiên của khái niệm “ownership” nói chung cho một ngôn ngữ cụ thể.  2 3 4 5

  34. Ada Resource Association, Ada 83 Rationale, LRM, & Guides; Ada Reference Manual, Introduction; Ada 95 Rationale, Part Two, Chapter 3; Altran Praxis/AdaCore, SPARK - The SPADE Ada Kernel; SPARK User’s Guide, Applying SPARK in Practice; AdaCore, Programming Languages for Space Software. Tài liệu Ada ghi lại chuẩn 1983, các mục tiêu ban đầu về độ tin cậy, khả năng bảo trì và hiệu quả, cùng truyền thống kiểm tra runtime đối với type/subtype; tài liệu SPARK cũ ghi rằng SPARK ban đầu dựa trên Ada 83. Tài liệu SPARK hiện tại giải thích phạm vi và giả định của AoRTE và contract proof, còn phần tổng quan hiện tại của AdaCore nêu rõ SPARK pointer support được bổ sung về sau dựa trên Rust ownership model. Vì vậy, chú thích này dùng Ada/SPARK để phân biệt so sánh lịch sử và phạm vi xác minh, thay vì xem nó là tổ tiên trực tiếp của Rust ownership.  2

  35. The Rust Reference, Influences; Rust standard library, OptionResult; OCaml, Options. Điều Rust Reference trực tiếp nêu là ảnh hưởng từ algebraic data types, pattern matching và type inference của SML/OCaml. Tài liệu chính thức của Rust và OCaml lần lượt cho thấy cấu trúc variant của Option/Resultoption, nhưng chỉ các nguồn này không xác lập một dòng trực tiếp cho API xử lý lỗi cụ thể của Rust hay cho toàn bộ xử lý lỗi đơn nguyên.  2

  36. The Rust Reference, Behavior considered undefined. Tài liệu này liệt kê data race, truy cập qua pointer dangling hoặc misaligned, vi phạm aliasing, gọi với ABI sai và tạo invalid value trong các ví dụ về UB, đồng thời quy định rằng UB tự nó vẫn không được phép ngay cả bên trong unsafe. Tài liệu cũng mô tả ranh giới soundness theo thuộc tính rằng safe client không thể gây UB khi safe code tương tác với phần hiện thực unsafe 2

  37. The Rust Reference, Array and array index expressionsThe unsafe keyword. Indexing array và slice thông thường thực hiện kiểm tra biên runtime khi không thể xác định tĩnh và panic khi thất bại, trong khi hàm unsafe như get_unchecked yêu cầu caller đáp ứng safety condition bổ sung rằng index phải nằm trong phạm vi. 

  38. The Rust Reference, The unsafe keywordBehavior considered undefined. Reference giải thích rằng unsafe fn, unsafe trait và các cấu trúc tương tự định nghĩa safety condition bổ sung, còn unsafe block và unsafe impl biểu thị proof obligation rằng những điều kiện đó đã được đáp ứng. Tài liệu cũng định nghĩa mã unsafe là sound khi safe client không thể dùng nó để gây UB.  2

  39. The Rust Reference, External blocksApplication binary interface. External block là ranh giới khai báo foreign item và Rust 2024 Edition yêu cầu unsafe extern. Rust định nghĩa nhiều ABI gồm "C", "system""C-unwind"; việc xác minh ABI và signature khớp với hợp đồng thực tế của mã bên ngoài là trách nhiệm riêng tại ranh giới đó.  2

  40. Cargo Reference, Profiles: panic; Rust standard library, std::panic::catch_unwind, UnwindSafe, JoinHandle::join; The Rust Reference, Destructors. Các nguồn này mô tả khác biệt giữa chiến lược unwind và abort, giới hạn rằng catch_unwind chỉ bắt unwinding panic, phạm vi có thể quan sát thread panic qua join, và ranh giới rằng soundness không được phụ thuộc vào việc destructor nhất thiết phải chạy.  2 3

  41. The Rust Reference, Behavior not considered unsafe; Rust standard library, std::mem::forget; The Rust Programming Language, Reference Cycles Can Leak Memory. Các nguồn này nêu rõ leak và việc destructor không chạy không đồng nhất với phạm trù unsafe của Rust, và Safe Rust vẫn có thể rò rỉ tài nguyên qua reference cycle hoặc mem::forget 2 3

  42. The Rust Reference, Behavior not considered unsafe; Cargo Reference, Profiles: overflow-checks. Reference phân biệt deadlock, memory/resource leak và việc kết thúc mà không chạy destructor với unsafe. Tài liệu cũng giải thích rằng khi debug_assert! được bật, kiểm tra overflow phải panic, còn ở build khác phần hiện thực có thể panic hoặc wrapping two’s-complement đã được định nghĩa; Cargo profile điều khiển kiểm tra overflow runtime bằng thiết lập overflow-checks 2

  43. The Rustonomicon, Data Races and Race Conditions. Tài liệu phân loại data race là UB, đồng thời nêu rõ Safe Rust không ngăn race condition nói chung. 

  44. Rust Security Response WG, Security advisory for the standard library (CVE-2024-24576)Security advisory for the standard library (CVE-2024-43402). Advisory đầu ghi lại các điều kiện khiến Command escape argument không đầy đủ khi thực thi Windows batch file và bản sửa trong Rust 1.77.2; advisory thứ hai ghi lại một cách vượt qua cụ thể của biện pháp giảm thiểu đó và bản sửa bổ sung trong Rust 1.81.0. Hai trường hợp chỉ được dùng như ví dụ có giới hạn rằng logical/security contract của safe API khác với memory safety, không phải để đo tần suất khiếm khuyết memory-safety.  2

  45. Martin Fowler, Definition Of Refactoring, 2004. Fowler định nghĩa refactoring là thay đổi cấu trúc bên trong mà không thay đổi hành vi quan sát được. Định nghĩa này được dùng để phân biệt thay ngôn ngữ và hiện thực mới với refactoring theo nghĩa hẹp.  2

  46. C++ Core Guidelines project, C++ Core Guidelines; LLVM/Clang, Clang-Tidy, AddressSanitizer, ThreadSanitizerUndefinedBehaviorSanitizer. Core Guidelines mô tả các quy tắc resource, memory và concurrency của C++ hiện đại cùng cách áp dụng dần; tài liệu Clang mô tả phạm vi chẩn đoán và chi phí instrumentation của các phân tích và sanitizer tương ứng. Tài liệu AddressSanitizer và ThreadSanitizer đều nêu rằng runtime của chúng không được thiết kế để liên kết vào production executable và không được phát triển dưới các ràng buộc nhạy cảm bảo mật. Các nguồn này được dùng để không đồng nhất phát hiện dựa trên công cụ với bảo đảm cấp ngôn ngữ, hay instrumentation kiểm thử với triển khai production.  2 3

  47. Android Open Source Project, Memory safety, updated 2026-07-16; Google Security Blog, Rust in the Android platform, 2021; Google Security Blog, Safer with Google: Advancing Memory Safety, 2024. Android kết hợp ngôn ngữ memory-safe cho native code mới với phát hiện và hardening cho C/C++ hiện có, cùng sandbox và hardware mitigation. Trường hợp này được dùng như ví dụ giới hạn ở một nền tảng lớn để cho thấy chiến lược hỗn hợp là khả thi, không phải bằng chứng đó là chiến lược tối ưu cho mọi cơ sở mã.  2 3

  48. Martin Fowler, Strangler Fig, 2024 update. Bài viết mô tả khó khăn thực tế trong việc khám phá đặc tả chi tiết của một hệ thống quan trọng hiện có và rủi ro của cut-over lớn, rồi đưa thay thế dần như một design pattern. Nguồn này được dùng để định nghĩa một lựa chọn chiến lược thay đổi, không phải bằng chứng ở cấp quần thể rằng di chuyển dần luôn có chi phí thấp hơn hoặc chất lượng cao hơn viết lại toàn bộ. 

  49. Google Security Blog, Rust/C++ interop in the Android Platform, 2021; Google Security Blog, Deploying Rust in Existing Firmware Codebases, 2024. Nguồn thứ nhất phân tích interop như một yêu cầu thực tiễn mà không giả định viết lại toàn bộ C++ trong Android; nguồn thứ hai mô tả áp dụng Rust dần, ưu tiên mã mới và rủi ro cao, đồng thời giữ C API qua shim. Nguồn thứ nhất giới hạn rõ phạm vi phân tích ở Android platform, nên cần bằng chứng bổ sung trước khi khái quát chiến lược sang cơ sở mã khác. 

  50. Google Security Blog, Bare-metal Rust in Android, 2023. Nhóm Android ghi lại việc viết lại protected-VM firmware của AVF bằng Rust. Trường hợp này được dùng như ví dụ giới hạn về một bounded rewrite được chọn tại ranh giới bảo mật cụ thể, không phải bằng chứng biện minh viết lại toàn bộ Android hay hệ thống legacy lớn nói chung. 

  51. AdaCore, SPARK User’s Guide 27.0w — Levels of Software AssuranceProve Absence of Run-Time Errors. Tài liệu phân biệt Stone, Bronze, Silver, Gold và Platinum là các verification objective khác nhau, nêu rõ Storage_Error không thuộc phân tích Silver AoRTE, và giải thích Platinum phụ thuộc vào việc contract bao phủ đầy đủ functional requirement.  2 3

  52. Ada Resource Association, Ada 2022 Reference Manual, đặc biệt 11.5 Suppressing Checks, 11.4 Exception Handling, 9 Tasks and Synchronization, C.6 Shared Variable Control, và 13.9.1 Data Validity. Ada 2022 Reference Manual tương ứng ISO/IEC 8652:2023(E). Các nguồn này được dùng để phân biệt thất bại của language-defined check và exception semantics, ranh giới erroneous-execution do check suppression tạo ra, cùng giới hạn của atomic/protected synchronization và unchecked access.  2 3 4

  53. AdaCore, SPARK User’s Guide 27.0w — Managing AssumptionsHow to Write Subprogram Contracts. Kết quả GNATprove có thể phụ thuộc modular contract và assumption về code chưa phân tích hoặc external environment; tài liệu yêu cầu biện minh riêng các assumption này bằng testing, manual analysis, review hoặc bằng chứng phù hợp khác.  2 3

  54. AdaCore, SPARK User’s Guide 27.0w — Concurrency and Ravenscar Profile. Tài liệu hạn chế tasking để tránh erroneous concurrent access vào shared data, tức data race, nhưng ví dụ atomic read-modify-write nêu rõ lost-update race condition vẫn có thể tồn tại mà không có data race. Tài liệu cũng mô tả Priority Ceiling Protocol cho protected-object locking của Ravenscar single-core để bảo đảm không deadlock, và giải thích GNATprove kiểm tra potentially blocking action cùng nhiều hạn chế tasking. Đồng thời, tài liệu ghi lại giới hạn hiện thực rằng project-wide tasking analysis hiện tại phụ thuộc with closure của source file đang xử lý và có thể bỏ sót check liên quan trong một số cấu hình library/task tách rời. Vì vậy không mở rộng bảo đảm data-race/deadlock đã tài liệu hóa thành general concurrency correctness hay whole-system guarantee bên ngoài context được phân tích.  2

  55. Microsoft, Fundamentals of garbage collectionDebug a memory leak; Go Project, A Guide to the Go Garbage Collectorruntime.AddCleanup. Tài liệu Microsoft mô tả managed reachability, retained-object leak và đường Dispose rõ ràng cho unmanaged resource; tài liệu Go mô tả thu hồi dựa trên reachability và ranh giới rằng cleanup có thể bị trì hoãn tùy ý hoặc không chạy. Vì vậy, mục này không mở rộng GC-managed memory reclamation thành deterministic resource-release contract.  2

  56. Go Project, Go 1.26 Release NotesA Guide to the Go Garbage Collector; Oracle, Java SE 26 HotSpot VM Garbage Collection Tuning Guide — Available Collectors, Garbage-First (G1) Garbage Collector, Ergonomics; Microsoft, .NET GC latency modes. Go GC guide nêu rõ implementation detail có thể thay đổi theo phiên bản, còn release note Go 1.26 ghi Green Tea là collector mặc định hiện tại. Mục này vì vậy dùng các phạm vi cost/latency đã được tài liệu hóa và trade-off riêng của từng collector thay cho một con số pause cố định cũ. Cùng với tài liệu Oracle và Microsoft, các nguồn này cũng được dùng để phân biệt pause-time goal với hard deadline.  2 3 4

  57. Oracle, Java SE 26 G1 Garbage CollectorErgonomics; Microsoft, .NET GC latency modes; Go Project, A Guide to the Go Garbage Collector — Latency. Ba nguồn lần lượt cho thấy tính xác suất/heuristic của pause-time goal, ranh giới memory-pressure của low-latency mode và các latency source vẫn còn trong concurrent GC. Mục này không mở rộng chúng thành bảo đảm hard real-time ở cấp application. 

  58. Ví dụ định tính về diễn ngôn công khai gồm thảo luận trải nghiệm backend/Rust trên Reddit r/rust, thảo luận lỗi soundness unsafethảo luận về memory leak trong dịch vụ chạy dài hạn trên Rust Users Forum. Các ví dụ này chỉ dùng để cho thấy sự tồn tại và cấu trúc của lập luận; không có thiết kế lấy mẫu nên chúng không được dùng để ước lượng tần suất, tính đại diện hay đồng thuận của toàn cộng đồng Rust.  2 3 4 5 6 7 8 9 10 11 12

  59. Rust Project, trang chính thức — Why Rust?rust-lang/rust README — Why Rust?. Trang chính thức hiện tại và phần giới thiệu kho mã mô tả Rust như công cụ giúp mọi người xây dựng reliable and efficient software, đồng thời trình bày performance, reliability và productivity như các đề xuất giá trị riêng. Ở đây không mở rộng chúng thành tuyên bố về quyền ưu tiên khái niệm hay ưu thế phổ quát. 

  60. Rust Project, The unsafe keyword, Behavior considered undefined, Behavior not considered unsafe, std::mem::forget. Reference mô tả unsafe là việc tạo hoặc hoàn tất (create or discharge) proof obligation và định nghĩa unsafe abstraction mà qua đó safe client có thể gây UB là unsound. Reference cũng không xem leak hay destructor không chạy là unsafe, và mem::forget là safe API vì ranh giới bảo đảm này.  2 3

  61. ISO/IEC JTC1/SC22/WG21, N1128 — auto_ptr proposal wording, 1997, N4168 — Removing auto_ptr, N3245 — C++ Standard Library Active Issues List, 2011, N3296 — C++ FCD Comment Status. N1128 ghi lại auto_ptr trước C++11 và strict-ownership transfer semantics của nó; N4168 ghi nhận việc chấp nhận hướng N1856 năm 2007, theo đó thêm hướng unique_ptr và deprecate auto_ptr; tài liệu ủy ban năm 2011 cho thấy unique_ptrshared_ptr trong thiết kế thư viện chuẩn thời C++11. Các nguồn này dùng để xác lập niên biểu và bối cảnh tiêu chuẩn hóa, không dùng để chứng minh dòng dõi nhân quả từ một smart pointer C++ cụ thể tới Rust. 

  62. C++ Core Guidelines, Resource management; ISO/IEC JTC1/SC22/WG21, N3025 — Specifying Pointer-Like Requirements; The Rust Programming Language, What Is Ownership?; thư viện chuẩn Rust, std::rc::Rcstd::sync::Arc. Các nguồn này hỗ trợ so sánh ngữ nghĩa giữa exclusive ownership, move semantics, moved-from unique_ptr state, RAII và reference-counted shared ownership. Chúng không được dùng làm bằng chứng rằng unique_ptr hay shared_ptr là tổ tiên lịch sử một-một của một kiểu Rust hoặc của toàn bộ Rust ownership.  2

  63. The Rust Programming Language, What Is Ownership?, References and Borrowing, Unsafe Rust; The Rust Reference, The unsafe keyword, Behavior considered undefined. Các nguồn này xác lập ownership/borrowing rule được compiler kiểm tra, các operation hữu hạn được unsafe cho phép, việc các kiểm tra thông thường vẫn có hiệu lực trong unsafe code, và proof/soundness obligation còn lại ngoài compiler verification. Rust Reference cũng nêu rõ các proof obligation như vậy có thể được discharge bằng run-time check hoặc data-structure invariant; vì thế thuật ngữ này không được dùng ở đây làm bằng chứng cho machine-checked formal proof.  2 3

  64. The Rust Reference, The unsafe keyword; The Rust Programming Language, Unsafe Rust, RefCell<T> and the Interior Mutability Pattern; The Rustonomicon, Splitting Borrows; thư viện chuẩn Rust, RefCell, Result::unwrap. Tài liệu Rust mô tả rõ type system như một xấp xỉ bảo thủ trong ngữ cảnh này, trình bày safe abstraction dùng unsafe implementation để xác lập disjointness mà borrow checker không trực tiếp suy ra, ghi lại run-time borrow checking của RefCell, phân biệt borrow/borrow_mut gây panic với try_borrow/try_borrow_mut không panic và trả lỗi, đồng thời quy định unwrap() panic khi gặp Err. Các nguồn này không xác lập quan hệ nhân quả về developer psychology hay defensive-programming behavior.  2 3

  65. C++ Core Guidelines, I.11: Never transfer ownership by a raw pointer or reference, R.20: Use unique_ptr or shared_ptr to represent ownership, R.32: Take a unique_ptr<widget> parameter to express that a function assumes ownership. Guidelines mô tả việc áp dụng từng bước và sự kết hợp giữa language/library semantics với tool-enforced guidance; chúng cũng nói parameter unique_ptr vừa ghi nhận vừa enforce ownership transfer. Các nguồn này được dùng để so sánh enforcement scope, không để khẳng định C++ và Rust cung cấp default memory-safety guarantee tương đương.  2

  66. Rust standard library, std::collections::LinkedListlinked_list module; The Rust Programming Language, Reference Cycles Can Leak Memory. Tài liệu thư viện chuẩn mô tả safe doubly linked list với owned node và lưu ý Vec hoặc VecDeque thường nhanh hơn, hiệu quả bộ nhớ hơn và cache-friendly hơn. Rust Book ghi lại strong Rc cycle có thể gây memory leak và Weak không biểu đạt ownership nên có thể phá ownership cycle. Các nguồn này không được dùng để khẳng định một representation là tối ưu phổ quát.  2 3

  67. AdaCore, SPARK User’s Guide 27.0w — Language Restrictions, Memory Ownership Policy, Pointer Support, Ownership, and Dynamic Memory Management, Applying SPARK in Practice. Các nguồn này ghi lại ownership-based restriction của SPARK đối với access value, moving/borrowing/observing semantics, và hạn chế hiện tại rằng pointer-based structure có cycle hoặc sharing nhìn chung nằm ngoài supported ownership pattern; guide nêu cụ thể sự đối chiếu giữa linked list/tree được hỗ trợ với conventional doubly linked list/DAG không được hỗ trợ.  2

  68. AdaCore, SPARK User’s Guide 27.0w — Formal Containers Library, Applying SPARK in Practice — Pointer-Based Data Structures. Guide khuyến nghị SPARK container abstraction như một lựa chọn thay thế pointer-intensive structure khi thực tế cho phép, cung cấp cả SPARK.Containers.Formal.Doubly_Linked_ListsSPARK.Containers.Formal.Unbounded_Doubly_Linked_Lists, phân biệt bounded formal container không dùng dynamic allocation với unbounded variant có dùng dynamic allocation, và nói rõ GNATprove có thể proof client use đúng theo SPARK-visible contract nhưng không vì thế chứng minh non-SPARK private implementation thỏa specification. Các điểm này tách explicit pointer-graph restriction khỏi container-level availability và giữ library implementation như một trust/verification boundary riêng.  2 3 4

  69. The Rust Programming Language, What Is Ownership?, References and Borrowing, và Validating References with Lifetimes; The Rust Reference, Borrow operatorsPointer types — References. Các nguồn này xác lập hành vi move/copy và borrowing, quy tắc về tính hợp lệ của tham chiếu, shared so với mutable borrow, cùng việc chú thích lifetime biểu đạt quan hệ thay vì thay đổi thời gian tham chiếu thực sự sống. Chúng cũng ghi lại lifetime inference/elision. Chú thích này chỉ hỗ trợ hành vi ngôn ngữ/trình biên dịch, không xác lập hiệu ứng lên năng suất nhà phát triển.  2

  70. Shuofei Zhu et al., Learning and Programming Challenges of Rust: A Mixed-Methods Study, ICSE 2022; Will Crichton, Gavin Gray, and Shriram Krishnamurthi, A Grounded Conceptual Model for Ownership Types in Rust, OOPSLA 2023; Will Crichton and Shriram Krishnamurthi, Profiling Programming Language Learning, OOPSLA 2024; Rust Survey Team, 2024 State of Rust Survey Results. Nghiên cứu ICSE kết hợp phân tích thủ công 100 câu hỏi Stack Overflow với survey 101 Rust programmer. Các nghiên cứu OOPSLA đo hiểu biết ownership và hành vi học trong các quần thể độc giả cụ thể; initial deployment năm 2023 báo cáo chênh lệch trung bình 9% về Ownership Inventory so với original version (N = 342, d = 0.56), còn nghiên cứu 2024 phân tích 62.526 độc giả và 1.140.202 câu trả lời quiz, báo cáo cải thiện trung bình 20% ở câu hỏi mục tiêu sau mười hai can thiệp. 2024 State of Rust survey có 7.310 câu trả lời hoàn chỉnh, khoảng 92% người trả lời tự nhận là người dùng Rust, khoảng 31% người không dùng nêu perceived difficulty là lý do chính không dùng Rust, và 53% tự đánh giá mình có thể dùng Rust ở mức productive. Đây là kết quả survey self-selected, hướng tới Rust, không phải ước lượng trực tiếp năng suất cấp tổ chức hay quần thể nhà phát triển nói chung.  2 3

  71. Rust Project, Rust Survey 2021 Results, 2025 State of Rust Survey Results, Lessons learned from the Rust Vision Doc process, và The many journeys of learning Rust. Các tỷ lệ áp dụng tại nơi làm việc năm 2021 — 83% gọi việc áp dụng là challenging, 13% báo cáo Rust làm đội chậm trong giai đoạn áp dụng và 82% nói Rust giúp đội đạt mục tiêu — là self-report của người trả lời chứ không phải so sánh ngôn ngữ có kiểm soát. Survey 2025 thu 7.156 câu trả lời và cảnh báo rõ không ngoại suy quá mức từ khoảng bảy nghìn câu trả lời và các mẫu số nhỏ hơn của câu hỏi tùy chọn; nó báo cáo slow compile time/storage usage và debugging trong các vấn đề productivity đáng kể. Vision Doc process thu hơn 4.200 câu trả lời survey và hơn 70 interview, tập trung chủ yếu vào individual developer experience thay vì đo toàn công ty, đồng thời ghi nhận selection bias, đặc biệt khó tiếp cận người đã từ chối hay ngừng dùng Rust. Các ví dụ hành trình học xác lập biến thiên định tính và những pattern hỗ trợ có thể có, không phải tần suất, thời gian ramp-up chuẩn hay hệ số nhân quả của năng suất cấp tổ chức.  2

  72. Abraham Kaplan, The Conduct of Inquiry: Methodology for Behavioral Science, Chandler Publishing Company, 1964; Abraham H. Maslow, The Psychology of Science: A Reconnaissance, Harper & Row, 1966. Thảo luận của Kaplan và phép ví von hammer của Maslow hỗ trợ việc dùng familiarity như một cảnh báo phương pháp luận về cách xác định vấn đề. Chúng không phải nghiên cứu quần thể software developer và không phải bằng chứng rằng học Rust gây ra việc mở rộng phạm vi áp dụng Rust. 

  73. Len Bass, Paul Clements, and Rick Kazman, Software Architecture in Practice, 3rd Editionsample chapter của publisher, “Choice of Technology,” p. 76. Thảo luận technology choice của họ nêu rõ công nghệ và tool sẵn có, familiarity nội bộ, external support, side effect và compatibility với stack hiện có; architecture framework cũng coi quality attribute và constraint là đầu vào thiết kế. Nguồn này hỗ trợ tiêu chí lựa chọn đa chiều, không phải xếp hạng programming language. 

  74. Rust Survey Team, 2024 State of Rust Survey Results. Survey nhận 7.310 câu trả lời hoàn chỉnh; khoảng 92% người trả lời self-identify là Rust user và Rust project lưu ý survey chủ yếu nhắm tới Rust developer hiện có. Trong người trả lời dùng Rust tại nơi làm việc, 21% nói họ dùng vì đã biết Rust và do đó coi nó là default choice; báo cáo cũng mô tả server backend, web/networking service và cloud technology là các technology domain đặc biệt phổ biến trong survey. Kết quả này mô tả mẫu survey hướng tới Rust; không xác lập tool bias phi lý, backend market share, năng suất so sánh hay tính phù hợp phổ quát.  2

  75. Rust Project, The Rust Reference — Functions: Async functions, std::future::Future, và Asynchronous Programming in Rust — Why Async?. Các nguồn này xác lập rằng async call trả về future, Future::poll là execution interface, Rust không cung cấp built-in async runtime, và Rust async có thể tránh việc heap allocation cùng dynamic dispatch là bắt buộc. Chúng không xác lập total runtime cost của application bằng không. 

  76. Rust Project, Asynchronous Programming in Rust — Pinningstd::pin. Tài liệu giải thích address sensitivity trong compiler-generated future, Pin contract và các low-level case nơi pinning lộ ra; đồng thời nêu rõ người dùng async/await thông thường thường không cần trực tiếp xử lý pinning. 

  77. Rust Survey Team, 2024 State of Rust Survey Results; Rust Project, 2025 March Project Goals Update2026 Project Goals. Open answer của survey nhắc khó khăn với async programming và debuggability, còn project-goal record chứa công việc tiếp tục về async ergonomics và Pin. Các tài liệu này xác lập những lĩnh vực công việc được nhìn nhận, không phải controlled estimate về tần suất hay comparative developer productivity. 

  78. Rust Project, Asynchronous Programming in Rust — Why Async?; Tokio, tokio::runtimetokio::sync. Các nguồn cho thấy cả hai phía của boundary: Rust không cung cấp built-in runtime; Tokio gộp scheduler, I/O driver và timer service, trong khi nhiều synchronization primitive của Tokio là runtime-agnostic và một số operation phụ thuộc timer thì không. Do đó runtime coupling phải được đánh giá theo từng API chứ không suy từ toàn ecosystem. 

  79. Rust Project, The Rust Reference — External blocks: Functions, Functions: Async functions, và std::future::Future. Foreign declaration trong external block không nhận async qualifier, còn Rust async function tạo future có poll interface dùng PinContext riêng của Rust. Những sự thật này xác lập nhu cầu về cross-language async protocol rõ ràng; chúng không có nghĩa chỉ blocking hoặc callback bridge mới khả thi. 

  80. Rust Project, 2026 Project GoalsAsync Future Memory Optimisation. Công việc được chấp nhận năm 2026 gồm async future memory và state-machine optimization. Memory-optimization goal ghi lại nested-future layout lớn và báo cáo lo ngại về stack overflow cùng môi trường cloud, embedded, kernel bị giới hạn memory. Đây là project problem statement và engineering evidence về implementation limit đang được xử lý, không phải population-wide benchmark của mọi async Rust program. 

  81. The Go Project, The Go Programming Language Specification — Go statements, và Rust Project, The Rust Reference — Async functions. Specification xác lập execution model khác nhau: go statement của Go bắt đầu goroutine, còn Rust async function trả future tiến triển khi được poll. Tự chúng không xác lập comparative latency, memory use, debugging difficulty hay developer productivity. 

  82. Rust Project, core::result, #[must_use], và rustc unused_must_use lint. Resultmust_use; bỏ qua mặc định tạo warning, có thể được lint policy nâng thành error nhưng không phải hard error nội tại trong mọi program. 

  83. Rust Project, The Rust Reference — try propagation expressioncore::result. ? trên Result early-return ở Err và dùng From::from để chuyển residual.  2

  84. Oracle, Java Language Specification, Java SE 26 — Chapter 11, đặc biệt §11.2. Checked exception phải được catch hoặc declare; RuntimeExceptionError là unchecked. 

  85. Haskell 2010 Language Report, Microsoft F# — ResultsDiscriminated Unions. Các nguồn xác lập ADT tương tự trước Rust, không xác lập ảnh hưởng trực tiếp tới Rust. 

  86. Rust Project, Panic, catch_unwind, và Cargo Profiles: panic. Các nguồn phân biệt unwind/abort, cleanup, recovery boundary, target limit và profile policy. 

  87. Matthew Prince, “Cloudflare outage on November 18, 2025”, 2025-11-18. Postmortem ghi nhận duplicated feature metadata, 200-feature limit và Rust panic do Result::unwrap(); không đo hành vi unwrap trong toàn bộ production Rust. 

  88. Rust Project, Cargo — Specifying DependenciesSemVer Compatibility. Cargo dùng left-most non-zero component; initial-development rule là convention chứ không phải hard guarantee. 

  89. Rust Project, Cargo — Publishing on crates.io. Tài liệu mô tả nhiều owner và cargo yank; yank loại version khỏi resolution mới mà không xóa hoặc phá lockfile cũ. 

  90. Rust Secure Code Working Group, RustSec Advisory Database. Advisory và cargo-audit hỗ trợ vulnerability management nhưng không chứng nhận chất lượng tổng thể của crate. 

  91. Rust Survey Team, 2025 State of Rust Survey Results. 7.156 response, giới hạn ngoại suy và concern về maintainer support không cung cấp registry-wide bus factor. 

  92. Rust Project Vision Doc group, “What we heard about Rust’s challenges”“Lessons learned from the Rust Vision Doc process”. Bài thứ hai ghi nhận khoảng 4.200 phản hồi survey, hơn 70 interview, selection bias do khó tuyển đủ người hoài nghi Rust, và giới hạn rằng dữ liệu chưa đủ để trả lời một số câu hỏi ưu tiên cụ thể theo domain. Original version của bài thứ nhất đã bị rút lại; trang hiện tại trình bày các high-level challenge mà nhóm xác định từ khoảng 70 interview kèm brief personal commentary và cảnh báo rõ rằng các statements này biased hơn mức Vision Doc thường mong muốn. Trang vẫn nêu crate discovery/trust và coverage chưa trưởng thành ở một số domain; sách này chỉ dùng chúng như qualitative prompt, không như bằng chứng về registry-wide prevalence, chất lượng trung bình hay ecosystem ranking.  2

  93. Rust Compiler Performance Working Group, “Rust compiler performance survey 2025 results”. Hơn 3.700 self-selected response mô tả mixed build experience, mean 6/10, selected-workload rebuild và IDE/CI; thiết kế câu hỏi giới hạn suy luận.  2 3

  94. Rust Compiler Development Guide, “Monomorphization”“Overview of the compiler”. Concrete generic instance có compile/binary cost nhưng chỉ là một stage của compiler pipeline.  2

  95. Rust Compiler Team, “Rust debugging survey 2026”. Nêu quality variation theo tool/OS và mục tiêu visualizer, async, expression evaluation; không phải nghiên cứu comparative productivity. 

  96. Rust Project, Cargo — Build Scripts. Tài liệu nêu C build, native library, generated module, platform configuration và change detection. 

  97. Rust Project, Cargo — Features, Workspaces, và Optimizing Build Performance. Các tài liệu mô tả feature/resolver, shared workspace state và build trade-off. 

  98. Rust Compiler Performance Working Group, “Rust compiler performance survey 2025 results”; Rust Compiler Team, “Rust debugging survey 2026”. Các nguồn xác lập current build/editor observation và debugging goal trong inference limit tương ứng, không xác lập maturity ranking chung so với Java/C# hay IDE cụ thể.  2

  99. Rust Project, The Rust Programming Language — Performance in Loops vs. IteratorsThe Embedded Rust Book — Zero Cost Abstractions. Ví dụ iterator định nghĩa zero-cost theo việc không thêm runtime overhead và tự nêu giới hạn benchmark; ví dụ embedded cho thấy zero-sized typestate bị xóa ở runtime. Không nguồn nào xác lập zero total lifecycle cost. 

  100. Alpine Linux, Alpine 3.24.1 released, 2026-06-13, and the official v3.24 stable x86_64 package repositories. Measurement date: 2026-08-28. The measured APKs were busybox-1.37.0-r31.apk (SHA-256 0e626fa97cf937fda7bba4ed4dde8e2f2dbb5083ac34e02180cec0c4eba9351b), coreutils-9.11-r0.apk (18710a17a606d2454491d7e5b6114776c2ea861633234efdaee5b85fad5f2434), and uutils-0.9.0-r0.apk (4dfdc5be7b31965765b21573ea53fce49a0765db83b822ae8d6911ee9437e1b8). After extraction, file identified /bin/busybox, /bin/coreutils, and /bin/uutils as stripped dynamically linked x86-64 PIE executables; file sizes were measured directly from those ELF files. uutils-coreutils is a metapackage depending on uutils, so it was not used as the measured implementation. The snapshot does not normalize command coverage or shared-library dependency closure. 

  101. Rust Project, The rustc book — prefer-dynamicThe Rust Reference — Linkage. rustc mặc định ưu tiên static dependency linkage nhưng có thể ưu tiên dynamic khi available; Reference định nghĩa rlib, Rust dylib, system staticlibcdylib

  102. Rust Project, The Rust Reference — External blocks: ABIType layout. extern "Rust" không có stability guarantee và default Rust representation có layout guarantee giới hạn; extern "C"repr(C) cung cấp interoperability boundary rõ ràng. Điều này không có nghĩa dynamic Rust library không được hỗ trợ.  2 3 4

  103. Rust Project, The Cargo Book — Profiles. Cargo mô tả s/z, debuginfo/strip, LTO, codegen-units, panic control cùng compile/link/runtime trade-off và cảnh báo size-oriented optimization không nhất thiết nhỏ hơn với mọi program. 

  104. Rust Project, The Rust Reference — no_std, alloc, và The Embedded Rust Book — A no_std Rust Environment. no_std dùng core; khi có allocator, alloc cung cấp Vec, Box, String, còn startup, panic handling, allocator và platform integration vẫn là trách nhiệm của environment. 

  105. Linux Kernel documentation, Rust Quick Start, documents CONFIG_RUST, the rust/ support code, samples/rust/, the complete LLVM setup as the best-supported build configuration, and GCC support for some configurations as very experimental. Direct inspection of the official Linux 7.2.1 stable source snapshot used for the cloc measurement also found Rust Binder under drivers/android/binder/ and Rust GPU drivers under drivers/gpu/drm/nova/ and drivers/gpu/drm/tyr/; the Nova and Tyr Kconfig help text marks them work in progress and potentially non-functional.  2

  106. Linux Kernel Archives, kernel.org, stable Linux 7.2.1, 2026-08-27. Measurement date: 2026-08-30. Artifact: linux-7.2.1.tar.xz, SHA-256 4158098c8a28ea8fbe068c855d3aa6341e03d06282add3cb9049f3a24e4557b3. Tool: Debian APT package cloc 2.04-1 (cloc v2.04). Procedure: extract the official tarball and run cloc . without additional options at the source root. The command reported 82,371 unique files, 30,518,591 total code lines, and 114,481 Rust code lines. This is a source-tree composition measurement, not a runtime-use, binary-size, defect-rate, or production-adoption metric.  2

  107. Linux kernel CVE record as reproduced by NVD, CVE-2025-68260, and the upstream fix 3e0ae02ba831da2b707905f4e602e43f8507b8cc. The record describes an unsafe removal from Rust Binder’s death_list, a concurrent list-access race and pointer corruption, and records Linux 6.18 as affected with 6.18.1 and 6.19-series fixes. It supports the specific unsafe-boundary failure analysis, not a defect-rate comparison between Rust and C kernel code.  2 3

  108. Ferrous Systems, Ferrocene Part 3: The Road to Rust in mission- and safety-critical, 2021; AdaCore, AdaCore and Ferrous Systems Joining Forces to Support Rust, 2022, và Announcements around Rust, 2023; Ferrous Systems, Officially Qualified - Ferrocene, 2023; Ferrocene, Qualification PlanSafety Manual - Qualification scope; Ferrous Systems, Ferrocene 26.02.0 now available!, 2026. Ferrous Systems công bố Ferrocene năm 2021 cùng công ty con Critical Section GmbH như một dự án qualification ngôn ngữ và compiler Rust cho lĩnh vực an toàn trọng yếu. AdaCore và Ferrous Systems công bố cùng phát triển năm 2022 và chấm dứt quan hệ hợp tác phát triển chung năm 2023. Tài liệu qualification công khai hiện nay ghi lại phạm vi ISO 26262 ASIL D/TCL 3, IEC 61508 class T3 và IEC 62304 của compiler cùng các ràng buộc sử dụng trong Safety Manual. Tài liệu Ferrocene năm 2026 mô tả qualification của TÜV SÜD theo ISO 26262 ASIL D, IEC 61508 SIL 3 và IEC 62304 Class C; đồng thời tách tập con core đã được certification ở ISO 26262 ASIL B và IEC 61508 SIL 2, và mô tả DO-178C DAL C là phạm vi hỗ trợ nỗ lực certification của khách hàng. Điều này không có nghĩa một ứng dụng hay hệ thống riêng lẻ được build bằng Ferrocene tự động nhận certification ở cấp an toàn tương ứng. Ferrous Systems, Ferrocene 26.05.0 now available!, 2026-07-28, cho biết release mới nhất có TÜV SÜD-qualified compiler, certified core subset ở ISO 26262 ASIL B / IEC 61508 SIL 2, customer certification support hướng tới DO-178C DAL C và IEC 61508 SIL 4, cùng thay đổi upstream Rust từ 1.93.0 đến 1.95.0. Evaluation Plan - Qualification Scope trên main công khai liệt kê rustc là qualified tool và các companion development tool là unqualified, nhưng chính trang cảnh báo đây là development-branch preview có thể incomplete/inaccurate. Vì vậy rustc/core 1.99.0 trong Safety Manual/Core Certification cùng nhánh main chỉ được dùng như thông tin scope của next-rolling development snapshot, không phải qualification version của release 26.05.0 đã phát hành.  2 3

  109. Rust Survey Team, 2025 State of Rust Survey Results. Khảo sát thu 7.156 phản hồi và báo cáo số tổ chức dự định tuyển thêm Rust developer tiếp tục tăng, đồng thời cảnh báo không ngoại suy quá mức từ respondent population thiên về Rust và denominator nhỏ hơn của optional question. Nó chứng minh Rust-oriented hiring activity, không phải labor-pool hay wage ranking giữa các ngôn ngữ. Survey 2025 diễn ra từ 17-11 đến 17-12-2025; 9.389 người bắt đầu và 7.156 người hoàn tất (completion 76,2%). Report cảnh báo rõ không thể ngoại suy quá mức từ khoảng 7.000 câu trả lời và denominator của optional question còn nhỏ hơn. Vì vậy hiring graph hỗ trợ một trend trong Rust-oriented population được khảo sát và các tổ chức của họ, không phải census job posting, quy mô toàn bộ labor market hay wage estimate giữa các ngôn ngữ. 

  110. CMU Software Engineering Institute, “The Growing Importance of Sustaining Software for the DoD: Part 1”. Bài viết phân biệt software sustainment với hao mòn vật lý và mô tả thay đổi hardware/environment, requirement, defect và performance như các driver maintenance liên tục.  2

  111. Robert C. Seacord et al., CMU Software Engineering Institute, “Legacy System Modernization Strategies”, CMU/SEI-2001-TR-025. Báo cáo so sánh các phương án modernization cho legacy system lớn, phức tạp thay vì quy định language replacement là default.  2

  112. Google Android Security Team, “Rust in the Android platform”, “Eliminating Memory Safety Vulnerabilities at the Source”, và “Deploying Rust in Existing Firmware Codebases”. Google ghi lại new-code-first, đầu tư interoperability và incremental/drop-in Rust trong low-level codebase hiện hữu thay vì yêu cầu rewrite toàn bộ C/C++ trưởng thành.  2 3

  113. Google, “Rust in Android: move fast and fix things”, 2025, và Google Android Security Team, “Eliminating Memory Safety Vulnerabilities at the Source”, 2024. Report Android 2025 so sánh Rust với C/C++ hoặc C++ trong development/security data của chính Android. Đây là evidence mạnh cho tổ chức và codebase đó, không phải randomized language experiment hay industry-wide estimate. 

  114. Microsoft, “What’s new in Windows 11 Enterprise LTSC 2024”, ghi nhận Rust implementation của GDI region trong win32kbase_rs.sys trên Windows 11 24H2. Điều này chứng minh shipped Windows kernel use case, không phải organization-wide language share hay comparative defect-rate estimate. 

  115. Amazon Web Services, Open Source Security, cho biết Firecracker được viết bằng Rust và hỗ trợ AWS Lambda cùng các serverless offering khác, còn EC2 team dùng Rust cho AWS Nitro System component mới. Đây là production adoption example, không phải universal workload recommendation. 

  116. Emily M. Bender et al., On the Dangers of Stochastic Parrots: Can Language Models Be Too Big?, FAccT 2021; Youssef Mansour and Reinhard Heckel, Measuring Bias of Web-filtered Text Datasets and Bias Propagation Through Training, 2024/2025. Các nguồn này bàn về rủi ro tổng quát và khả năng thực nghiệm rằng thành phần, lọc và phân bố của dữ liệu huấn luyện quy mô Web có thể ảnh hưởng hành vi mô hình. Không nguồn nào đo phân bố diễn ngôn Rust so với Ada/SPARK hoặc độ thiên lệch câu trả lời liên quan đến Rust của một mô hình cụ thể; vì thế cuốn sách không suy ra hiệu ứng khuếch đại LLM đặc thù cho Rust từ các nguồn đó.  2

  117. “Câu chuyện viên đạn bạc (silver-bullet narrative)” trong cuốn sách này là nhãn phân tích mở rộng ẩn dụ “silver bullet” của Frederick P. Brooks Jr. trong No Silver Bullet — Essence and Accidents of Software Engineering, Computer 20(4), 1987, pp. 10-19. Bài báo của Brooks không nghiên cứu Rust hay một cộng đồng công nghệ cụ thể, và bản thân thuật ngữ này không chứng minh tần suất hay nguyên nhân của bất kỳ diễn ngôn Rust nào. Ở đây nó chỉ được dùng để nhận diện lập luận mở rộng một biện pháp cải thiện có điều kiện thành giải pháp duy nhất hoặc phổ quát cho vấn đề phức tạp. 

  118. Rust Project, Governance; Rust RFC Book, Project Goals 2025H1Project Goals 2026; Rust Project Goals, 2026 Overview. Các nguồn này cho thấy thảo luận dựa trên RFC, đề xuất project-goal theo hướng bottom-up và hỗ trợ của team, các giới hạn về nguồn lực và đồng thuận, cùng các công việc cải tiến được nêu rõ như async ergonomics và low-level tooling. Chúng là bằng chứng rằng dự án chính thức công khai xử lý các vấn đề chưa giải quyết và trade-off, không phải bằng chứng đại diện cho thái độ của toàn bộ diễn ngôn Rust phi chính thức.  2 3 4 5

  119. Leon Festinger, A Theory of Cognitive Dissonance, Stanford University Press, 1957; Henri Tajfel and John C. Turner, An Integrative Theory of Intergroup Conflict, bài gốc 1979, bản tuyển tập sau đó năm 2000; Matteo Cinelli et al., The echo chamber effect on social media, PNAS 118(9), 2021. Các nguồn này cung cấp lý thuyết tổng quát và nghiên cứu thực nghiệm về những chủ đề hoặc nền tảng khác, chứ không nghiên cứu cộng đồng Rust. Vì vậy cuốn sách không dùng riêng các nguồn này để xác định động cơ nội tại của người dùng Rust hay sự tồn tại của echo chamber đặc thù cho Rust.  2 3

  120. Open Source Initiative, History of the Open Source Initiative; GNU Project, Free Software MovementWhat is Free Software?. OSI ghi nhận rằng khi tạo nhãn open-source năm 1998, họ muốn phân biệt framing thực dụng/business-case của phát triển cộng tác với framing triết học và chính trị gắn với free software. Tài liệu GNU đặt freedom và community vào các giá trị trung tâm của free software. Các nguồn sơ cấp này được dùng để cho thấy các cộng đồng kỹ thuật liên quan thời đó không thể quy về một value frame duy nhất. 

  121. Eric S. Raymond, The Cathedral and the Bazaar, trình bày lần đầu năm 1997 và được sửa đổi sau đó. Raymond mô tả thế giới phát triển Linux bằng ẩn dụ bazaar, nơi các agenda và approach khác nhau cùng tồn tại. Đây là cách diễn giải đương thời có ảnh hưởng của một người tham gia, không phải mẫu xác suất đại diện cho toàn bộ người dùng Linux thập niên 1990. 

  122. The Jargon File, Version 4.2.2, 20 Aug 2000. Historical lexicon này mô tả hacker culture như một tập hợp các subculture kết nối lỏng lẻo, bàn về slang như biểu hiện của trải nghiệm chung và inclusion/exclusion, đồng thời ghi các cách dùng đương thời của M$RTFM. Nó chứng minh sự tồn tại của hacker slang, không phải mẫu đại diện đo thái độ của toàn bộ người dùng Linux hay tần suất các biểu đạt đó. 

  123. ISRG Prossimo, A Safer High Performance AV1 Decoder, 2023; Stephen Crane and Khyber Sen, Porting C to Rust for a Fast and Safe AV1 Media DecoderOptimizing rav1d, an AV1 Decoder in Rust, 2024; memorysafety/rav1d. Các nguồn chính thức này mô tả việc port C code của dav1d, tái sử dụng native assembly, drop-in C API, mục tiêu upstream synchronization và ranh giới hiệu năng trong quá trình chuyển sang safe Rust.  2 3

  124. ISRG Prossimo, $20,000 rav1d AV1 Decoder Performance Bounty, 2025; rav1d v1.1.0 release, 2025. Nguồn thứ nhất báo cáo khoảng cách khoảng 5% tại thời điểm đó, thay đổi theo benchmark, input và platform, và công bố bounty; nguồn thứ hai ghi lại việc đồng bộ bằng cách backport cải tiến hiệu năng từ dav1d 1.5.1. Đây là dữ kiện hiệu năng và maintenance theo thời điểm, không phải ước lượng khoảng cách hiện tại trên mọi platform. 

  125. Hacker News, Improving performance of original dav1d video decoder, 2025. Thảo luận nêu các câu hỏi về safety scope của assembly tái sử dụng, chi phí backport lặp lại, codec expertise và tính bền vững của support dài hạn. Nguồn này chỉ được dùng như ví dụ định tính cho thấy sự tồn tại và cấu trúc của phê bình công khai; các con số và đánh giá giá trị của người tham gia không được coi là sự kiện nếu chưa kiểm chứng độc lập. 

  126. Antony Flew, Thinking about Thinking: Or, Do I Sincerely Want to Be Right?, Fontana/Collins, 1975. “No-true-Scotsman Move” của Flew chỉ cách loại một phản ví dụ bằng việc thay đổi hồi tố định nghĩa về thành viên “thực thụ”, thay vì chấp nhận phản ví dụ đối với khái quát ban đầu. 

  127. Ronny Scherer, Fazilat Siddiq, Bárbara Sánchez Viveros, “The Cognitive Benefits of Learning Computer Programming: A Meta-Analysis of Transfer Effects,” Journal of Educational Psychology, 111(5), 2019, pp. 764–792, DOI: 10.1037/edu0000314. Nghiên cứu báo cáo hiệu ứng chuyển giao tổng thể g = 0.49, chuyển giao gần g = 0.75 và chuyển giao xa g = 0.47. Tuy nhiên, nghiên cứu không kiểm chứng hiệu quả riêng của Rust hay sự gia tăng trí thông minh chung; khác biệt theo thiết kế nghiên cứu và loại nhóm đối chứng cũng cần được xem xét. Meta-analysis này tổng hợp 105 nghiên cứu và 539 effect sizes. Moderator analysis cho thấy transfer estimate lớn hơn ở nghiên cứu dùng untreated control so với treated/active control, và effect trong published study lớn hơn gray literature; các khác biệt về design và publication này tiếp tục giới hạn causal hay population-wide interpretation. 

  128. Uniform Guidelines on Employee Selection Procedures, 29 C.F.R. Part 1607, đặc biệt §1607.9 và §1607.14. Hướng dẫn này chỉ áp dụng trong bối cảnh luật lao động Hoa Kỳ, nhưng cung cấp một ví dụ phương pháp luận về việc gắn tiêu chí tuyển chọn với phân tích công việc và tính hợp lệ thực nghiệm. §1607.9 “No assumption of validity” loại rõ general reputation, label, promotional material, usage frequency, testimonial và anecdotal account khỏi vai trò thay thế validity evidence. §1607.14 yêu cầu validity study xem xét job information và nhìn chung dùng job analysis phù hợp với validation strategy. Đây là framework của luật lao động Hoa Kỳ, không phải quy luật tâm lý phổ quát hay claim riêng về Rust. 

  129. Rust Project, A note on the Trademark Policy Draft, 2023-04-12; Rust Foundation, Rust Trademark Policy Draft Revision – Next Steps, 2023-04-17; Rust Foundation, Trademark Policy: Review and Survey, 2022-08-10. Các nguồn này ghi lại survey năm 2022, việc công bố draft ngày 2023-04-06, consultation mười ngày, sự hợp tác với Project Directors, Trademark Working Group và legal counsel, việc thừa nhận wider Project inclusion cùng communication chưa đủ, và ranh giới rằng draft không được áp dụng ngay mà chuyển sang feedback review và revision.  2 3 4

  130. Rust Project Leadership Council, Next Steps on the Rust Trademark Policy, 2024-11-06; Rust Foundation, Rust Trademark Policy Updates, 2024-11-06. Các nguồn này ghi lại revised draft năm 2024, các nhóm concern lặp lại trong feedback 2023, việc bỏ package-name restriction và sửa các rule về logo, merchandise, publication, cùng trạng thái final-feedback draft. Chúng mô tả xu hướng trong feedback đã gửi, không phải phân bố ý kiến của toàn bộ người dùng Rust.  2 3 4

  131. Rust Project, Governance và Rust Forge, Leadership Council — Relationship to the Rust Foundation; Rust Project Directors, January & February 2026 Project Director Update; Rust Foundation Board minutes, June 11, 2024. Các nguồn này mô tả vai trò hiện tại của Leadership Council, Project teams và Moderation team; cấu trúc Project Directors đại diện Project trên Foundation Board và phụ trách Foundation relationship; cùng ranh giới trademark revision được tiến hành như một công việc interface Foundation/Project riêng. Rust Forge cũng nói ranh giới chính xác của Foundation-related purview của Project Directors chưa được quy định hoàn toàn, vì vậy cuốn sách không gán quyền hạn chính xác hơn tài liệu hiện có.  2

  132. Rust Foundation, Rust Language Trademark Policy Updates, Explained, 2025-01-23; Rust Foundation, Rust Language Trademark Policy, current page accessed 2026-08-30. Nguồn đầu ghi lại final approval của Foundation Board bao gồm Project Directors và các phạm vi sử dụng chính; policy hiện tại phân biệt Project governance của Leadership Council với trademark ownership/stewardship của Foundation và chia cụ thể các use không cần approval và cần approval.  2

  133. National Security Agency, Software Memory Safety, originally November 2022, April 2023 Version 1.1. v1.1 khuyến nghị cân nhắc chuyển dịch chiến lược từ C/C++ và assembly sang MSL khi có thể, nêu Python, Java, C#, Go, Delphi/Object Pascal, Swift, Ruby, Rust và Ada như ví dụ, đồng thời ghi nhận sự khác nhau giữa các bảo đảm MSL và sự cần thiết tiếp tục hardening ngoài ngôn ngữ. Danh sách được giới thiệu là “some examples”, không phải standard đầy đủ hay chứng nhận phù hợp cho một workload cụ thể.  2

  134. National Security Agency and Cybersecurity and Infrastructure Security Agency, Memory Safe Languages: Reducing Vulnerabilities in Modern Software Development, June 2025, Ver. 1.0, và release notice. Báo cáo nêu Ada, C#, Delphi/Object Pascal, Go, Java, Python, Ruby, Rust và Swift như ví dụ, nói rõ MSL không phải panacea và adoption không thực tế trong mọi circumstance; tài liệu cũng bàn integration qua interoperability thay cho complete rewrite và non-MSL hardening khi MSL adoption không thực tế.  2 3 4 5

  135. Office of the National Cyber Director, Back to the Building Blocks: A Path Toward Secure and Measurable Software, February 2024. Báo cáo khuyến nghị MSL như một strong security building block, đồng thời bàn hybrid migration cho existing codebase, ranh giới no-one-size-fits-all, và vai trò bổ sung của hardware cùng formal methods. Phần space-system nêu Rust như một ví dụ đáp ứng các ràng buộc như không bắt buộc GC, đồng thời nói rõ vẫn cần thêm fielded evidence, toolchain maturity và workforce development.  2

  136. Jeff Vander Stoep, Alex Rebert, “Eliminating Memory Safety Vulnerabilities at the Source”, Google Online Security Blog, September 25, 2024. Báo tỷ lệ Android giảm 76% xuống 24% trong sáu năm và chiến lược ưu tiên mã mới an toàn. 

  137. Jeff Vander Stoep, “Rust in Android: move fast and fix things”, Google Online Security Blog, November 13, 2025. Dữ liệu tỷ lệ 2025, khoảng năm triệu dòng Rust, ước tính mật độ từ một lỗ hổng tiềm năng trước phát hành, review và rollback. 

  138. Jesse Howarth, “Why Discord is switching from Go to Rust”, Discord Blog, February 4, 2020. Mô tả cache–GC và kết quả viết lại dịch vụ cụ thể, không khuyến nghị viết lại mọi hệ thống. 

  139. Yizhou Zhang, “How we built Pingora, the proxy that connects Cloudflare to the Internet”, Cloudflare Blog, September 19, 2022. Nêu nhiều nguyên nhân giảm CPU/bộ nhớ, gồm tái sử dụng kết nối, đa luồng và bỏ ranh giới ngôn ngữ. 

  140. Arun Gupta, “Announcing the Firecracker Open Source Technology: Secure and Fast microVM for Serverless Computing”, AWS Open Source Blog, November 26, 2018. Báo dưới 125 ms trên i3.metal, microVM mặc định, mô hình thiết bị tối thiểu. 

  141. Miguel Ojeda, “[PATCH] rust: conclude the Rust experiment”, Linux Kernel Mailing List, December 13, 2025. Nêu kết thúc thí nghiệm, hỗ trợ tiếp tục, tổ hợp chưa hoàn tất và việc còn lại. 

  142. Ilia Afanasiev, “Is Rust the Future of Programming?”, JetBrains Blog, May 13, 2025. Dựa dữ liệu 2024, ước tính 2,267 triệu người dùng Rust và 709 nghìn người dùng làm ngôn ngữ chính. JetBrains, Developer Ecosystem 2024 — MethodologyDeveloper Ecosystem Data Playground — Methodology, ghi rằng survey tháng 5–6/2024 sau cleaning còn 23.262 developer từ 171 quốc gia/vùng lãnh thổ và được weighting theo geography, employment status, language use và JetBrains-product use, đồng thời thừa nhận vẫn có response bias. Population model kết hợp category share trong survey với developer population quốc gia được model hóa và coi population figure thu được là estimate chứ không phải exact count. Vì vậy 2,267 triệu / 709 nghìn là population estimate, không phải census các developer có thể định danh hay số Rust job opening. 

  143. Rust Survey Team, “2025 State of Rust Survey Results”, Rust Blog, March 2, 2026. Báo 7.156 phản hồi và giới hạn ngoại suy. 

  144. National Vulnerability Database, “CVE-2025-30388”. Ghi tràn heap Windows Win32K-GRFX và vector tấn công cục bộ, không quy kết Rust. 

  145. Ubuntu Security, “CVE-2025-68260”. Giải thích truy cập song song thao tác xóa danh sách unsafe Rust Binder gây data race và hỏng con trỏ. 

  146. Rust Project Goals, “Just add async”, 2026. Nêu khoảng cách đồng bộ–bất đồng bộ, giới hạn destructor đồng bộ và mục tiêu khám phá 2026–2027. 

  147. Defense Advanced Research Projects Agency, “TRACTOR: Translating All C to Rust”. Mục tiêu và cấu trúc đánh giá chương trình nghiên cứu tự động dịch C legacy sang Rust. 

  148. Rust Project Goals, 2026 GoalsC++/Rust Interop Problem Space Mapping. Danh sách goal 2026 tiếp tục bao gồm công việc lập bản đồ không gian vấn đề C++/Rust interoperability, còn tài liệu chi tiết thừa nhận rõ lượng tài sản C++ lớn hiện có và nhu cầu tương tác theo từng bước. Đây không phải mệnh đề phổ quát rằng full rewrite luôn không phù hợp, mà là bằng chứng chính thức cho việc xem interoperability như một bài toán kỹ thuật độc lập. 

  149. Rust Project Goals, 2026 GoalsNormative Documentation for Sound unsafe Rust. Các goal chính thức bao gồm công việc về normative unsafe safety contract, FLS, sanitizer và MC/DC coverage liên quan tới sử dụng cần bảo đảm cao. Chúng ghi nhận khoảng trống hiện tại và công việc dự kiến; chúng không chứng minh certification đã hoàn thành hay sự phù hợp với mọi domain. 

  150. Rust Foundation, Rust Security Initiative; Rust Project Goals, Implement Verifiable Mirroring Prototype2026 contributor tasks. Các tài liệu này mô tả ecosystem audit và threat modeling, cryptographically verified mirroring và công việc trên Cargo SBOM precursor. Sự tồn tại của một goal riêng lẻ không chứng minh effect của feature chưa được deploy.