2023-05-03 12:00:39 +09:00
たとえばString
に対して何らかの操作をして、String
を返す関数を考えてみる。(&mutで渡せばいいじゃんってのは一旦無視する)
fn hoge(input: String) -> String {
input.push_str("hogehoge")
}
この場合もし&str
を渡したくなったら"なんちゃら".into()
だのString::from("どうたら")
だのしなければいけない。実際面倒。こういう時に(内部の処理との兼ね合いを踏まえて可能ならば)&str
で引数を定義してあげると(&)String
と&str
を受け入れられるようになる。&String
には&str
へのDeref
が定義されているので自動で型強制が入るからだ。
ただ、これだと複数の文字列を受け取りたいときに&
演算子が沢山になっちゃってなんか見た目が大変になると思う。問題はないんだろうけどちょっとモヤるというか。
let a = String::from("aaa")
let b = String::from("bbb")
...
let z = String::from("zzz")
let result = hoge::fuga(&a, &b, ... &z)
極端な例だとこうなると思うんだけど。
うーん結局impl AsRef<str>
になるのかなぁ。書くの一番面倒だけど一番汎用性もあるよねこれ。さすがにトレイト境界使ってるだけはある
ただしOptionで包んでるとtype annotation必要になるからそこはアレだけど、そもそもOptionでかつString | &str | あるいはimpl AsRef<str>
な引数が必要な場面ってほぼないと思うからおとなしくどっちかにしとけという事か。
結論:面倒くさがらずにAsRef<str>
って書こうね(一部例外を除いて)