簡體   English   中英

用於在 Rust 中實現 len() 函數的類型的通用更長函數

[英]Generic longer function for types implementing len() function in Rust

我正在嘗試做的是創建通用函數來比較具有長度的事物的兩個實例。

我的代碼:

fn main() {
    let vec1 = vec!(1, 2, 3);
    let vec2 = vec!(1, 2, 3, 4);
    println!("Longest vector is: {:?}", longer_vec_gen(&vec1, &vec2));
    println!("Longest iterator is {:?}", longer_exact_size_iterator(&vec1.iter(), &vec2.iter()))
}

fn longer_vec_gen<'a, T>(x: &'a Vec<T>, y: &'a Vec<T>) -> &'a Vec<T> {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

fn longer_exact_size_iterator<'a, T: ExactSizeIterator>(x: &'a T, y: &'a T) -> &'a T {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

這兩個函數都有效,但第一個函數只適用於Vec ,所以我想向前邁出一步,為任何有長度的東西做這件事。 第二個實現了這一點,但現在我不得不在調用這個我希望避免的函數時在參數上使用.iter()

另一個問題是我不能將字符串字符串文字傳遞給這個函數。

我希望實現的是創建更長的函數,該函數將需要任何兩個已實現函數.len()的元素,因此此代碼將無錯誤地運行:

fn main() {
    let vec1 = vec!(1, 2, 3);
    let vec2 = vec!(1, 2, 3, 4);
    println!("Longer vector is: {:?}", longer(&vec1, &vec2));

    let string1 = String::from("abcd");
    let string2 = String::from("xyz");
    println!("Longest string is : {:?}", longer(&string1, &string2))
}

fn longer(...) {
...
}

但現在我不得不在調用這個函數時在參數上使用.iter() ,我希望避免這種情況

您可以通過限制IntoIterator來解決該特定問題。 這有點棘手,因為您想返回傳遞給函數的引用,但IntoIterator它的接收器。 您可以通過要求類型為IntoIterator + Copy來完成這項工作。 由於共享引用滿足Copy的要求,因此此函數適用於對大多數(如果不是全部)標准容器類型的引用:

fn longer_exact_size_iterator<T, U>(x: T, y: T) -> T
where T: IntoIterator<IntoIter=U> + Copy,
    U: ExactSizeIterator,
{
    if x.into_iter().len() > y.into_iter().len() {
        x
    } else {
        y
    }
}

現在你可以做longer_exact_size_iterator(&vec1, &vec2)

游樂場

如果您想要一個適用於任何帶有.len()但可能沒有精確大小的迭代器的變體,那么您必須編寫自己的特征並在您要處理的類型上實現它; 它不會是自動的。 例如:

pub trait HasLength {
    fn len(self) -> usize;
}

impl<T> HasLength for &Vec<T> {
    fn len(self) -> usize {
        Vec::len(self)
    }
}

impl<T> HasLength for &[T] {
    fn len(self) -> usize {
        <[T]>::len(self)
    }
}

// And so on...

fn longer<T: HasLength + Copy>(x: T, y: T) -> T {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

游樂場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM