yai*_*chu 6 closures types rust
我编写了一个函数来迭代二维网格中单元格的邻居:
pub fn neighbours(
(width, height): (usize, usize),
(x, y): (usize, usize),
) -> impl Iterator<Item = (usize, usize)> {
[(-1, 0), (1, 0), (0, -1), (0, 1)]
.iter()
.map(move |(dx, dy)| (x as i64 + dx, y as i64 + dy))
.filter(move |&(nx, ny)| 0 <= ny && ny < height as i64 && 0 <= nx && nx < width as i64)
.map(|(nx, ny)| (nx as usize, ny as usize))
}
Run Code Online (Sandbox Code Playgroud)
请注意,它返回一个impl Iterator<Item = (usize, usize)>
.
如果我理解正确,返回 animpl
会导致代码变慢,调用函数指针而不是将内容编译为简单的循环。正确的?
因此,想要指定更精确的类型,我将类型替换为,()
以查看编译器推断出的类型,并且它推断出
std::iter::Map<std::iter::Filter<std::iter::Map<std::slice::Iter<'l, (i64, i64)>, _>, _>, _>
Run Code Online (Sandbox Code Playgroud)
其中_
s 代表闭包,我不知道如何指定它们的类型。
我尝试提取具有Fn
特征的结构的闭包,但无法使其工作,而且IIUC 实现Fn
特征是一个不稳定的功能,我不应该使用它“
\n\n如果我理解正确,返回 an
\nimpl
会导致代码变慢,调用函数指针而不是将内容编译为简单的循环。正确的?
没有。从代码生成角度来看,返回impl Iterator<Item = (usize, usize)>
与返回 .\xc2\xb9 完全相同,Map<Filter<Map<...>>>
区别有两个:
neighbours
不需要更改其签名,因此impl Iterator
与其返回类型的更改向前兼容。impl Iterator
不会与其他不透明impl Iterator
类型统一,即使它们碰巧具有相同的基础类型。(简单来说:编译器不允许您从不同来源创建 of Vec
,impl Iterator
即使所有这些不透明类型都是相同的具体类型。)这些差异都不会影响代码生成或编译器内联任何内容的能力,因此请继续使用impl Iterator
.
在一种情况下,您仍然必须使用间接调度 ( dyn Iterator
):当函数neighbours
本身是特征的一部分时,impl Trait
语法尚不可用(从 1.59 开始)。目前解决这个问题最好的办法就是返回Box<dyn Iterator>
。(但是请注意,这并不意味着每个调用都会动态调度;对的调用.next()
将会动态调度,但“内部”的所有内容仍然使用易于优化的静态调度。)
\xc2\xb9 请注意,为了实际返回 Map<Filter<Map<...>>>
,您仍然必须使用impl Trait
来表示闭包,因为它们具有匿名类型。
归档时间: |
|
查看次数: |
389 次 |
最近记录: |