関数パラメーターから派生した文字列を操作して、その操作の結果を返そうとしています:
fn main() {
let a: [u8; 3] = [0, 1, 2];
for i in a.iter() {
println!("{}", choose("abc", *i));
}
}
fn choose(s: &str, pad: u8) -> String {
let c = match pad {
0 => ["000000000000000", s].join("")[s.len()..],
1 => [s, "000000000000000"].join("")[..16],
_ => ["00", s, "0000000000000"].join("")[..16],
};
c.to_string()
}
ビルド時に、次のエラーが発生します。
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
--> src\main.rs:9:9
|
9 | let c = match pad {
| ^ `str` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `str`
= note: all local variables must have a statically known size
ここで何が問題になっていますか?それを修正する最も簡単な方法は何ですか?
TL; DRstr
を使用せず、&str
を使用します。参照は重要です。
問題はこれに簡略化できます:
fn main() {
let demo = "demo"[..];
}
&str
をスライスしようとしています(ただし、String
、&[T]
、Vec<T>
などについても同様です)。結果。つまり、demo
の型はstr
になります。修正するには、&
を追加します:
let demo = &"demo"[..];
より広い例では、String
ステートメント内に(match
を介して)割り当てられたjoin
を作成し、参照を返そうとしているという事実にも遭遇しています。それに。 String
はmatch
の最後にドロップされ、すべての参照が無効になるため、これは許可されません。別の言語では、これはメモリの安全性を損なう可能性があります。
潜在的な修正の1つは、作成されたString
を関数の期間保存して、新しい文字列が作成されるまで割り当てが解除されないようにすることです。
fn choose(s: &str, pad: u8) -> String {
let tmp;
match pad {
0 => {
tmp = ["000000000000000", s].join("");
&tmp[s.len()..]
}
1 => {
tmp = [s, "000000000000000"].join("");
&tmp[..16]
}
_ => {
tmp = ["00", s, "0000000000000"].join("");
&tmp[..16]
}
}.to_string()
}
編集上、おそらくこの関数を書くためのより効率的な方法があるでしょう。 フォーマット機構 には、文字列をパディングするためのオプションがあります。新しい文字列を作成せずに、join
から返された文字列を単に切り捨てることもできます。
それが何を意味するのかを簡潔に説明することは困難です。 Rustには、unsizedのタイプがいくつかあります。最も一般的なタイプは、str
および[T]
です。 &str
または&[T]
。これらのタイプは、Box<str>
またはArc<[T]>
と表示されることもあります。共通点は、常にこれらのタイプがある種のリファレンス。
これらのタイプにはサイズがないため、スタックの変数に格納することはできません。コンパイラは、それらのために予約するスタックスペースの量を知りません。それがエラーメッセージの本質です。
以下も参照してください。