2015-07-10 15 views
9

Có cách nào để tránh gọi số .to_string() khi tôi cần một chuỗi không? Ví dụ:Cách tạo chuỗi trực tiếp?

fn func1(aaa: String) -> .... 

Và thay vì

func1("fdsfdsfd".to_string()) 

tôi có thể làm một cái gì đó như thế này:

func1(s"fdsfdsfd") 

Trả lời

10

TL; DR:

Tính đến Rust 1.9, str::to_string, str::to_owned, String::from, str::into tất cả đều có đặc tính hiệu suất tương tự. Sử dụng bất cứ điều gì bạn thích.


Cách rõ ràng và thành ngữ nhất để chuyển đổi một lát string (&str) đến một chuỗi nước (String) là sử dụng ToString::to_string. Điều này làm việc cho bất kỳ loại nào thực hiện Display. Điều này bao gồm các lát chuỗi, nhưng cũng là số nguyên, địa chỉ IP, đường dẫn, lỗi, v.v.

Trước khi Rust 1,9, triển khai strto_string tận dụng số formatting infrastructure. Trong khi nó hoạt động, nó là quá mức cần thiết và không phải là con đường hiệu quả nhất.

Giải pháp nhẹ hơn là sử dụng ToOwned::to_owned, được triển khai cho các loại có cặp "mượn" và cặp "sở hữu". Đó là implemented in an efficient manner.

Một giải pháp nhẹ khác là sử dụng Into::into để tận dụng From::from. Đây cũng là implemented efficiently.


Đối trường hợp cụ thể của bạn, điều tốt nhất để làm là chấp nhận một &str, như thirtythreeforty answered. Sau đó, bạn cần phải thực hiện số không phân bổ, đó là kết quả tốt nhất.

Nói chung, tôi có thể sử dụng into nếu tôi cần tạo chuỗi được phân bổ - chỉ có 4 chữ cái dài^_ ^. Khi trả lời các câu hỏi về Stack Overflow, tôi sẽ sử dụng to_owned vì nó rõ ràng hơn nhiều về những gì đang xảy ra.

+0

vì vậy cái nào để sử dụng cho "fdsfd"? – imatahi

+0

@imatahi được cập nhật. – Shepmaster

12

Không, phương pháp str::to_string() là cách kinh điển của việc tạo ra một String từ một &'static str (một chuỗi chữ). Tôi thậm chí thích nó vì lý do bạn không thích nó: đó là một chút tiết. Bởi vì nó liên quan đến việc phân bổ đống, bạn nên suy nghĩ kỹ trước khi gọi nó trong các trường hợp như vậy. Cũng lưu ý rằng kể từ Rust gained impl specialization, str::to_string không chậm hơn str::to_owned hoặc ilk của nó.

Tuy nhiên, những gì bạn thực sự muốn ở đây là func1 có thể dễ dàng được chuyển bất kỳ chuỗi nào, có thể là &str hoặc String. Bởi vì String sẽ Deref thành một số &str, bạn có thể có func1 chấp nhận một &str, do đó tránh phân bổ Chuỗi hoàn toàn. Xem ví dụ này (playground):

fn func1(s: &str) { 
    println!("{}", s); 
} 

fn main() { 
    let allocated_string: String = "owned string".to_string(); 
    func1("static string"); 
    func1(&allocated_string); 
} 
+2

'to_string' vẫn được sử dụng bởi mặc định, ngay cả khi đó là kỹ thuật chậm hơn một chút. Với chuyên môn hóa nó sẽ không được, mặc dù. –

+1

theo alex crichton, 'to_string' là cách thành ngữ để chuyển đổi' str' thành 'Chuỗi': https://github.com/rust-lang/rust/pull/26176 –

+0

@steveklabnik tại liên kết GitHub đó, bạn nói rằng "' to_owned() 'là tốt hơn cho mã chung." Tại sao vậy? – thirtythreeforty

-1

Bây giờ tôi thích mạnh hơn to_owned() cho chuỗi ký tự trên một trong hai số to_string() hoặc into().

Sự khác nhau giữa String&str là gì? Một câu trả lời không đạt yêu cầu là "một là một chuỗi và chuỗi kia không phải là một chuỗi" bởi vì rõ ràng cả hai đều là các chuỗi. Lấy một cái gì đó mà là một chuỗi và chuyển đổi nó thành một chuỗi bằng cách sử dụng to_string() có vẻ như nó bỏ lỡ lý do tại sao chúng tôi đang làm điều này ở nơi đầu tiên, và quan trọng hơn bỏ lỡ cơ hội để tài liệu này cho độc giả của chúng tôi.

Sự khác biệt giữa Chuỗi và & str là địa chỉ được sở hữu và một tài sản không thuộc sở hữu. Sử dụng to_owned() hoàn toàn nắm bắt được lý do chuyển đổi được yêu cầu tại một vị trí cụ thể trong mã của chúng tôi.

struct Wrapper { 
    s: String 
} 

// I have a string and I need a string. Why am I doing this again? 
Wrapper { s: "s".to_string() } 

// I have a borrowed string but I need it to be owned. 
Wrapper { s: "s".to_owned() } 

Không nếu bạn tinh thần đọc to_string như to_String

https://users.rust-lang.org/t/to-string-vs-to-owned-for-string-literals/1441/6?u=rofrol

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