Rust 我可以在捕获环境的同时实现特性吗?
我正试图实现一个搜索代码2019的出现(是的,我知道是Slowpoke)。我是这样开始的:Rust 我可以在捕获环境的同时实现特性吗?,rust,closures,traits,Rust,Closures,Traits,我正试图实现一个搜索代码2019的出现(是的,我知道是Slowpoke)。我是这样开始的: fn find_path(start: Coords, goal: Coords, map: &Vec<Vec<char>>) -> Vec<Coords> { struct Node { distance: u32, pos: Coords, } impl PartialEq for
fn find_path(start: Coords, goal: Coords, map: &Vec<Vec<char>>) -> Vec<Coords> {
struct Node {
distance: u32,
pos: Coords,
}
impl PartialEq for Node {
fn eq(&self, other: &Self) -> bool {
self.distance + manhattan(self.pos, goal) == other.distance + manhattan(other.pos, goal)
}
}
...
let mut edge = BinaryHeap::new();
edge.push(Node{distance: 0, pos: start});
...
fn查找路径(开始:坐标,目标:坐标,映射:&Vec)->Vec{
结构节点{
距离:u32,
位置:Coords,
}
节点的impl PartialEq{
fn eq(&self,其他:&self)->bool{
self.distance+manhattan(self.pos,goal)=other.distance+manhattan(other.pos,goal)
}
}
...
让mut edge=BinaryHeap::new();
推(节点{距离:0,位置:开始});
...
Coords
是一个包含x
和y
的结构。这里的问题是我不能在trait中使用goal
,因为它不在范围内。闭包可以捕获它,但我怀疑我是否可以在这里使用闭包而不是fn
。如果是,语法是什么?如果不是,是否有fundame为什么不能这样做?我在网上找不到答案
我知道简单的解决方案是在节点
中包含目标
,但这是多余的,因为我将在*期间创建数千个节点
,所有这些节点都具有相同的目标,浪费内存和CPU周期。原则上,目标
可以是单个全局变量,但这是一个不整洁的选项
尽管我确信在节点
中包含目标
在实践中效果会很好,但我宁愿不这样做
有没有另一种惯用的方法来完成我想做的事情?没有,您不能在
impl
块中捕获任何环境。闭包捕获环境,因此您不能在impl
块中将闭包用作函数
函数和方法被设计为可以从任何上下文调用,因此不能保证甚至可以捕获环境。事实上,我们可以在另一个函数内部声明类型、函数、方法等,这基本上是语法上的精确性
我可能会创建一个包装节点
和目标
的类型:
struct Foo(Node, Coord);
impl Foo {
fn value(&self) -> WhateverType {
self.0.distance + manhattan(self.0.pos, self.1)
}
}
impl PartialEq for Foo {
fn eq(&self, other: &Self) -> bool {
self.value() == other.value()
}
}
另见:
PartialEq
的原因是节点随后进入二进制堆
。如果二进制堆
可以提供自定义比较器,那将是完美的:我不需要节点
成为Ord
,我可以让目标
驻留在该com中并列(闭合)
似乎正在考虑这一点:
同时,有一个板条箱提供了这种功能:
现在,我要接受goal
在Node
内部的开销,但是知道我的选项很好。感谢链接。petgraph
似乎很有用,我会记住它,尽管我想创建一个A*实现,它不需要从一开始就显式枚举所有节点。我有一个网格map,节点是隐式的。