[back]

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>って書こうね(一部例外を除いて)