&v.to_string() がmatchの中でドロップしてしまっていることが原因でエラーが発生していると認識していますが、
その通りです。
いきなり話が脱線しますが、実はRustではToString
を実装することは推奨されておらず、代わりにstd::fmt::Display
を実装することが推奨されています。(Display
を実装すると、自動的にToString
も実装されます)
https://doc.rust-lang.org/stable/std/string/trait.ToString.html
ToString
shouldn’t be implemented directly: Display
should be implemented instead, and you get the ToString
implementation for free.
Display
を実装する際は自分でString
を構築する必要はなく、フォーマッターに対してprint!
マクロに良く似たwrite!
で書き込みます。その方法ですと今回のご質問のようなライフタイムのエラーには遭遇しないですみます。
とはいえ、ご質問のエラーも、別の、いろいろな場面で遭遇するはずですので、まずはご質問のコード(ToString
)のまま解決する方法を紹介して、そのあと、Display
を実装するコードをお見せします。
解決方法1
&v.to_string() がmatchの中でドロップしてしまっていることが原因
&str
をmatch
の外に持ち出せないのならmatch
の中でtext
に追記してしまえば解決します。
変更前
rust
1text += match self.field[x][y].placed_number{
2 Some(v) => &v.to_string(),//error[E0716]: temporary value dropped while borrowed
3 None => " ",
4};
変更後
rust
1match self.field[x][y].placed_number {
2 // match内でtextに追記すればライフタイムのエラーが起こらない
3 Some(v) => text += &v.to_string(),
4 None => text += " ",
5};
text +=
が2回繰り返されるので、あまりかっこいいやり方でないのはたしかです。
解決方法2
そもそも元のコードで&v.to_string()
としているのは、None
のときに&str
を返したいので、それに合わせるためだったと思います。std::borrow::Cow
で包むことで&str
のような借用する値とString
のような所有する値を1つの型に統一できます。
rust
1let s: Cow<'_, str> = match self.field[x][y].placed_number {
2 // StringをCow::Owned(..) に変換する
3 Some(v) => v.to_string().into(),
4 // &'static strをCow::Borrowed(..)に変換する
5 None => " ".into(),
6};
7text += &s;
Display
を実装する
Display
を実装する場合は以下のようなコードになります。なおご質問のコードではfor
ループを配列のインデックスx
とy
で回していますが、以下のように直接配列の要素を得る方が簡潔なコードになり、Rustらしい書き方になります。
rust
1use std::fmt;
2
3impl fmt::Display for NumberPlace {
4 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5 // lineは1行分のデータ。&[Grid; 9]型
6 for line in &self.field {
7 // cellは1マス分のデータ。&Grid型
8 for cell in line {
9 match cell.placed_number {
10 // print!マクロによく似たwrite!マクロでフォーマッターに書く
11 Some(v) => write!(f, "{}", v)?,
12 None => write!(f, " ")?,
13 };
14 }
15 writeln!(f)?;
16 }
17 Ok(())
18 }
19}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/09/25 11:10
2021/09/25 11:13
2021/09/25 11:25 編集