向诸位大神请教一下。 最近在使用filter方法时看了一下标准库的实现。 函数在库中的定义fn filter(self, predicate: P) -> Filter<Self, P> 返回的类型是一个Filter
但是在使用时发现其返回类型是一个impl接口 let iter: impl Iterator<Item = &i32> = lsg_a.iter().filter(|x| **x > 0);
vscode提示的类型是impl Iterator<Item = &i32>
不太理解是如何转换的,求大家指教一下,谢谢
1
共 3 条评论, 1 页
评论区
写评论感谢您的详细解答,获益匪浅
--
👇
苦瓜小仔:
原因在于 闭包 是无法命名(或者匿名)的类型。比如 RA 会告诉你一个变量类型为
let var: Filter<Iter<i32>, |&&i32| -> bool>
,但你无法“指名”这个类型。对于所有匿名类型,使用者可以利用泛型(单态化)或者类型擦除。
Ra 使用了 impl trait type,所以你看到的是
impl Iterator<Item = &i32>
。考虑以下函数:
你无法写
Filter<Iter<i32>, |&&i32| -> bool>
,因为|&&i32| -> bool
不是 你能写的 类型,那么Filter<Iter<i32>, F> where F: FnMut(&&i32) -> bool
呢?你需要更复杂的签名。但这显然不需要,引入的精确类型并没有多大帮助:因为 impl trait type 会单态化,最终类型依然是精确的。
playground
原因在于 闭包 是无法命名(或者匿名)的类型。比如 RA 会告诉你一个变量类型为
let var: Filter<Iter<i32>, |&&i32| -> bool>
,但你无法“指名”这个类型。对于所有匿名类型,使用者可以利用泛型(单态化)或者类型擦除。
Ra 使用了 impl trait type,所以你看到的是
impl Iterator<Item = &i32>
。考虑以下函数:
你无法写
Filter<Iter<i32>, |&&i32| -> bool>
,因为|&&i32| -> bool
不是 你能写的 类型,那么Filter<Iter<i32>, F> where F: FnMut(&&i32) -> bool
呢?你需要更复杂的签名。但这显然不需要,引入的精确类型并没有多大帮助:因为 impl trait type 会单态化,最终类型依然是精确的。
playground
实际上还是
Filter
,只是rust-analyzer显示成了impl xxx
,因为可读性更好。