Rust 我可以在捕获环境的同时实现特性吗?

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

我正试图实现一个搜索代码2019的出现(是的,我知道是Slowpoke)。我是这样开始的:

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,节点是隐式的。