Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 对于<&燃气轮机;语法不同于常规的生存期界限?_Rust - Fatal编程技术网

Rust 对于<&燃气轮机;语法不同于常规的生存期界限?

Rust 对于<&燃气轮机;语法不同于常规的生存期界限?,rust,Rust,考虑以下代码: trait Trait<T> {} fn foo<'a>(_b: Box<dyn Trait<&'a usize>>) {} fn bar(_b: Box<dyn for<'a> Trait<&'a usize>>) {} trait{} fn foo>){} fn条(_b:Box>){ 函数foo和bar似乎都接受一个框,因为语法被称为高等级特征界限(HRTB),它的引入实

考虑以下代码:

trait Trait<T> {}

fn foo<'a>(_b: Box<dyn Trait<&'a usize>>) {}
fn bar(_b: Box<dyn for<'a> Trait<&'a usize>>) {}
trait{}
fn foo>){}
fn条(_b:Box>){
函数
foo
bar
似乎都接受一个
,因为
语法被称为高等级特征界限(HRTB),它的引入实际上主要是因为闭包

简而言之,
foo
bar
之间的区别在于,在
foo()
中,内部
usize
引用的生存期由函数的调用方提供,而在
bar()
中,相同的生存期由函数本身提供。这种区别对于
foo
/
bar
的实现非常重要

但是,在这种特殊情况下,当
Trait
没有使用类型参数的方法时,这种区别是没有意义的,因此让我们想象一下
Trait
如下所示:

trait Trait<T> {
    fn do_something(&self, value: T);
}
这不会编译,因为局部变量的生存期严格小于生存期参数指定的生存期(我认为这是很清楚的原因),因此不能调用
b.do\u something(&x)
,因为它要求其参数具有生存期
'a
,它严格大于
x

但是,您可以使用
bar

fn bar(b: Box<for<'a> Trait<&'a usize>>) {
    let x: usize = 10;
    b.do_something(&x);
}
这里的闭包必须接受对
T
的引用,否则就不可能返回包含在选项中的值(这与迭代器上的
filter()
的推理相同)

但是
FnOnce(&T)->bool
中的
&T
应该有什么生存期呢?记住,我们不在函数签名中指定生命周期,只是因为存在生命周期省略;实际上,编译器在函数签名中为每个引用插入一个生存期参数。在
FnOnce(&T)->bool
中应该有一些与
&T
相关的生存期。因此,扩展上述签名的最“明显”的方法是:

fn filter<'a, F>(self, f: F) -> Option<T> where F: FnOnce(&'a T) -> bool
然后用
&value
调用
f
作为参数是完全有效的:我们现在可以选择生存期,因此使用局部变量的生存期是绝对正确的。这就是为什么HRTBs很重要:没有它们,你将无法表达很多有用的模式


您还可以在中阅读关于HRTBs的另一个解释。

太棒了!这很清楚,谢谢。希望这将是这个问题的典型答案。作为后续(如果你有一个链接,那就好了,因为我认为这有点超出了我最初问题的范围):为什么它们的等级-特质界限更高?他们和更高级的类型有什么关系吗(我稍微熟悉一点)?@Thirty340是的,我相信他们完全是以HKTs命名的,因为他们确实很像他们。我可以想象,HKT也可以用
for
来编写,如果它们可用的话:
for Monad
,或者至少,它们有类似的概念——指定无限多的特征边界(或类型,在HKT的情况下),并用一些东西(生命期或类型)参数化。这就是说,HRTBs可以支持类型以及生命周期,只是还没有人提出具体的设计。我认为更高种类的类型与更高等级的类型是正交的。更高级别的类型描述了在类型签名中可以进行量化的位置,而更高级别的类型指的是在类型构造函数上编写多态代码。另请参见:@BurntSushi5哦,我总是把它们彼此混淆:(HRTB是Haskell的
QuantifiedConstraints
的锈名吗?
fn bar(b: Box<for<'a> Trait<&'a usize>>) {
    let x: usize = 10;
    b.do_something(&x);
}
impl<T> Option<T> {
    fn filter<F>(self, f: F) -> Option<T> where F: FnOnce(&T) -> bool {
        match self {
            Some(value) => if f(&value) { Some(value) } else { None }
            None => None
        }
    }
}
fn filter<'a, F>(self, f: F) -> Option<T> where F: FnOnce(&'a T) -> bool
fn filter<F>(self, f: F) -> Option<T> where F: for<'a> FnOnce(&'a T) -> bool