Open10
cannot return value referencing local data
X cargo run rhb.json 'Slide (5).png'
Compiling test-app01 v0.1.0 (/home/botamotch/Git/botamotch/Rust/test-app01)
error[E0515]: cannot return value referencing local data `sheet.cells`
--> src/main.rs:56:5
|
44 | let cell: &Cell = sheet
| _______________________-
45 | | .cells
46 | | .get(framename)
| |_______________________- `sheet.cells` is borrowed here
...
56 | Ok(&cell)
| ^^^^^^^^^ returns a value referencing data owned by the current function
For more information about this error, try `rustc --explain E0515`.
error: could not compile `test-app01` (bin "test-app01") due to previous error
ローカルデータを参照している値を返すことはできません
関数が所有するデータを参照する値を返しています
的な
こんなコードで
#[derive(Deserialize, Clone)]
pub struct Sheet {
frames: HashMap<String, Cell>,
}
#[derive(Deserialize, Clone)]
struct Cell {
frame: RectSheet,
}
impl Cell {
fn copy(&self) -> Cell {
Cell {
frame: RectSheet {
x: self.frame.x,
y: self.frame.y,
w: self.frame.w,
h: self.frame.h,
},
}
}
}
fn bar<'a>(filename: &'a str, framename: &'a str) -> Result<&'a Cell> {
let mut file = std::fs::File::open(filename).map_err(|e| anyhow!(e))?;
let mut s = String::new();
file.read_to_string(&mut s).map_err(|e| anyhow!(e))?;
let sheet: Sheet = serde_json::from_str(&s).map_err(|e| anyhow!(e))?;
let cell: &Cell = sheet
.frames
.get(framename)
.ok_or_else(|| anyhow!("frame not found"))?;
Ok(cell)
}
こんな感じのエラーが出る
X cargo run rhb.json 'Slide (5).png'
Compiling test-app01 v0.1.0 (/home/botamotch/Git/botamotch/Rust/test-app01)
error[E0515]: cannot return value referencing local data `sheet.frames`
--> src/main.rs:86:5
|
81 | let cell: &Cell = sheet
| _______________________-
82 | | .frames
83 | | .get(framename)
| |_______________________- `sheet.frames` is borrowed here
...
86 | Ok(cell)
| ^^^^^^^^ returns a value referencing data owned by the current function
For more information about this error, try `rustc --explain E0515`.
error: could not compile `test-app01` (bin "test-app01") due to previous error
コピーを作る関数を実装してエラーは回避した。多コピーの現在を読め
impl Cell {
fn copy(&self) -> Cell {
Cell {
frame: RectSheet {
x: self.frame.x,
y: self.frame.y,
w: self.frame.w,
h: self.frame.h,
},
}
}
}
fn foo(filename: &str, framename: &str) -> Result<Cell> {
let mut file = std::fs::File::open(filename).map_err(|e| anyhow!(e))?;
let mut s = String::new();
file.read_to_string(&mut s).map_err(|e| anyhow!(e))?;
let sheet: Sheet = serde_json::from_str(&s).map_err(|e| anyhow!(e))?;
Ok(sheet
.frames
.get(framename)
.ok_or_else(|| anyhow!("frame not found"))?
.copy())
}
ここを読め
まさにこれじゃん。草
fn main() {
{
let r;
{
let x = 5;
r = &x;
}
println!("r: {}", r);
}
}
$ cargo run
Compiling chapter10 v0.1.0 (file:///projects/chapter10)
error[E0515]: cannot return value referencing local variable `result`
(エラー[E0515]: ローカル変数`result`を参照している値は返せません)
--> src/main.rs:11:5
|
11 | result.as_str()
| ------^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| `result` is borrowed here
| (現在の関数に所有されているデータを参照する値を返しています
| `result`はここで借用されています)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0515`.
error: could not compile `chapter10`.
To learn more, run the command again with --verbose.
ダングリング参照を変えてくれるようなライフタイム引数を指定する手段はなく、 コンパイラは、ダングリング参照を生成させてくれません。今回の場合、最善の修正案は、 (呼び出し先ではなく)呼び出し元の関数に値の片付けをさせるために、参照ではなく所有されたデータ型を返すことでしょう。
もしかしたらコピーメソッドを実装して解決する方法は最善だったのかもしれない
参照を使用する関数や構造体にはライフタイム引数を指定する必要がある。
にもかかわらずこのコードはコンパイル可能。予測可能なケースではライフタイムが省略可能なときもある。
fn first_word(s: &str) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
&s[..]
}
これと同じ
fn first_word<'a>(s: &'a str) -> &'a str {
これがわかればジェネリックな型引数、トレイト境界、ライフタイム指定についてりかいしているということになるらしい。が、トレイト境界がまだよくわからん。ちょっとづつ理解していこう
fn longest_with_an_announcement<'a, T>(
x: &'a str,
y: &'a str,
ann: T,
) -> &'a str
where
T: Display,
{
println!("Announcement! {}", ann);
if x.len() > y.len() {
x
} else {
y
}
}