rust-quiz:011-function-pointer-comparison.rs

题目

fn f<'a>() {}
fn g<'a: 'a>() {}

fn main() {
    let pf = f::<'static> as fn();
    let pg = g::<'static> as fn();
    print!("{}", pf == pg);
}

关键

  • 数据限定
    我们经常使用let a: u32这种办法去限定一个数据的类型,这算是数据的限定。

  • 类型限定
    A:T这种形式,就是类型限定,它决定了一个类型的最基础要求。
    当然,也有T的无要求数据类型。

  • 生命周期
    lifetime算是数据还是类型呢,它是一种特殊的数据类型。
    它可以被省略,被自动推导;也可以手动声明,还可以手动限定。

展示

生命周期本身是可以自动推导的。

fn f<'b, 'a:'b>(a: &'a u32) -> &'b u32 {
    a
}

这里出现了限定,更简略一些

fn f<'a>(a: &'a u32) -> &'a u32 {
    a
}

但是,这里最简应该是

fn f(a: &u32) -> &u32 {
    a
}

简单总结出来,输出的引用的生命周期始终是受限于输入的生命周期。
但是输入的生命周期是上下文就可以进行推导出来的,某些场景下无需手动声明。

就算手动声明,如果和推导的结果一致,也无大用处。

关键在于:怎么声明,才和推导的不一样?
最关键的一处在于:推导的入参生命周期来源于上下文,我们是可以重新指定的。

  • 生命周期在函数签名之外声明
  • 生命周期参数以它必须超过的其他生命周期为界

这叫做early bound,也就是说,无非等到自动推导,提前指定了生命周期。

审题

  • fn f<'a>() {}
    如果方法有生命周期,这里只不过是显式写了出来,并没有额外的操作。

  • fn g<'a: 'a>() {}
    这里限定了一个声明周期,也就是运行时需要指定一个声明周期。

fn main() {
    let pf = f::<'static> as fn();
    let pg = g::<'static> as fn();
    print!("{}", pf == pg);
}

因此,pf其实本身并不能通过编译,因为它并没有实现early bound的语法。
不能够以指定生命周期的形式进行调用。
pg没有问题,因为声明当中,它的生命周期有明显的受限声明。

答案

errorshit!

改动一下展示的例子,展示”受限”,这和我们平时的类型限定没有什么区别

fn  f<'a:'a>(a: &'a  u32) ->  &'a  u32 {
    a
}
fn  main() {
    f::<'static>(&1);
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!