Syntax 如何指定选项的生存期<;关闭>;?
我试图在结构上放置一个字段,该字段应包含一个Syntax 如何指定选项的生存期<;关闭>;?,syntax,rust,lifetime,Syntax,Rust,Lifetime,我试图在结构上放置一个字段,该字段应包含一个选项 然而,Rust对我大喊大叫,说我必须指定生命周期(并不是说我真的会这么做)。我正在尽我最大的努力去做,但是Rust对我的想法从来都不满意。请查看我的内联注释,以查找我得到的编译错误 struct Floor{ handler: Option<|| ->&str> //this gives: missing lifetime specifier //handler: Option<||: 'a>
选项
然而,Rust对我大喊大叫,说我必须指定生命周期(并不是说我真的会这么做)。我正在尽我最大的努力去做,但是Rust对我的想法从来都不满意。请查看我的内联注释,以查找我得到的编译错误
struct Floor{
handler: Option<|| ->&str> //this gives: missing lifetime specifier
//handler: Option<||: 'a> // this gives: use of undeclared lifetime name `'a`
}
impl Floor {
// I guess I need to specify life time here as well
// but I can't figure out for the life of me what's the correct syntax
fn get(&mut self, handler: || -> &str){
self.handler = Some(handler);
}
}
结构层{
handler:Option&str>//这给出了:缺少生存期说明符
//处理程序:选项(&str){
self.handler=Some(handler);
}
}
这有点棘手
一般来说,当您在数据结构中存储借用的引用(即&
类型)时,您需要命名其生存期。在本例中,您使用的'a
是正确的,但必须在当前范围中引入该'a
。这与引入类型变量的方式相同。因此,要定义您的楼层
结构:
struct Floor<'a> {
handler: Option<|| -> &'a str>
}
从技术上讲,您可以将其缩短为一个生命周期,并使用
|:'a->&'a str
,但这意味着返回的&str
始终与闭包本身具有相同的生命周期,我认为这是一个错误的假设。回答当前生锈版本1.x
:
有两种可能得到您想要的结果:一种是未装箱的闭包,另一种是装箱的闭包。未绑定的闭包速度非常快(大多数情况下,它们是内联的),但它们向结构添加了一个类型参数。盒式闭包在这里增加了一点自由度:它们的类型被一级间接删除,遗憾的是速度有点慢
我的代码有一些示例函数,因此有点长,请原谅;)
无框闭包
完整代码:
struct Floor<F>
where F: for<'a> FnMut() -> &'a str
{
handler: Option<F>,
}
impl<F> Floor<F>
where F: for<'a> FnMut() -> &'a str
{
pub fn with_handler(handler: F) -> Self {
Floor {
handler: Some(handler),
}
}
pub fn empty() -> Self {
Floor {
handler: None,
}
}
pub fn set_handler(&mut self, handler: F) {
self.handler = Some(handler);
}
pub fn do_it(&mut self) {
if let Some(ref mut h) = self.handler {
println!("Output: {}", h());
}
}
}
fn main() {
let mut a = Floor::with_handler(|| "hi");
a.do_it();
let mut b = Floor::empty();
b.set_handler(|| "cheesecake");
b.do_it();
}
type HandlerFun = Box<for<'a> FnMut() -> &'a str>;
struct Floor {
handler: Option<HandlerFun>,
}
impl Floor {
pub fn with_handler(handler: HandlerFun) -> Self {
Floor {
handler: Some(handler),
}
}
pub fn empty() -> Self {
Floor {
handler: None,
}
}
pub fn set_handler(&mut self, handler: HandlerFun) {
self.handler = Some(handler);
}
pub fn do_it(&mut self) {
if let Some(ref mut h) = self.handler {
println!("Output: {}", h());
}
}
}
fn main() {
let mut a = Floor::with_handler(Box::new(|| "hi"));
a.do_it();
let mut b = Floor::empty();
b.set_handler(Box::new(|| "cheesecake"));
b.do_it();
}
这有点慢,因为我们对每个闭包都有一个堆分配,当调用一个装箱闭包时,大多数时候都是间接调用(CPU不喜欢间接调用…)
但是
Floor
struct没有类型参数,因此您可以拥有其中的Vec
。您还可以删除b.set_处理程序(Box::new(| |“cheesecake”)代码>它仍然可以工作。哦,哇,这让我头晕目眩。人们应该习惯这种疯狂吗-S@Christoph:如果你认为这很疯狂,试着实际使用你的楼层结构……是的,我已经遇到了下一个麻烦。:)我做错了吗?喜欢不写惯用的锈代码吗?@Christoph,希望在什么时候登陆,闭包的情况会变得更好。例如,您可以在一个结构中存储一个堆装箱闭包,而不需要指定生存期。@shaman.sir,您可能想就此提出一个单独的问题,但简而言之,可以存储在结构中的一种类型的自有装箱闭包可以如下所示,例如:Box String+'static>
。
struct Floor<F>
where F: for<'a> FnMut() -> &'a str
{
handler: Option<F>,
}
impl<F> Floor<F>
where F: for<'a> FnMut() -> &'a str
{
pub fn with_handler(handler: F) -> Self {
Floor {
handler: Some(handler),
}
}
pub fn empty() -> Self {
Floor {
handler: None,
}
}
pub fn set_handler(&mut self, handler: F) {
self.handler = Some(handler);
}
pub fn do_it(&mut self) {
if let Some(ref mut h) = self.handler {
println!("Output: {}", h());
}
}
}
fn main() {
let mut a = Floor::with_handler(|| "hi");
a.do_it();
let mut b = Floor::empty();
b.set_handler(|| "cheesecake");
b.do_it();
}
type HandlerFun = Box<for<'a> FnMut() -> &'a str>;
struct Floor {
handler: Option<HandlerFun>,
}
impl Floor {
pub fn with_handler(handler: HandlerFun) -> Self {
Floor {
handler: Some(handler),
}
}
pub fn empty() -> Self {
Floor {
handler: None,
}
}
pub fn set_handler(&mut self, handler: HandlerFun) {
self.handler = Some(handler);
}
pub fn do_it(&mut self) {
if let Some(ref mut h) = self.handler {
println!("Output: {}", h());
}
}
}
fn main() {
let mut a = Floor::with_handler(Box::new(|| "hi"));
a.do_it();
let mut b = Floor::empty();
b.set_handler(Box::new(|| "cheesecake"));
b.do_it();
}