Hiểu đặc điểm và thời gian sống của Rust
Đặc điểm và thời gian sống là những thành phần chính của Rust. Bạn có thể sử dụng các đặc điểm để xác định hành vi và khả năng thực hiện của các loại. Chúng rất linh hoạt, cho phép bạn viết mã chung hơn, giảm trùng lặp và cải thiện khả năng bảo trì.
Rust sử dụng một cơ chế khác—các vòng đời—để theo dõi quyền sở hữu các biến trong và ngoài phạm vi. Điều này ngăn chặn con trỏ lơ lửng trong quá trình thỏa thuận biến.
Cùng với nhau, các đặc điểm và thời gian tồn tại giúp đảm bảo an toàn cho loại, an toàn cho bộ nhớ và độ tin cậy của mã.
Mục Lục
Hiểu đặc điểm trong Rust
Đặc điểm là tập hợp các phương thức mà các loại khác có thể thực hiện. Các đặc điểm tương tự như giao diện trong các ngôn ngữ như Java, Go và TypeScript nhưng linh hoạt hơn.
Bạn sẽ sử dụng đặc điểm từ khóa để xác định các đặc điểm trong Rust, theo sau là khai báo các chữ ký của phương thức.
trait MyTrait {
fn my_method(&self);
}
Mã xác định một đặc điểm có tên Mytrait với một my_method phương pháp. Các &bản thân tham số chỉ ra rằng phương thức đề cập đến đối tượng của kiểu triển khai làm tham số đầu tiên của nó.
Sau khi xác định một đặc điểm, bạn có thể triển khai đặc điểm đó cho các loại tùy chỉnh của mình.
Đây là cách bạn có thể triển khai một đặc điểm cho các loại cấu trúc của mình.
struct Person {
name: String,
age: u32,
}impl Info for Person {
fn summary(&self) {
println!("My name is {} and I am {} years old.", self.name, self.age);
}
}
Các Người thực hiện cấu trúc Thông tinvà bạn có thể gọi bản tóm tắt phương pháp trên các trường hợp của Người cấu trúc.
fn main(){
let john = Person { name: String::from("John"), age: 30 };
john.summary();
}
Các John biến là một thể hiện của Người cấu trúc.
Các chủ yếu lời gọi hàm bản tóm tắt in một tin nhắn tới bàn điều khiển:
Enums có thể triển khai các đặc điểm. Đây là cách bạn có thể định nghĩa một enum với các biến thể triển khai bản tóm tắt phương pháp:
enum MyEnum {
VariantA,
VariantB,
}impl Info for MyEnum {
fn summary(&self) {
match self {
MyEnum::VariantA => {
}
MyEnum::VariantB => {
}
}
}
}
Sử dụng Đặc điểm cho Tham số Chức năng và Giá trị Trả về
Bạn có thể sử dụng các đặc điểm làm tham số chức năng và giá trị trả về. Sử dụng các đặc điểm làm tham số chức năng rất hữu ích để viết mã chung với nhiều loại.
Đây là một hàm nhận tham số thuộc bất kỳ loại nào thực hiện Thông tin.
fn do_something<T: Info>(value: T) {
value.summary();
}
Các
Cuộc sống trong Rust
Công cụ kiểm tra mượn của Rust phân tích các chương trình và đảm bảo sử dụng bộ nhớ phù hợp. Trong Rust, mọi giá trị đều có chủ sở hữu chịu trách nhiệm phân bổ lại giá trị. Khi các biến mượn giá trị, chúng mượn tham chiếu đến giá trị được truyền, nhưng chủ sở hữu vẫn giữ quyền sở hữu.
Thời gian tồn tại là một cách để đảm bảo rằng các giá trị mượn được sử dụng đúng cách. Thời gian tồn tại là một nhãn được gắn vào một tham chiếu, mô tả khoảng thời gian tham chiếu đó hợp lệ.
Trong Rust, bạn có thể chỉ định thời gian tồn tại bằng cách sử dụng chú thích dấu nháy đơn:
func<'a>
Khi tạo tham chiếu, tham chiếu được chỉ định thời gian tồn tại mô tả khoảng thời gian tham chiếu hợp lệ. Nếu bạn có một hàm nhận tham chiếu đến một giá trị, thời gian tồn tại phải dài hơn lệnh gọi hàm để đảm bảo rằng giá trị hợp lệ khi hàm trả về.
Đây là một ví dụ về đặc tả vòng đời trong một chức năng.
fn do_something<'a>(x: &'a i32) -> &'a i32 {
x
}fn main() {
let x = 42;
let result = do_something(&x);
println!("The result is: {}", result);
}
bên trong làm việc gì đó chức năng, các ‘Một tham số trọn đời chỉ ra rằng tham chiếu đến x có giá trị miễn là chức năng gọi. Tham chiếu được trả về cũng hợp lệ miễn là lệnh gọi hàm.
Các chủ yếu hàm in kết quả bằng cách chuyển một tham chiếu đến x biến trong chủ yếu chức năng cho bàn điều khiển.
Cú pháp trọn đời có thể dài dòng, nhưng nó cần thiết cho việc quản lý bộ nhớ và an toàn. Các quy tắc loại bỏ ba vòng đời cung cấp các nguyên tắc cho phép Rust suy ra vòng đời của các tham chiếu trong các tình huống nhất định.
Quy tắc trọn đời đầu vào
Quy tắc thời gian tồn tại của đầu vào chỉ định rằng nếu một hàm hoặc phương thức lấy một hoặc nhiều tham chiếu làm tham số đầu vào, thì Rust giả định rằng tất cả các tham chiếu đều có cùng thời gian tồn tại.
Nói một cách đơn giản, thời gian tồn tại của các tham chiếu đầu ra sẽ giống như thời gian tồn tại của các tham chiếu đầu vào.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
bên trong dài nhất chức năng, Rust suy ra rằng thời gian tồn tại của tham chiếu đầu ra giống với tham chiếu đầu vào vì cả hai đều có cùng tham số thời gian tồn tại ‘Một.
Quy tắc thời gian tồn tại của đầu vào giúp việc viết các hàm chung nhận nhiều tham chiếu làm đầu vào trở nên dễ dàng.
Quy tắc trọn đời đầu ra
Quy tắc thời gian tồn tại của đầu ra chỉ định rằng nếu một hàm hoặc phương thức trả về một tham chiếu, thì Rust sẽ cho rằng thời gian tồn tại của tham chiếu đầu ra khác với thời gian tồn tại của bất kỳ tham chiếu đầu vào nào.
fn first_word<'a>(s: &'a str) -> &'a str {
s.split_whitespace().next().unwrap()
}
Trong chức năng này, Rust suy ra rằng thời gian tồn tại của tham chiếu đầu ra khác với thời gian tồn tại của tham chiếu đầu vào vì split_whitespace() phương thức tạo một tham chiếu đầu ra không có tham số tham chiếu đầu vào.
Sự hủy diệt của quy tắc trọn đời
Quy tắc loại bỏ vòng đời áp dụng nếu một hàm hoặc phương thức nhận một tham chiếu hoặc tham số đầu vào và trả về một tham chiếu. Trong trường hợp đó, Rust giả định rằng tham chiếu đầu ra có cùng thời gian tồn tại với tham chiếu đầu vào.
fn longest<'a>(x: &'a str, y: &str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
Trong hàm này, Rust suy ra rằng thời gian tồn tại của tham chiếu đầu ra giống như thời gian tồn tại của tham chiếu đầu vào vì tham chiếu đầu vào y không có tham số trọn đời. Rust vượt qua tham số trọn đời cho y và cho rằng nó có cùng thời gian tồn tại như x.
Quy tắc này giúp viết các hàm nhận một tham chiếu đầu vào và trả về một tham chiếu đầu ra dễ dàng hơn.
Đặc điểm và Lifetimes
Bạn có thể kết hợp các đặc điểm và thời gian tồn tại để tạo các hàm chung hoạt động cho các loại triển khai một đặc điểm và có thời gian tồn tại hợp lệ.
Đây là một đặc điểm và một hàm tham chiếu đến một giá trị thực hiện đặc điểm đó.
trait ToString {
fn to_string(&self) -> String;
}fn to_string<'a, T: ToString>(t: &'a T) -> String {
t.to_string()
}
Ở đây, tham số trọn đời ‘Một đảm bảo rằng tài liệu tham khảo t có giá trị trong suốt thời gian tồn tại của đối tượng mà nó tham chiếu. Bạn có thể dùng to_string chức năng với các loại thực hiện ToString đặc điểm có một cuộc sống hợp lệ.
Các đặc điểm hình thành cơ sở để triển khai các khái niệm OOP trong Rust
Đặc điểm cho phép bạn xác định hành vi. Mặc dù Rust không phải là ngôn ngữ lập trình hướng đối tượng (OOP), nhưng bạn có thể sử dụng các đặc điểm để triển khai các khái niệm OOP từ đóng gói đến kế thừa, đa hình và trừu tượng hóa.
Việc triển khai các khái niệm OOP này với các đặc điểm giúp các chương trình Rust của bạn có thể mở rộng, mạnh mẽ, có thể bảo trì và hiệu quả.