如何将Option<&str>转换为&str?

3
我发现在变量的生命周期作用域方面,Option 有些令人困惑。我一直在尝试从 OptionSome 中提取基础值,就像下面这样的匹配模式:
let filename = match canonicalize(&PathBuf::from(filename)).unwrap().to_str() {
    Some(path) => path,
    _ => "",
};

// Later, I validate the string content 
if filename.is_empty() {
    do_something();
}

然而,这会抛出以下错误:
temporary value dropped while borrowed: borrow later used here 

文档没有详细说明如何将生命周期持久化到超出其初始化调用范围的位置。我看过 这里这里 的示例。这两个示例都意味着要么丢弃值,要么转换为 Option,而我都不想要。我只想在函数成功后获取底层的 &str 值。

我刚刚运行了您提供的链接中的代码,但出现了错误。您做了什么让它运行起来了吗? - Jarred Parr
抱歉,我的错,我弄乱了你的代码,让我在一分钟内解释一下... - rodrigo
1个回答

2

你的问题不在于Option本身,而是在于你的代码创建的临时变量。你的主要代码行比较长,所以让我们对它进行一些剖析:

let temp: PathBuf = conicalize(PathBuf::from(filename)).unwrap();
let filename: &str = temp.to_str();

现在,你稍后使用filename的代码就可以正常工作了。你可能会想知道为什么写临时变量会有所不同。答案是编译器创建的临时变量在包含它的语句结束时被销毁。
请注意,filename实际上是一个引用,因此必须有一个关联的生命周期,显然就是变量temp的生命周期。这意味着filename不能超过temp的生命周期。但在你的代码中,temp实际上不是一个具名变量,而是一个在行完成时就被销毁的临时变量,filename因此变得无法使用。
如果你阅读完整个编译器错误,你将看到一个提示:

note: consider using a let binding to create a longer lived value.

这正是建议你这样做的地方。
[1]: 如果你阅读PathBuf函数的定义:fn to_str<'a>(&'a self) -> Option<&'a str>(这里添加省略的生命周期以便清晰阅读),就能明白这一点。

我很好奇,这里t2是在哪里创建的? - Jarred Parr
@JarredParr:t2 实际上是我之前回答中的 temp,现在已经修复了。我不应该在深夜写作... - rodrigo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接