我的Rust代码出现了”无法返回引用临时值”错误。为什么以及在哪里?

huangapple go评论78阅读模式
英文:

My Rust code has "cannot return value referencing temporary value" error. Why and where?

问题

I created a function to get the file name of the current exe (not the full path).

fn exe_name() -> Result<Option<&'static OsStr>, Box<dyn Error>> {
    Ok(env::current_exe()?.file_name())
}

But the code won't compile:

$ cargo clippy
...
error[E0515]: cannot return value referencing temporary value
 --> src/libs.rs:8:5
  |
8 |     Ok(env::current_exe()?.file_name())
  |     ^^^-------------------^^^^^^^^^^^^^
  |     |  |
  |     |  temporary value created here
  |     returns a value referencing data owned by the current function

For more information about this error, try `rustc --explain E0515`.
...

I've checked rustc --explain E0515 and searched on the internet (and StackOverflow too). Basically, I can't return a reference to a local variable because it will get destroyed when the function ends. Still, I don't know where the problematic part of my code is. Can you explain it?

Oh, I have tried this code that still didn't work:

Ok(env::current_exe()?.to_owned().file_name())
Ok(env::current_exe()?.clone().file_name())
英文:

Note: I'm still new to Rust

I created a function to get the file name of the current exe (not the full path).

fn exe_name() -&gt; Result&lt;Option&lt;&amp;&#39;static OsStr&gt;, Box&lt;dyn Error&gt;&gt; {
    Ok(env::current_exe()?.file_name())
}

But the code won't compile:

$ cargo clippy
...
error[E0515]: cannot return value referencing temporary value
 --&gt; src/libs.rs:8:5
  |
8 |     Ok(env::current_exe()?.file_name())
  |     ^^^-------------------^^^^^^^^^^^^^
  |     |  |
  |     |  temporary value created here
  |     returns a value referencing data owned by the current function

For more information about this error, try `rustc --explain E0515`.
...

I've checked rustc --explain E0515 and search on internet (and StackOverflow too), so basically I can't return a reference to a local var, because it'll get destroyed when the function ends. Still, I dont' know where are actually the problematic part of my code. Can you explain about it?

Oh, I have tried this code that still didn't work:

Ok(env::current_exe()?.to_owned().file_name())
Ok(env::current_exe()?.clone().file_name())

答案1

得分: 2

错误是因为current_exe返回PathBuf,它是一个owned value

当在PathBuf上调用file_name时,它引用了存储在PathBuf中的路径的一部分。因此,当函数返回时,引用不再引用任何拥有者拥有的数据。

这相当于

fn example() -&gt; &amp;str {
    let s = String::new(&quot;hello&quot;);
    &amp;s
}

你已经注意到你的函数的返回值需要某种生命周期,你已将其设置为`static,意味着整个程序的生命周期,这是不正确的。

那么file_name返回的生命周期实际上是什么?在这种情况下,生命周期是由exe_name函数返回的,因此它不能被返回。

要使函数工作,你需要将file_name的结果变成一个拥有的值,而不是current_exe

fn exe_name() -&gt; Result&lt;Option&lt;OsString&gt;, Box&lt;dyn Error&gt;&gt; {
    Ok(env::current_exe()?.file_name().map(|name| name.to_owned()))
}
英文:

The error is because current_exe returns PathBuf, witch is an owned value.

When file_name is called on PathBuf, it is refrencing a piece of the path stored in PathBuf. So when the function returned, the reference is no longer refrencing data owned by anything.

It is equivilent to

fn example() -&gt; &amp;str {
    let s = String::new(&quot;hello&quot;);
    &amp;s
}

You have noticed that the return value of your function needs some sort of lifetime witch you have set to `static, meaning the entire length of the program, witch is not correct.

So is that lifetime returned from file_name actually referring to?
In this case, the lifetime is one that is returned by the exe_name function, so it can not be returned.

To get your function working, you need to make the result of file_name an owned value, not current_exe.

fn exe_name() -&gt; Result&lt;Option&lt;OsString&gt;, Box&lt;dyn Error&gt;&gt; {
    Ok(env::current_exe()?.file_name().map(|name| name.to_owned()))
}

huangapple
  • 本文由 发表于 2023年5月26日 12:08:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76337609.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定