你可以强制Some(box |:|)到Option <box <fnonce <...>&gt;&gt;生锈?</box <fnonce <...>

时间:2014-11-09 13:15:17

标签: rust

根据标题。你能?或者它是否需要特征演员的中间步骤?

我意识到关闭改革尚未完全完成,并且存在许多漏洞。

然而,错误跟踪器是如此完全充满了错误和RFC以及过时和新票的链接,我很难用新的无箱封锁来了解游戏状态。< / p>

这有效:

#![feature(unboxed_closures, unboxed_closure_sugar)]
#![allow(dead_code, unused_variables)]

fn test(bar:Box<FnOnce<(int,), ()> + Send>) {
  bar.call_once((10,));
}

fn main() {
  let bar:Box<FnOnce<(int,), ()> + Send> = box |:x:int| { println!("Hi:{}", x); };
  test(bar);

  test(box |:x:int| { println!("Hi:{}", x); });
}

这有效:

#![feature(unboxed_closures, unboxed_closure_sugar)]
#![allow(dead_code, unused_variables)]

fn test2(mut bar:Option<Box<FnOnce<(int,), ()> + Send>>) {
  bar.take().unwrap().call_once((10,));
}

fn main() {
  let bar2:Box<FnOnce<(int,), ()> + Send> = box |:x:int| { println!("Hi:{}", x); };
  test2(Some(bar2));
}

然而,由于某种原因,这不起作用:

#![feature(unboxed_closures, unboxed_closure_sugar)]
#![allow(dead_code, unused_variables)]

fn test2(mut bar:Option<Box<FnOnce<(int,), ()> + Send>>) {
  bar.take().unwrap().call_once((10,));
}

fn main() {
  test2(Some(box |:x:int| { println!("Hi:{}", x); }));
}

错误:

foo.rs:21:9: 21:53 error: mismatched types: expected `core::option::Option<Box<core::ops::FnOnce<(int,), ()>+Send>>`, found `core::option::Option<Box<closure>>` (expected trait core::ops::FnOnce, found closure)
foo.rs:21   test2(Some(box |:x:int| { println!("Hi:{}", x); }));

所以,问:

1)上面的代码应该吗?或者Option<> / Some()是否意味着在这种背景下我无法理解的复杂事物?

2)如果是这样,是否有|:|糖和FnOnce类型之间隐式转换的开放票?

(因为https://github.com/rust-lang/rust/issues/18101似乎暗示应该这样做,这就是示例#1有效的原因,但是我已经完全失去了试图通过该元bug查找任何特定的bug来引用关闭糖)。

1 个答案:

答案 0 :(得分:5)

值得注意的是,这是特征对象和通用结构/枚举的一般属性,并不完全特定于未装箱的封闭,FnOnceOption|:|(尤其不是这个,因为它只是创建实现特定特征的价值的一种很好的方式。)

此外,最近的RFC #401是相关的。

  

1)上述代码是否有效?或者选项&lt;&gt; / Some()是否意味着在这种背景下我无法理解的复杂事物?

Box<FnOnce<..>>是一个特征对象,因此与Box<F>的非动态F: FnOnce<...>具有相同的表示或类型。从理论上讲,我们可以通过某些类型的枚举和结构来支持更高级的深度强制,但它不一定能够很好地/统一地发挥共同和反向差异。

在任何情况下,你都可以做一个普通的trait对象:

#![feature(unboxed_closures, unboxed_closure_sugar)]
#![allow(dead_code, unused_variables)]

fn test2(mut bar:Option<Box<FnOnce<(int,), ()> + Send>>) {
  bar.take().unwrap().call_once((10,));
}

fn main() {
  test2(Some((box |: x| println!("Hi:{}", x)) as Box<FnOnce(int)+Send>));
}

关于差异的说明,请考虑:

enum Option2<T> {
    Empty,
    One(fn() -> T)
}

也就是说,它既不存储也不存储返回T的函数。将Option2<Box<X>>投射到Option2<Box<Trait>>是什么意思?人们不能强行假装返回Box<X>的函数返回Box<Trait>类型的值。

  

2)如果是这样,是否有一个打开的票证,用于|:|之间的隐式转换糖和FnOnce类型?

|:|糖是FnOnce - 实施类型。 FnOnce是一种特质,强制就像任何其他特质对象一样发生。