2015-07-15 14 views
10

Khi hàm lấy một chuỗi giá trị làm tham số, nó có được coi là kiểu tốt để chấp nhận một Iterator<T> thay vì Vec<T>?Lấy một `Iterator` thay vì` Vec` khi có thể?

Bằng cách này, người gọi có thể tự quyết định cách thức chuỗi được lưu trữ (bên trong Vec, [T; N] hoặc bất kỳ thứ gì khác, thực sự là Option<T> sẽ có thể!). Ngoài ra, điều này giúp loại bỏ sự cần thiết phải chuyển đổi bất cứ điều gì bạn có thành một Vec, và cũng có thể, sau khi áp dụng một số sửa đổi Iterator, không có .collect() là cần thiết! Vì vậy, nó cũng nên nhanh hơn!

Tôi có thiếu cái gì hay đây là cách thực hiện?

Trả lời

11

Chức năng như bạn mô tả thường sẽ mang lại một cách tổng quát IntoIterator<Item = T>; do đó, nó có thể chấp nhận cả hai số Iterator<T>Vec<T> làm đầu vào.

Điều này cũng có thể được kết hợp với các kỹ thuật khác; ví dụ, phương pháp này concat sẽ chấp nhận một &[&str] (và do đó &Vec<&str> bởi auto deref/ref ép buộc), &[String] (và do đó &Vec<String>), một iterator &str, một iterator String, vân vân:

use std::borrow::Borrow; 

fn concat<T: Borrow<str>, Iter: IntoIterator<Item = T>>(iter: Iter) -> String { 
    iter.into_iter() // -> impl Iterator<Item = T> 
     .map(|s| s.borrow()) // -> impl Iterator<Item = &str> 
     .collect() // -> String 
} 

(Ví dụ cụ thể này thực sự sẽ phù hợp hơn với SliceConcatExt, bởi vì nó có thể tính toán kết quả cuối cùng sẽ ở phía trước bao lâu và do đó phân bổ chuỗi dài đúng tất cả cùng một lúc, nhưng nó chỉ là một bằng chứng về khái niệm và nhiều kỹ thuật ưa thích có thể được kết hợp.)

Các vấn đề liên quan