我剛開始學習 Rust,在閱讀“Rust Book”時,我正在創造性地嘗試一些東西。
我知道可以創建一個通用方法來從陣列中獲取最大元素,如下所示:
fn largest<T: PartialOrd Copy> (nums: &[T]) -> T {
let mut largest = nums[0];
for &el in nums {
if el > largest {
largest = el;
}
}
return largest;
}
并main像這樣呼叫函式:
fn main() {
let list: Vec<u32> = vec![1,7,4];
println!("{}", largest(&list)); // 7
}
我將如何做同樣的事情但“擴展”陣列,如下所示:
fn main() {
let list: Vec<u32> = vec![1,7,4];
println!("{}", list.largest()); // 7
}
我想最后一個問題是:如果可能的話,這是否是一種不好的做法?為什么?
我嘗試了這樣的事情,但沒有設法弄清楚如何實作回傳 T 的“Largeble”特征:
pub trait Largeble {
fn largest(&self);
}
impl<T: Copy PartialOrd Display> Largeble for Vec<T> {
fn largest(&self) {
let mut largest = match self.get(0) {
Some(&el) => el,
None => panic!("Non Empty array expected")
};
for &el in self {
if el > largest {
largest = el;
}
}
println!("{}", largest);
// return largest;
}
}
uj5u.com熱心網友回復:
您需要使LargeabletraitT從回傳 a Vec<T>,您可以使用關聯型別執行此操作:
use std::fmt;
pub trait Largeble {
type Output;
fn largest(&self) -> Self::Output;
}
impl<T: Copy PartialOrd fmt::Display> Largeble for Vec<T> {
type Output = T;
fn largest(&self) -> T {
let mut largest = match self.get(0) {
Some(&el) => el,
None => panic!("Non Empty array expected")
};
for &el in self {
if el > largest {
largest = el;
}
}
largest
}
}
println!("{}", vec![1, 2, 3, 2].largest()); // prints "3"
像這樣的Largeable特征通常稱為擴展特征,因為它們使用新功能擴展現有專案。使用擴展特性來擴展現有庫中的專案在 Rust 生態系統中很常見。擴展名的后綴很常見Ext(因此Vec將呼叫的附加方法的集合VecExt)。擴展特性的一個流行用途是itertools庫,它提供了一個特性,可以Iterator在標準庫中添加額外的有用方法。
uj5u.com熱心網友回復:
我將如何做同樣的事情但“擴展”陣列
當然,您的代碼片段很接近,您可以創建一個特征并在型別上實作它。
pub trait Largeble<T>
where
T: Ord,
{
fn largest(&self) -> Option<&T>;
}
impl<T> Largeble<T> for Vec<T>
where
T: Ord,
{
fn largest(&self) -> Option<&T> {
// Iterator already has a method for getting max which simplifies things
self.iter().max()
}
}
或者,您可以創建T一個可能更適合此示例的關聯型別。
您可以在Rust Playground 中運行此代碼。
這會是一個不好的做法嗎?為什么?
不,這絕對不是壞習慣。這是在 Rust 中開發的一種非常常見的方式,并且非常強大。你的 trait 需要在你能夠呼叫的范圍內.largest(),所以它不會污染任何東西。
此外,如果您有多個來自不同特征的同名方法,您可以提供更長的語法來指定要使用的確切特征:Largest::<u32>::largest(&list)。
我嘗試過這樣的事情,但沒有設法弄清楚如何實作回傳 T 的“Largeble”特征。
您的代碼大部分是正確的,但是您最大的方法沒有回傳任何內容。這就是為什么 trait 需要一個 generic T,來指定你將 return T。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/386035.html
上一篇:JavaScript-在通過參考問題時清空陣列/物件
下一篇:在pd資料幀單元格內切片陣列
