The article is one of a series of posts telling about the use of some useful library types and the associated Rust idioms using the example of string data types. The information is undoubtedly useful both for beginning Rust programmers, and for those who have already managed to try themselves a little in this language, but have not quite gotten to know the rich library of types. The original post contains several inaccuracies and typos in the code, which I tried to correct during the translation process, but in general, the described approaches and motivation are correct, suitable for the concept of βbest practicesβ, and therefore deserve attention.&str as the preferred type for functions that take string arguments. Toward the end of the post, we discussed when it is better to use a String , and when &str in structures ( struct ). Although I think that in general the advice is good, but in some cases using &str instead of String not optimal. For such cases, we need another strategy.Person structure below. For the purposes of our discussion, we assume that there is a real need in the name field. We will decide to use String instead of &str . struct Person { name: String, } new() method. Following the advice from the previous post, we prefer the &str type: impl Person { fn new(name: &str) -> Person { Person { name: name.to_string() } } } .to_string() call in the new() method (In fact, itβs better to use the to_owned() method, because the to_string() method uses a rather heavy text formatting library to place a string in memory to_owned() simply copies the string cut &str directly to the new String object - approx . However, the usability of the function leaves much to be desired. If we use a string literal, we can create a new Person record like this: Person::new("Herman") . But if we already have the owning String String , then we need to get a link to it: let name = "Herman".to_string(); let person = Person::new(name.as_ref()); String , then we call as_ref() to turn it into &str , only then to turn it back into a String inside the new() method. We could go back to using a String , like fn new(name: String) -> Person , but then we would have to force the user to constantly call .to_string() if he wants to create a Person from a string literal.&str to String . If we already have a String , then there will be no conversion. struct Person { name: String } impl Person { fn new<S: Into<String>>(name: S) -> Person { Person { name: name.into() } } } fn main() { let person = Person::new("Herman"); let person = Person::new("Herman".to_string()); } new() signature is now slightly different. We use generic types ( English ) and types ( English ) to explain to Rust that some type S must implement the type Into for type String . The String type implements Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( ) Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( )Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( )Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( ) Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( ) Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( )Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( )Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( )Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( )Into , String . &str Into .to_string() ( β . .) , new() . .to_string() , . , Into , β . Rust (.) .
, , . , , , String , &str . , fn new<S: Into>(name: S) -> Person β , , . , , Into . , Rust. , . , , crates.io. , , Rust .
Person::new()
where , , , , :
struct Person { name: String, } impl Person { fn new<S>(name: S) -> Person where S: Into<String> { Person { name: name.into() } } }
String &str Rust ( ) Rust, String &str ( )Source: https://habr.com/ru/post/274455/
All Articles