Rust:returns 引用当前函数拥有的数据的值
Rust: returns a value referencing data owned by the current function
我有一小段代码。为什么第二个编译失败?
fn apply (&self, text: Text) -> Text {
// works fine
let mut data = String::new();
for c in text.data.chars() {
let c = *self.mapping.get(&c).unwrap_or(&c);
data.push(c);
}
return Text {
data,
};
// not compile
return Text {
data: text.data.chars().map(|c| self.mapping.get(&c).unwrap_or(&c)).collect(),
};
}
编译器会告诉您确切原因(这就是为什么阅读和发布编译错误很有用:
8 | data: text.data.chars().map(|c| self.mapping.get(&c).unwrap_or(&c)).collect()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--^
| | |
| | `c` is borrowed here
| returns a value referencing data owned by the current function
如果输入 char
不存在于映射中,它 returns 对局部变量的引用是不允许的...然后引用将被保留 dangling, 生锈是不允许的。
解决方案与“工作正常”版本中使用的解决方案完全相同:取消引用回调的结果,这将 Copy
&char
到 char
,即拥有,因此可以无后顾之忧地归还:
Text {
data: text.data.chars().map(|c| *self.mapping.get(&c).unwrap_or(&c)).collect()
}
或者您可以 copied
HashMap::get
的结果产生 Option<char>
,然后 unwrap_or
到 char
,解决问题出于同样的原因:
Text {
data: text.data.chars().map(|c| self.mapping.get(&c).copied().unwrap_or(c)).collect()
}
我有一小段代码。为什么第二个编译失败?
fn apply (&self, text: Text) -> Text {
// works fine
let mut data = String::new();
for c in text.data.chars() {
let c = *self.mapping.get(&c).unwrap_or(&c);
data.push(c);
}
return Text {
data,
};
// not compile
return Text {
data: text.data.chars().map(|c| self.mapping.get(&c).unwrap_or(&c)).collect(),
};
}
编译器会告诉您确切原因(这就是为什么阅读和发布编译错误很有用:
8 | data: text.data.chars().map(|c| self.mapping.get(&c).unwrap_or(&c)).collect()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--^
| | |
| | `c` is borrowed here
| returns a value referencing data owned by the current function
如果输入 char
不存在于映射中,它 returns 对局部变量的引用是不允许的...然后引用将被保留 dangling, 生锈是不允许的。
解决方案与“工作正常”版本中使用的解决方案完全相同:取消引用回调的结果,这将 Copy
&char
到 char
,即拥有,因此可以无后顾之忧地归还:
Text {
data: text.data.chars().map(|c| *self.mapping.get(&c).unwrap_or(&c)).collect()
}
或者您可以 copied
HashMap::get
的结果产生 Option<char>
,然后 unwrap_or
到 char
,解决问题出于同样的原因:
Text {
data: text.data.chars().map(|c| self.mapping.get(&c).copied().unwrap_or(c)).collect()
}