java 不是封闭类_未装箱的封闭类型对每个封闭都是唯一的

同样,我想从与答案相同的例子开始 . 比较一下:

fn show_both_1(x: S, y: S) {

println!("{:?} {:?}", x, y);

}

还有这个:

fn show_both_2(x: S1, y: S2) {

println!("{:?} {:?}", x, y);

}

(由于最近的更改,现在使用 {:?} 而不是 {} )

第一个函数要求两个参数必须具有相同的类型,即使此类型可以是任意的,只要它实现 Show :

show_both_1::(1i32, 2i32); // ok

show_both_1::(1.0f64, 2.0f64); // ok

show_both_1::??>(1i32, 2.0f64); // not ok!

显然,最后一个函数调用没有意义,因为参数的类型不同,但函数希望它们具有相同的类型 . 你甚至不能明确地写出类型参数 - 它应该是 i32 还是 f64 ?

第二个函数允许不同的类型,因此所有这些调用都可以:

show_both_2::(1, 2);

show_both_2::(1.0, 2.0);

show_both_2::(1, 2.0);

现在,对于每个参数,使用不同的类型参数,因此传递不同类型的值是完全正确的,只要这两种类型都实现 Show .

关闭时绝对会发生同样的事情 . 对于每个闭包,编译器会生成一个新的唯一类型,该类型实现 Fn* traits之一 . 这些类型是匿名的,因此您无法命名它们:

let f: ??? = |&: x: i32, y: i32| x + y;

没有什么可以写,而不是上面的 ??? ,但没有必要,因为编译器知道它为闭包生成了哪种类型,因此它可以推断 f 的类型 . 真正重要的是这个匿名类型将始终实现一个特殊的特征:Fn,FnMut或FnOnce . 因此,如果您希望函数接受闭包,则需要传递一个实现其中一个特征的某种类型的实例 .

但这对于仿制药来说是很自然的工作!当你希望函数接受一些实现某些已知特征的任意类型时,通常会使用它们,而闭包的情况绝对相同 . 所以你有这个:

fn call_closure bool>(f: F) -> bool {

f(10)

}

因为此函数参数具有泛型类型,所以此函数可以与实现 FnMut(i64) -> bool trait的任何类型一起使用(这只是 FnMut 的简写,包括编译器生成的闭包的匿名类型:

call_closure(|x| x > 10);

call_closure(|x| x == 42);

编译器将为每个闭包生成唯一类型,但由于这些生成的类型将实现 FnMut(i64) -> bool trait, call_closure 将很乐意接受它们 .

我在开头描述的具有不同类型参数的情况自然延伸到闭包,因为这里使用相同的机制,即特征 .

fn call_closures_2 bool>(f1: F, f2: F) -> bool {

f1(10) && f2(20)

}

只要此类型实现 FnMut(i64) -> bool trait,此函数接受两个必须属于同一类型的参数 . 这意味着这个调用不起作用:

call_closures_2(|x| x > 9, |x| x == 20)

它不起作用,因为这些闭包具有唯一的,即不同的类型,但功能要求类型必须相同 . 例如,这确实有效:

fn call_closures_3 bool>(f1: &F, f2: &F) -> bool {

f1(10) && f2(20)

}

let f = |&: x: i64| x == 10;

call_closures_3(&f, &f);

请注意,函数参数必须仍然是相同的类型(现在为方便示例引用),但由于我们使用对同一个闭包的引用来调用它,它们的类型是相同的,并且一切正常 . 这不是很有用,因为它非常有限 - 通常你想为需要几个的函数提供不同的闭包 .

因此,该函数需要单独的类型参数才能接受不同的闭包:

fn call_closures_4(f1: F1, f2: F2) -> bool

where F1: FnMut(i64) -> bool,

F2: FnMut(i64) -> bool {

f1(10) && f2(20)

}

call_closures_4(|x| x >= 9, |x| x <= 42)

现在类型参数是独立的,即使闭包有不同的匿名类型,也可以用它们调用这个函数: F1 将成为第一个闭包的生成类型, F2 将成为第二个闭包的生成类型 .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值