2016-12-16 22 views
11

Mỗi Steve Klabnik's writeup in the pre-Rust 1.0 documentation on the difference between String and &str, trong Rust, bạn nên sử dụng &str trừ khi bạn thực sự cần có quyền sở hữu trên String. Tương tự, bạn nên sử dụng tham chiếu đến lát cắt (&[]) thay vì Vec s trừ khi bạn thực sự cần quyền sở hữu đối với số Vec.Chuyển đổi Vec <String> thành một slice & str trong Rust?

Tôi có một Vec<String> và tôi muốn viết một hàm có sử dụng chuỗi này của chuỗi và nó không cần phải sở hữu đối với Vec hoặc String trường hợp, chức năng đó nên &[&str]? Nếu vậy, cách tốt nhất để tham khảo Vec<String> là gì vào &[&str]? Hay, liệu sự ép buộc này có quá mức không?

Trả lời

13

Bạn có thể tạo một hàm mà chấp nhận cả &[String]&[&str] sử dụng AsRef trait:

fn test<T: AsRef<str>>(inp: &[T]) { 
    for x in inp { print!("{} ", x.as_ref()) } 
    println!(""); 
} 

fn main() { 
    let vref = vec!["Hello", "world!"]; 
    let vown = vec!["May the Force".to_owned(), "be with you.".to_owned()]; 
    test(&vref); 
    test(&vown); 
} 
+1

Tôi nghĩ đây là câu trả lời mà OP đang tìm kiếm, vì nó cho phép sử dụng slice mà không cần phân bổ không cần thiết. Cách tiếp cận này thậm chí còn hữu ích hơn khi chấp nhận một lát 'AsRef '- bạn muốn hàm chấp nhận tất cả' & [& str] ',' & [String] ',' & [Đường dẫn] 'và' & [PathBuf ] ', không phân bổ bộ nhớ mới. – user4815162342

4

Điều này thực sự là không thể nếu không có phân bổ bộ nhớ .

Vấn đề là, chuyển từ String thành &str không chỉ xem các bit theo một ánh sáng khác; String&str có bố cục bộ nhớ khác nhau và do đó chuyển từ bố cục này sang chế độ khác yêu cầu tạo đối tượng mới. Điều tương tự cũng áp dụng cho Vec&[]

Do đó, trong khi bạn có thể đi từ Vec<T> để &[T], và do đó Vec<String>-&[String], bạn không thể trực tiếp đi Vec<String>-&[&str]:

  • hoặc chấp nhận để sử dụng &[String]
  • hoặc phân bổ Vec<&str> mới tham chiếu Vec đầu tiên và chuyển đổi thành một &[&str]

Việc quy đổi yêu cầu là không thể, tuy nhiên sử dụng Generics và AsRef<str> ràng buộc như trong @aSpex 's câu trả lời bạn nhận được một khai báo hàm hơi dài dòng hơn với sự linh hoạt bạn đã yêu cầu.

+0

Cảm ơn, Matthieu. Đối với trường hợp của tôi ngay bây giờ, tôi nghĩ rằng tôi sẽ đi với '& [String]' kể từ khi tôi tưởng tượng phân bổ một mới 'Vec <&str>' phải chịu thêm công việc. –

+1

@DonRowe: Nó phát sinh thêm một phân bổ (O (1) nhưng có khả năng tốn kém) + chuyển đổi (O (n)). –

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