Rust là gì

     

Rust (đọc là rớt-xtờ /rʌst/) là một trong ngôn ngữ lập trình hệ thống (system programming language) được quảng bá là bao gồm tốc độ cực kỳ nhanh, ngăn chặn được phần lớn mọi bug crash (segfaults), ngăn ngừa được data race, siêu memory safe và lại không buộc phải tới garbage collector!

Cú pháp cơ bạn dạng của một công tác Hello World trong Rust như thế này:

fn main() println!("hello, ", "world");Bạn thấy gì qua đoạn công tác trên nào? có vẻ như vừa như thể C, vừa giống như Go tốt Swift, Java, C#,... Mỗi vật dụng một tí, đúng không?

Tại sao đề nghị dùng Rust?

Chắc các bạn cũng biết đến khả năng kiểm soát điều hành tài nguyên khi thao tác với các ngôn ngữ như C/C++ tốt Java, Python, Ruby, JavaScript,...

Bạn đang xem: Rust là gì

*

Với C/C++, bạn được:

Toàn quyền điều hành và kiểm soát mọi lắp thêm (malloc, free,...)Thường xuyên chống mặt với memory leak, data race, segfaults,...

Đối với thiên con đường JavaScript giỏi Ruby, bạn:

Chẳng rất cần phải quan chổ chính giữa một thay đổi được cung cấp phát ra sao và mất ra đi saoNhưng trade-off của nó chính là performance cực kì tệ hại.

Rust là chiến thuật kết hợp cho ưu thế của cả hai loại ngữ điệu trên, khi làm việc với Rust, bạn không cần phải quan trung khu tới việc bị memory leak xuất xắc segfault, khi làm multi thread, bạn không hề sợ data race vày rust compiler vẫn lo hết chuyện đó mang đến bạn, để bảo vệ trong thời điểm chạy (runtime) thì chương trình sẽ luôn hoạt động một cách bình an và vẫn đảm bảo được tốc độ và performance buổi tối ưu nhất.

À! Chắc sẽ sở hữu được bạn hỏi: Rust cùng Go thì nên lựa chọn ai? Nếu tất cả cùng thắc mắc, thì đương nhiên là chọn Rust rồi, do mình đã quảng cáo Rust nhưng :)) xin mời chúng ta xem bài này nhé.

Rust nhanh tới nút nào?

OK. Đầu tiên buộc phải nói ngay lập tức là Rust không hẳn ngôn ngữ lập trình nhanh nhất, trong số các ngữ điệu lập trình bậc cao (high cấp độ programming language), không có cái nào như vậy cả.

Vậy ngôn ngữ nào new là cấp tốc nhất? với vì sao nó nhanh?

Kẻ giành danh hiệu đó có thể phải kể tới Assembly, chính là nơi các bạn toàn quyền kiểm soát và điều hành một trở nên được tạo ra ở đâu, lúc nào. Thích tạo ra trong stack giỏi trong heap là tùy bạn. Chúng ta được toàn quyền với bộ nhớ, vì bộ lưu trữ là của nó luôn, thích hợp xài lúc nào là xài.

Mà khoan đã! Khả năng kiểm soát điều hành liên quan gì tới tốc độ?

Trong Assembly, từng instruction (lệnh) được viết ra mọi được map đúng chuẩn với binary code/machine opcode cơ mà từng nhiều loại CPU cung cấp ("close to lớn the metal").

*

Khi thao tác với Assembly, chúng ta phải nỗ lực được tập lệnh (instruction set) của một số loại CPU mà bạn đang làm việc - và cùng với mỗi nhiều loại CPU không giống nhau thì lại có một tập lệnh không giống nhau - với nó một các loại cú pháp hết sức gần cận với laptop (nhưng xa lạ với con người :)))

*

C thành lập để khắc chế nhược đặc điểm đó của Assembly, chuyển sức mạnh kiểm soát và điều hành của Assembly vào phổ biến với cú pháp thân thiết hơn với các lập trình viên.

Bằng bí quyết lượt bỏ hết đều dòng lệnh phức tạp của mã máy, C thay thế bằng những câu lệnh dễ dàng hơn (syntax sugar). Ví dụ:

.section__TEXT,__text,regular,pure_instructions.macosx_version_min 10, 12.globl_main.align4, 0x90_main: ##
main.cfi_startproc## BB#0:pushq%rbpLtmp0:.cfi_def_cfa_offset 16Ltmp1:.cfi_offset %rbp, -16movq%rsp, %rbpLtmp2:.cfi_def_cfa_register %rbpxorl%eax, %eaxmovl$100, -4(%rbp)popq%rbpretq.cfi_endproc.subsections_via_symbolsĐoạn mã Assembly trên là những gì sẽ được compiler dịch ra mang đến đoạn lịch trình C sau:

int main() int number = 100;Chỉ cùng với 3 chiếc code C (mid màn chơi language), bạn sẽ không còn đề xuất vật vã viết từng lệnh để cấp phép bộ nhớ, move giá trị vào từng ô nhớ, hóa giải nó khi xong xuôi chương trình vào Assembly nữa. Vị C đã đơn giản và dễ dàng hóa vấn đề bằng cách "giấu" đi tất cả những làm việc đó và chuyển ra cho mình một cú pháp vô cùng đơn giản và dễ dàng là int number = 100;.

Việc "giấu" bớt các thao tác làm việc rườm kiểm tra và hỗ trợ một phương pháp đơn giản hơn để thực hiện một vấn đề được call là abstraction, với điều này ra mắt càng nhiều hơn thế ở những ngôn ngữ lập trình bậc cao như C#, Java, Ruby, JavaScript, Python,...

*

Lợi thế của abstraction kia là giúp cho lập trình viên đàng hoàng tay để còn tập trung vào hầu hết thứ khác quan trọng đặc biệt hơn như code logic, business của chương trình. Nhưng thực chất thì các thao tác phức tạp bên dưới vẫn phải được thực hiện, cùng compiler của từng ngôn ngữ sẽ sở hữu nhiệm vụ "viết" các đoạn code đó ra nạm cho bạn. Tác dụng là gì?

Như đã nhắc đến ở trên thì mỗi căn cơ phần cứng lại có một tập lệnh không giống nhau, vậy đề xuất phần code được compiler "thêm" vào bắt buộc được viết theo một cách không thể phụ thuộc vào vào từng các loại phần cứng nắm thể. Lấy ví dụ như nó không thể chắc chắn là được phải truy cập vào đâu để lấy thông tin về chuột/bàn phím, nỗ lực là nó phải tốn thêm một bước đó là: Hỏi máy vi tính xem nhỏ chuột nó nằm ở đâu để truy nã vấn tới. Và cố là, thay vì chưng chỉ làm mỗi trọng trách đọc coi nút nào trên bé chuột vừa mới được nhấn xuống, nó yêu cầu làm thêm 1 vài vấn đề nữa như thể chạy cho tới hỏi anh kernel của hệ điều hành và quản lý xem đơn vị anh chuột nằm ở vị trí đâu, rồi chạy qua bên anh con chuột gõ cửa xem ảnh có đơn vị không,... Với những bài toán lôi thôi kia tốn thêm 1 ít thời gian nữa.

*

Những gì ở dưới thì bạn sẽ không thể kiểm soát và điều hành hay can thiệp vào để tối ưu hóa nó được, ví dụ: các bạn không khi nào có thể chủ động giải phóng một vùng nhớ khi dùng Garbage Collector, chúng ta không thể yêu ước JavaScript tạo ra một biến phía bên trong stack tuyệt heap theo ý chúng ta được,... Và chúng ta phải chấp nhận với cái bí quyết nó đốt thời gian như là một sự thật hiển nhiên.

Đánh thay đổi tốc độ, gia tăng các lớp abstraction, giúp cho lập trình viên rất có thể viết code một cách thoải mái và dễ chịu hơn, xây dựng sản phẩm nhanh hơn. Đó là bản chất xấu xa của các high level programming languages :))

Zero-cost Abstraction

Cũng y như C/C++, lân cận khả năng kiểm soát điều hành gần như hoàn hảo và tuyệt vời nhất (vâng, Rust cũng đều có thể cho mình kiểm soát mang đến từng ô nhớ!), Rust chọn zero-cost abstraction làm một trong những nguyên tắc căn cơ của nó.

Xem thêm: " Quyền Giám Đốc Tiếng Anh Là Gì ? Tên Các Chức Vụ Quan Trọng Trong Tiếng Anh

C++ implementations obey the zero-overhead principle: What you don"t use, you don"t pay for . And further: What you vị use, you couldn"t hand code any better.

– Stroustrup

*

Rust design ra những abstraction dễ dùng, nhưng lại được compile về machine code một biện pháp rất tác dụng và ko làm ảnh hưởng đến tốc độ của toàn chương trình, những high-level API được compile về machine code một cách tối thiểu và buổi tối ưu tuyệt nhất (you pay for the features you actually use).

Ngoài ra Rust còn reviews khái niệm Traits góp bạn được thiết kế việc y hệt như trên những ngôn ngữ lập trình bậc cao nhưng vẫn đảm bảo được khả năng kiểm soát code cùng tài nguyên như những ngôn ngữ xây dựng bậc thấp!

Tốc độ của Rust

Khi so sánh với những ngôn ngữ khác, đích thực thì đó là một câu hỏi không nên thiết, nhưng bạn cũng có thể tham khảo, bảng so sánh vận tốc thực thi tính tổng hàng số Fibonacci giữa những ngôn ngữ Rust, Go, NodeJS với Swift:

*

Bảng so sánh thời hạn thực hiện, càng nhỏ thì càng xịn

Bạn rất có thể xem bảng đối chiếu performance của Rust và một số trong những ngôn ngữ không giống tại:

Rust an ninh tới cỡ nào?

Một trong số những điểm mà lại Rust quảng cáo chính là an toàn, không lúc nào bị crash, vậy làm sao Rust đã đạt được những điều đó?

Câu trả lời nằm sinh sống Rust Compiler.

Thông thường, phần lớn lỗi của một lịch trình C/C++ sẽ tương quan đến vấn đề truy xuất bộ nhớ lưu trữ khi thực thi (runtime error - ví dụ bạn truy vấn vào vùng bộ nhớ lưu trữ đã bị giải phóng, thực hiện nhầm những biến có mức giá trị null, lỡ tay tạo ra nhiều thread thuộc ghi vào một vùng nhớ,...)

*

Để chống chặn vụ việc này, Rust Compiler đặt ra một loạt những quy tắc để kiểm tra ngay trong lúc nó biên dịch chương trình, họ sẽ ko đi sâu vào những quy tắc này, tuy nhiên mình sẽ nói sơ qua:

Mọi thay đổi mặc định số đông là immutable, với không được sở hữu giá trị null (nên không tồn tại lỗi NullReferenceException)Trong Rust, một vùng nhớ luôn có một trở thành sỡ hữu nó.Gán một biến vào một trong những biến khác, có nghĩa là bạn đưa quyền sở hữu vùng nhớ của vươn lên là đó cho trở thành mới. Biến cũ ko được quyền tróc nã xuất tới đó nữa.Trong một thời điểm, chỉ gồm một trong nhị trường hợp hoàn toàn có thể xảy ra, kia là:Nhiều biến hóa khác rất có thể mượn vùng nhớ kia chỉ nhằm đọc (read only).Chỉ bao gồm một biến bao gồm quyền mượn để ghi quý hiếm lên đó.Một biến hóa chỉ rất có thể tồn tại phía bên trong scope của nó, thoát khỏi scope kia nó sẽ bị giải phóng ngay lập tức.

Bất cứ lúc nào lập trình viên vi phạm các quy tắc này, Rust đã báo cho bạn biết ngay khi biên dịch, chứ không hề để lọt lỗi.

Trong số các quy tắc được liệt kê làm việc trên, trừ quy tắc trước tiên ra, thì các mục còn lại chính là Ownership, Borrowing và Lifetime System của Rust.

Ví dụ với đoạn code sau minh họa cho vấn đề chuyển quyền sở hữu nhắc ở trên:

let v = vec!<1, 2, 3>;let v2 = v;println!("v<0> is: ", v<0>);Theo lẽ thường, chúng ta nghĩ đoạn code trên sẽ in ra số 1, là cực hiếm của v<0>. Tuy thế khi biên dịch thì sẽ gặp mặt ngay lỗi:

error: use of moved value: `v`println!("v<0> is: ", v<0>);Đừng lo nếu bạn thiếu hiểu biết tại sao lại phát hình thành lỗi này, ví dụ như này chỉ nhằm minh họa cho bạn thấy về kĩ năng bắt lỗi runtime trong cả trong compile time của Rust thôi.

Rust không đề xuất Garbage Collector?

Đúng vậy, Rust không có garbage collector (GC), tuy nhiên vẫn đảm bảo được tính an toàn về bộ nhớ, đó là một vào những chức năng đặc biệt của Rust.

*

Thay vào đó, Rust Compiler sẽ dự kiến được bao giờ một biến sẽ không còn được thực hiện và auto chèn thêm code súc tích để giải phóng nó, bớt thiểu giá cả cho việc quản lý bộ nhớ lúc runtime.

fn main() let score = 10; // Khởi tạo nên vùng nhớ mới, cấp phép cho trở nên score // Tới đấy là hết scope của trở thành score, mình yêu cầu giải phóng nó đi thôi Đoạn trên là diễn biến lưu ý đến của Rust Compiler qua từng mẫu code :))

Và việc này được kiểm soát thông qua Ownership System.

Việc không tồn tại GC còn làm Rust rất có thể dễ dàng được nhúng vào những ngôn ngữ bao gồm GC khác nữa.

Dùng Rust có thể làm được gì?

Đây là thắc mắc mà bản thân thấy đa số người hỏi nhất.

Câu trả lời là: Mọi thứ!

Mặc dù là một ngôn từ lập trình hệ thống (system programming language), tuy nhiên Rust nhắm đến việc đối đầu và cạnh tranh với C/C++ để tăng độ bình yên và nâng cấp performance cho các ứng dụng được viết ra, chính vì như vậy Rust hoàn toàn có thể làm được phần lớn thứ mà C/C++ làm cho được, ví dụ:

...

Xem thêm: Thủ Tục Làm Hộ Chiếu Tại Hà Nội Ở Đâu? Thủ Tục Làm Hộ Chiếu Tại Hà Nội?

Giờ bước đầu học Rust như vậy nào?

*

Ảnh đem từ: (http://www.slideshare.net/LizBaillie/rustconf-2016-illustrated-adventure-guide-65894363)

Để bắt đầu, các chúng ta cũng có thể tham khảo một số trong những tài liệu sau:

Ngoài ra, các bạn cũng có thể tham gia vào các cộng đồng Rust như:

For fun, bạn nên biết một số trong những từ vựng bắt buộc biết trước lúc gia nhập cộng đồng này :))

Rustacean: Là từ chỉ những người sử dụng Rust, giống hệt như Gophers giỏi Rubyist tuyệt Alchemist (của Elixir).Rustlandia: Là khu vực mà các rustaceans hoạt động, điều này chắc chỉ gồm hội Rust mới gồm :))

Ngoài ra chúng ta cũng có cộng đồng Rust Việt Nam: