在当前范围内找不到名为“match_command”的结构“HashMap”的方法

No method named `match_command` found for struct `HashMap` in the current scope

我正在编写一个命令解析器。这是我的代码。

use std::collections::HashMap;
use std::hash::{Hash, Hasher};

struct Command {
    begin: String,
    command: String,
    args: Vec<String>
}

impl Command {
    fn parse(command: &str) -> Self {
        let command: Vec<&str> = command.split(" ").collect();
        Command {
            begin: command[0][0..1].to_string(),
            command: command[0][1..].to_string(),
            args: command[1..].iter()
                .map(|x| x.to_string())
                .map(|x| x.replace("%s", " "))
                .map(|x| x.replace("%n", "\n"))
                .collect()
        }
    }

    fn prefix(&self) -> String {
        format!("{}{}", self.begin, self.command)
    }
}

impl ToString for Command {
    fn to_string(&self) -> String {
        let mut string = format!("{}{}", self.begin, self.command);
        for i in self.args {
            string.push_str(format!(" {}", i).as_str())
        }
        string
    }
}

trait CommandRegister {
    fn match_command(&self, command: &str) -> Option<fn(args: Vec<String>)>;
}

impl CommandRegister for HashMap<Command, fn(args: Vec<String>)> {
    fn match_command(&self, command: &str) -> Option<fn(args: Vec<String>)> {
        let command = Command::parse(command);
        for i in self {
            if *i.0 == command {
                return Some(*i.1)
            }
        }
        None
    }
}

impl PartialEq<Self> for Command {
    fn eq(&self, other: &Self) -> bool {
        self.begin == other.begin && self.command == other.command && self.args.len() == other.args.len()
    }
}

impl Eq for Command {
}

impl Hash for Command {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.to_string().hash(state)
    }
}

fn main() {
    let command = Command::parse("/alpha do 1 2");
    println!("Begin: {}", command.begin);
    println!("Command: {}", command.command);
    for i in 0..command.args.len() {
        println!("Arg{i}: {}", command.args[i])
    }
    let mut map: HashMap<&Command, fn(args: Vec<String>)> = HashMap::new();
    let command = Command {
        begin: String::from("/"),
        command: String::from("alpha"),
        args: vec!("arg1".to_string(), "arg2".to_string())
    };
    map.insert(&command, |args: Vec<String>| {
        println!("Arguments length: {}", args.len());
    });
    match map.match_command(command.to_string()) {
        Some(func) => func(command.args)
    }
}

match_command 给了我一个错误,它说 no method named match_commandfound for structHashMap in the current scope

但是我在范围内实现了 HashMap 的 CommandRegister 特性。我想也许是因为类型转换,但我不知道如何处理它。而且我还想问一下fnClosure的区别。如果我想在这里使用闭包,可以吗?

未找到实现,因为类型不匹配。比较:

impl CommandRegister for HashMap<Command, fn(args: Vec<String>)> {
let mut map: HashMap<&Command, fn(args: Vec<String>)> = HashMap::new();

一个使用Command,另一个使用&Command

但是,请注意您使用 HashMap 非常 的效率很低:

for i in self {
    if *i.0 == command {
        return Some(*i.1)
    }
}

这对内容执行线性搜索。使用 HashMap 的全部意义在于通过哈希查找项目而不是进行线性搜索:

fn match_command(&self, command: &str) -> Option<fn(args: Vec<String>)> {
    let command = Command::parse(command);
    self.get(&command).copied()
}

如果这不起作用,那是因为您的 HashPartialEq 实现比较了不同的东西:

impl PartialEq<Self> for Command {
    fn eq(&self, other: &Self) -> bool {
        self.begin == other.begin && self.command == other.command && self.args.len() == other.args.len()
    }
}

impl Hash for Command {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.to_string().hash(state)
    }
}

请注意,PartialEq 实现仅比较向量的长度。为了同意您的 Hash 实施,它应该比较 Hash 所看到的:

impl PartialEq<Self> for Command {
    fn eq(&self, other: &Self) -> bool {
        self.to_string() == other.to_string()
    }
}

处理此问题的最简单方法是删除您自己的 EqPartialEqHash 实现,而是在您的结构上派生它们:

#[derive(PartialEq, Eq, Hash)]
struct Command {

这将为您生成自动查看所有结构字段的实现。生成的 Hash 实施应该比您的执行得更好,但更重要的是,所有实施都将 正确。