已知fn(T)在T上是逆变的,也就是fn(&'a str)类型可以转换为fn(&'static str)。那么反过来fn(&'static str)不能转换为fn(&'a str)。下面代码会报错是正常的:
fn f1<'a>(f: fn(&'static str)) {
let a: fn(&'a str) = f;
}
但是不知道为什么下面这段代码不会报错:
fn f2<'a>(f: fn(&'a str)) {
}
fn f1(f: &'static str) {
}
f2(f1);
都是转换,一个是直接赋值,另外一个是实参到形参。为什么会不一样呢?
1
共 3 条评论, 1 页
评论区
写评论在第一个例子里,生命周期
'a
可以是'static
的,也可以是其他长度,所以'static
是'a
的 subtyping,而fn(T)->()
是逆变的(唯一的逆变),根据逆变的规则,fn(&'a i32)
类型可以赋值给fn(&'static i32)
,反之不行。所以第一个例子失败,但是以下例子是成功的而第二个例子,就没那么难搞了,当函数f2作为参数传入f1时, f1里的
'a
就被指定为'static
了,其实就变成了自然没有问题了
你理解错了,在rust里除了'static这样特殊的生命周期,'a,'b这样的一般都只是一个”变量“,表示某一个生命周期。
'a和'static没有一定的“继承”或者包含的关系。在你的例子中,'a都是一种模板中的生命周期”变量“。(这里使用双引号表示这个说法可能不太标准,下同)
在第一段代码中,因为'a在模板中,在传入时才确定,而不是所有生命周期都能”转化为“'static,所以编译器拒绝了。
但第二段代码中,由于你传入的是一个'static的周期,因此模板自动推算出'a就是'static,因此能成功。
下面的能通过是对的嘛
这种情况下
f2<'a>
这个地方的'a
等于'static