رد پای کد Rust خود را کاهش دهید و استحکام آن را با انواع عمومی افزایش دهید.
همیشه سطوح عدم قطعیت در هنگام توسعه برنامه ها وجود دارد که می تواند منجر به خطا شود، به خصوص اگر توابع شما انواع خاصی از آرگومان ها را بپذیرند. برای کاهش خطاهای ناشی از عدم قطعیت، می توانید از Generics استفاده کنید. Generics عملکردی را برای ایجاد کلاس ها، توابع و ساختارهای داده برای کار با انواع مختلف فراهم می کند.
با استفاده از ژنریک، میتوانید الگوریتمها و ساختارهای دادهای را ایجاد و تعریف کنید که میتوانند روی چندین نوع بدون نوشتن کد پیچیده و پیادهسازیهای جداگانه برای هر نوع کار کنند. ژنریک قابلیت استفاده مجدد و کارایی کد را بهبود می بخشد و در عین حال ایمنی نوع و عملکرد را حفظ می کند.
استفاده از انواع عمومی در زنگ
نوع عمومی Rust می تواند با سایر انواع داده Rust تعامل داشته باشد. انواع عمومی را با براکت های زاویه ای (<>) و به دنبال آن دو یا چند پارامتر تعریف می کنید.
در اینجا یک تعریف ساختار عمومی وجود دارد که دو پارامتر نوع عمومی را می گیرد:
struct Point<T, U> {
// T and U are generic type parameters that the x and y fields will
// assume on instantiation
x: T,
y: U,
}
در ساختار Point، T و U پارامترهای نوع عمومی هستند.
می توانید پارامترهای نوع عمومی را با هر نوع داده ای در نمونه سازی جایگزین کنید:
fn main() {
let my_point = Point { x: String::from("hello"), y: String::from("world") };
println!(
"The x value of my_point is {} and the y value is {}.",
my_point.x,
my_point.y
);
}
متغیر my_point نمونه ای از ساختار Point است که با انواع رشته ها مقداردهی اولیه شده است. کامپایلر Rust انواع بتن T و U را بر اساس مقادیر موجود در نمونه استنباط می کند.
مرزهای صفت برای انواع ژنریک
انواع عمومی زنگ می توانند از مرزهای صفت برای اطمینان از ایمنی نوع استفاده کنند. صفات مجموعهای از روشها هستند که تیپها میتوانند برای نشان دادن رفتارهای مشخصی که برای صفت تعریف شده است، پیادهسازی کنند.
کران صفت مشخص می کند که یک نوع عمومی باید یک یا چند صفت را اجرا کند.
در اینجا مثالی از یک تابع عمومی آورده شده است که مقدار بیشتر از دو مقدار را با کران صفت برمی گرداند که تضمین می کند که انواع مقایسه شده این صفت را اجرا می کنند:
// Maximum is a trait that defines a method for evaluating the maximum of two
// types
trait Maximum {
fn max(self, other: Self) -> Self;
}
// Implements the `Maximum` trait for all types that implement the
// `PartialOrd` trait.
impl<T: PartialOrd> Maximum for T {
fn max(self, other: Self) -> Self {
// return `self` if it is greater than `other`; otherwise, return
// `other.`
if self > other {
self
} else {
other
}
}
}
fn main() {
let a = 5;
let b = 10;
let largest = Maximum::max(a, b);
println!("The largest value is {}", largest);
}
صفت Maximum یک متد max دارد که بزرگتر از دو مقدار از یک نوع را برمی گرداند. هر نوع که صفت PartialOrd را پیاده سازی کند، ویژگی Maximum را پیاده سازی می کند.
متد max دو مقدار از نوع Self را می گیرد – به نوعی که ویژگی Maximum را اجرا می کند – و مقادیر را با هم مقایسه می کند.
تابع اصلی دو متغیر را با استفاده از روش max مقایسه می کند و بزرگترین را چاپ می کند.
محدودیت برای انواع عمومی
محدودیتها مشابه مرزهای صفت هستند، اما به شما اجازه میدهند تا الزامات اضافی را در مورد انواعی که به عنوان پارامتر نوع استفاده میکنید، مشخص کنید.
اگر میخواهید یک تابع عمومی ایجاد کنید که انواع را برای تبدیل رشته بپذیرد، میتوانید از یک محدودیت استفاده کنید تا اطمینان حاصل کنید که پارامتر type یک ویژگی را پیادهسازی میکند.
// ToString is a trait with a string conversion method
trait ToString {
fn to_string(&self) -> String;
}
// to_string is a generic function that takes a value of any type that
// implements the ToString trait
fn to_string<T: ToString>(value: T) -> String {
value.to_string()
}
پارامتر مقدار to_string باید ویژگی ToString را پیاده سازی کند، که تضمین می کند که می توانید مقادیر نوع T را با روش to_string به رشته تبدیل کنید.
انواع عمومی برای کار با صفات مفید هستند
انواع عمومی زنگ قوی هستند و زمینه هایی برای بهبود وجود دارد. یک حوزه مهم تمرکز، بهبود عملکرد کد عمومی است. در حال حاضر، سیستم نوع Rust میتواند سربار را به کدهای عمومی تحمیل کند و عملکرد را کاهش دهد.
انواع ژنریک برای کار با صفات مفید هستند. با استفاده از انواع عمومی، می توانید اشیاء ویژگی ایجاد کنید که با هر نوع کارکردی با یک ویژگی کار می کنند تا روش های شما انعطاف پذیرتر شود.