RustでStringまたは&strを受け入れる関数を作成する

翻訳者から


この記事は、文字列データ型を例として使用して、いくつかの有用なライブラリー特性と関連するRustイディオムの使用を説明する一連の投稿の1つです。 この情報は、Rustの初心者や、この言語で既に少し試してみたが、特徴の豊富なライブラリをまだ完全にマスターしていない人にとって間違いなく有用です。 元の投稿には、コードにいくつかの不正確さとタイプミスが含まれていますが、翻訳プロセス中に修正しようとしましたが、一般に、説明されたアプローチと動機は正しく、「ベストプラクティス」の概念に適しているため、注意が必要です。


私の最後の投稿で、文字列引数を取る関数の優先型として&strを使用することについて多くのことを話しました。 投稿の終わりに向かって、 Stringを使用するほうが適切な場合と、構造体( struct )でいつ&strを使用するかについて説明しました。 全体的なアドバイスは良いと思いますが、場合によってはString代わりに&strを使用することは最適でStringません。 そのような場合、別の戦略が必要です。

文字列型の文字列フィールドを持つ構造


以下のPerson構造を見てください。 説明のために、 nameフィールドに実際のニーズがあると仮定します。 &str代わりにStringを使用することにしました。

 struct Person { name: String, } 

次に、 new()メソッドを実装する必要があります。 前の投稿のアドバイスに従って、 &strタイプを優先し&str

 impl Person { fn new(name: &str) -> Person { Person { name: name.to_string() } } } 

この例は、 new()メソッドで.to_string()を呼び出すことを忘れない場合にのみ機能しますnew() 実際、 to_string()メソッドは文字列をto_owned()するためにかなり重いテキストフォーマットライブラリを使用し、 to_owned()文字列のスライス&strを新しいStringオブジェクトに直接コピーするだけですto_owned()約transl。) 。 ただし、関数の使いやすさは貧弱です。 文字列リテラルを使用する場合、 Person::new("Herman")ような新しいPersonエントリを作成できます。 ただし、 String所有する文字列が既にある場合は、そのリンクを取得する必要があります。

 let name = "Herman".to_string(); let person = Person::new(name.as_ref()); 

まるで歩いているようです。 最初にStringas_ref() 、次にas_ref()を呼び出してそれを&strに変換してから、 new()メソッド内でStringに戻します。 fn new(name: String) -> PersonようなString使用に戻ることもできますが、文字列リテラルからPersonを作成する場合は、ユーザーに.to_string()を常に呼び出さ.to_string()必要があります。

コンバージョンへ


Intoトレイトで関数を使いやすくすることができます 。 この特性は、 &strを自動的にString変換し&str 。 すでにStringがある場合、変換は行われません。

 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()署名の構文は、わずかに異なります。 汎用型English )とEnglish )を使用して、一部のS型がString型のInto型を実装する必要があることをRustに説明します。 StringInto , 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/J274455/


All Articles