当函数来自不同的模块时,如何在Rust中实现函数的向量(数组,...)

时间:2015-07-31 01:21:06

标签: arrays rust

我见过:

并在线搜索。我不想要关闭。我正在尝试实现经典的动态(-ish)函数查找表。

mod impl_foo;
mod impl_bar;

use utils;
// a CmdResult is a Result with a tuple of an int and a string

static FUNCTIONS: &'static [fn(&[String]) -> utils::CmdResult] = &[
    ("bar".to_string(), impl_bar::call_bar),
    ("foo".to_string(), impl_foo::call),
];

fn find_action(name: &String) -> (fn(&[String]) -> utils::CmdResult) {
    match FUNCTIONS.binary_search_by(|item| item[0].cmp(name)) {
        Ok(action) => action,
        Err(_) => (|&[String]| Err((1, format!("Unknown '{}'", name))))
    }
}

// later on in another function ....

action = find_action(" foo");    let result = action(args);    //处理结果

但是这不能编译:

src/main.rs:44:5: 44:50 error: mismatched types:
   expected `fn(&[collections::string::String]) ->    core::result::Result<i32, (i32, collections::string::String)>`,
found `(collections::string::String, fn(&[collections::string::String]) -> core::result::Result<i32, (i32, collections::string::String)> {impl_foo::call})`

再次为impl_bar::call_bar

我错过了什么?它似乎与使用不同的模块有关,因为它显然适用于其他人。

我还试图定义一个类型:

type Action = fn(&[String]) -> utils::CmdResult;

并用它来减少打字,但也没有运气。

顺便说一句,由于#![feature(slice_patterns)],您需要&[String]

第二天早上编辑.....

弗朗西斯指出我的转录下面有一个缺陷。它与我遇到的真正问题并不完全相符,但它让我看到了新鲜的眼睛。 切片模式要求是因为我试图用闭包来处理未知函数。一旦我删除,投诉就消失了。我想我的想法是一种过于动态的语言风格: - )

下面是完整的代码,它实际上可以正常工作,以便找到此问题的人可以查看工作代码。

type Action = fn(&[String]) -> utils::CmdResult;

static FUNCTIONS: &'static [(&'static str, Action)] = &[
    ("bar", impl_bar::call),
    ("foo", impl_foo::call_foo),
];

fn find_action(prog: &String) -> Option<Action> {
    match FUNCTIONS.binary_search_by(|&(name,_)| name.cmp(prog)) {
        Ok(idx) => Some(FUNCTIONS[idx].1),
        Err(_) => None,
    }
}

fn invoke(prog: &String, args: &[String]) -> i32 {
    let result = match find_action(prog) {
        Some(action) => action(args),
        None => Err((1, format!("Unknown: {}", prog))),
    };

    result.unwrap_or_else(|(n, msg)| {
        writeln!(io::stderr(), "{}", msg).ok();
        n
    })
}

1 个答案:

答案 0 :(得分:4)

仔细阅读错误消息:

src/main.rs:44:5: 44:50 error: mismatched types:
   expected `fn(&[collections::string::String]) ->    core::result::Result<i32, (i32, collections::string::String)>`,
found `(collections::string::String, fn(&[collections::string::String]) -> core::result::Result<i32, (i32, collections::string::String)> {impl_foo::call})`

让我们简化一下:

src/main.rs:44:5: 44:50 error: mismatched types:
   expected `fn(&[String]) -> Result<i32, (i32, String)>`,
found `(String, fn(&[String]) -> Result<i32, (i32, String)> {impl_foo::call})`

这条消息告诉你的是,你试图将一个String元组和一个函数类型放入一个只需要函数类型的数组中。

你可能想要像这样定义你的数组:

static FUNCTIONS: &'static [(&'static str, fn(&[String]) -> utils::CmdResult]) = &[
    ("bar", impl_bar::call_bar),
    ("foo", impl_foo::call),
];