Lập trình Rust cho các nhà phát triển Java trong năm 2022
23/03/2022 07:59
Nếu bạn là một nhà phát triển Java, bạn sẽ thấy Rust tương đối dễ dàng để nắm bắt, nhờ vào sự giống nhau của hai ngôn ngữ. Cùng tìm hiểu thêm về Rust ngay sau đây!
Trong số các ngôn ngữ lập trình mới hơn ngày càng phổ biến là Rust. Rust được giới thiệu lần đầu tiên vào năm 2010 và đã lặng lẽ nhận được sự quan tâm sâu sắc về hiệu suất, cú pháp và các tính năng an toàn chuỗi. Nếu bạn là một nhà phát triển Java, bạn sẽ thấy Rust tương đối dễ dàng để nắm bắt, nhờ vào sự giống nhau của hai ngôn ngữ. Cùng tìm hiểu thêm về Rust ngay sau đây!
Cú pháp lập trình Rust
Giống như Java, Rust được biên dịch. Nó được biên dịch theo thông số kỹ thuật LLVM , tương tự như JVM , cho phép xuất ra nhiều nền tảng mục tiêu.
Và giống như Java, Rust có nguồn gốc từ dòng C. Việc sử dụng dấu ngoặc nhọn cho các khối và dấu chấm phẩy cho các kết thúc dòng hoàn toàn giống với Java.
Listing 1. Simple Rust code
fn main() {
println!("Hello, InfoWorld!");
}
Lưu ý rằng có một main()hàm, tương tự như entry point trong Java.
Các chức năng trong Rust
Các hàm đứng riêng trong Rust và chúng có thể được khai báo ở bất kỳ đâu, kể cả được lồng trong các hàm khác. Điều này không giống như Java, nơi các hàm luôn được khai báo dưới dạng các phương thức trên các đối tượng (ngoại trừ trường hợp lambdas). Nói một cách khác, trong Java một đối tượng, còn ở Rust thì không.
Listing 2. Using functions in Rust
fn main() {
println!("Hello, world!");
fn function2(){
println!("Hello InfoWorld");
}
function2();
function3();
}
fn function3() {
println!("Hello again.");
}
Giá trị trả về ngầm định
Không giống như Java, Rust cho phép bạn bỏ qua từ khóa trả về ở cuối một hàm. Câu lệnh cuối cùng trong hàm sẽ tự động được đánh giá là giá trị trả về. Khi thực hiện việc này, bạn bỏ dấu chấm phẩy khỏi câu lệnh cuối cùng.
Lambdas
Giống như Java, Rust hỗ trợ lambdas để mã hóa kiểu chức năng. Cú pháp khác nhau, nhưng không khó hiểu nếu bạn đã quen thuộc với API luồng Java. listing 3 cho thấy việc sử dụng map()hàm để tạo một tập hợp các chuỗi ký tự viết hoa. Như bạn có thể thấy, nó khá giống với Java.
Listing 3. Functional sorting with lambdas
// Rust
fn main() {
let animals = ["dog", "badger", "quokka"];
let result = animals.iter().map(|value| value.to_uppercase());
for animal in result {
println!("Uppercased: {}", animal);
}
}
Hàm map()nhận một đối số gồm hai phần. Phần đầu tiên là một biến bên trong các ký tự ống dẫn |value|, phần này sẽ xác định biến được sử dụng làm phần xử lý trên mỗi mục. Phần thứ hai là thao tác để thực thi. Trong trường hợp này, chúng ta gọi to_uppercase()từng phần tử của mảng.
Lưu ý rằng, giống như Java, Rust lambdas là các bao đóng để nắm bắt trạng thái của khối xung quanh. Nói cách khác, chúng có quyền truy cập vào ngữ cảnh biến mà chúng thực thi.
Tham khảo: Khóa học lập trình Java
Đối tượng là cấu trúc trong Rust
Hãy xem listing 4, trong đó giới thiệu structtừ khóa. Một cấu trúc, viết tắt của cấu trúc, cho phép bạn xác định một vùng chứa cho dữ liệu, giống như phần trạng thái của một lớp trong Java.
Listing 4. Using a Rust struct
struct Animal {
name: String
}
fn main() {
let dog = Animal{
name: String::from("Shiba")
};
println!("{}", dog.name);
}
Bạn xác định các thành viên của struct bên trong dấu ngoặc nhọn của struct. Các biến này tương tự với các thành viên công khai.
Lưu ý rằng trong dòng mà bạn khai báo dogbiến, không cần gọi từ khóa mới. Rust có thể suy ra từ ngữ cảnh mà một tham chiếu mới theo thứ tự.
Tiếp theo, hãy lưu ý rằng namebiến được đặt tại thời điểm tạo là một chuỗi có giá trị. Điều này được thực hiện bằng cách gọi String.fromphương thức tích hợp bằng toán tử tham chiếu dấu hai chấm.
Cuối cùng, hãy lưu ý rằng giống như Java, Rust sử dụng toán tử dấu chấm để truy cập nametrường trên cá dogthể:.dog.name
Methods trong Rust
Bạn có thể thêm các hàm vào cấu trúc và các hàm này hoạt động giống như các phương thức trong Java. Ví dụ: để thêm một speak()phương thức vào Animalcấu trúc được hiển thị trong listing 4, bạn có thể sử dụng impltừ khóa như trong listing 5.
Listing 5. Adding a method
impl Animal {
fn speak(&self) {
println!("{}", self.name);
}
}
Impl có nghĩa là thực hiện. Ở đây trong listing 5, chúng tôi đang triển khai Animalcấu trúc. Chúng tôi xác định một phương thức duy nhất speak, sử dụng một đối số duy nhất. Đối số này là con trỏ đặc biệt &self(ký hiệu và trong Rust có nghĩa là đối số là một tham chiếu). Con trỏ đặc biệt này có ngữ nghĩa rất giống với thistừ khóa trong Java. Nó đề cập đến cá thể đối tượng hiện đang hoạt động.
Việc gọi dog.speak()sẽ xuất ra tên của đối tượng được khởi tạo hiện tại, "Shiba"trong ví dụ này.
Tính đột biến trong Rust
Một trong những điều thú vị hơn về Rust, nếu bạn đến từ nền tảng Java, là tính bất biến mặc định của các biến. Nói tóm lại, khi bạn khai báo một biến trong Rust, theo mặc định, nó là bất biến và cố gắng thay đổi nó sẽ dẫn đến lỗi.
Để làm cho một biến có thể thay đổi, muttừ khóa phải được thêm vào, nhưng mutchỉ có thể được thêm bởi một tham chiếu tại một thời điểm. Hãy nhớ rằng, Rust rất quan tâm đến việc giữ an toàn cho chuỗi mã. Điều này cũng tránh được các lỗi sửa đổi đồng thời trong Java.
listing 6 chỉ ra cách làm cho dogđối tượng có thể thay đổi được, rồi gán một tên mới cho nó.
Listing 6. A mutable string
let mut dog = Animal{
name: String::from("Shiba")
};
dog.name = String::from("Suki");
println!("{}", dog.name);
Nhập suy luận bằng Rust
Trong Rust, không phải lúc nào bạn cũng phải cho trình biên dịch biết bạn đang khai báo loại biến nào. Điều này có vẻ kỳ lạ đối với các nhà phát triển đến từ Java, nơi không có cơ sở để suy ra loại biến. Ví dụ, trong listing 7, trình biên dịch suy ra chính xác kiểu là số nguyên.
Listing 7. Type inference example
let number1 = 10;
let number2 = 10;
println!("{}", number1 * number2);
Kết luận:
T3H hy vọng bạn thấy bài viết này hữu ích. Nếu bạn biết bất kỳ câu hỏi về Rust Java , hãy cho chúng tôi biết trong phần bình luận bên dưới. Bạn cũng có thể tham khảo thêm các khóa học lập trình của chúng tôi ngay hôm nay!