如何实现的鲁斯特功能的载体(数组,..)时的功能来自不同模块 [英] How to implement a vector (array, ..) of functions in Rust when the functions come from different modules

查看:125
本文介绍了如何实现的鲁斯特功能的载体(数组,..)时的功能来自不同模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我所看到的:

和在线搜索。我不想关闭。我想实现一个经典的动态(-ish)函数查找表。

  MOD impl_foo;
MOD impl_bar;使用utils的;
//一个CmdResult是一个int和一个字符串的元组结果静态函数:放大器;静态[FN(安培; [字符串]) - GT; utils的:: CmdResult] =安培;
    (栏.to_string(),impl_bar :: call_bar)
    (富.to_string(),impl_foo ::调用),
];FN find_action(名称:放大器;字符串) - GT&; (FN(安培; [字符串]) - GT; utils的:: CmdResult){
    比赛FUNCTIONS.binary_search_by(|项目|项目[0] .cmp(名称)){
        OK(动作)=>行动,
        ERR(_)=> (|&安培;![字符串] | ERR((1,格式(未知'{}',名))))
    }
}//后来在另一个函数....

行动= find_action(富);
   让结果=动作(参数);
   //处理结果

但是,这并不编译:

 的src / main.rs:44:5:44:50错误:类型不匹配:
   预计`FN(安培;集合::字符串::字符串]) - GT;核心::结果::结果< I32(I32,集合::字符串::字符串)>`
发现`(集合::字符串::字符串,FN(安培;集合::字符串::字符串]) - GT;核心::结果::结果< I32(I32,集合::字符串::字符串)&GT {impl_foo ::通话})`

和再次 impl_bar :: call_bar

我在想什么?它似乎有事情做与使用不同的模块,因为它清楚地适用于其他人。

我也试图定义一个类型:

 键入行动= FN(安培; [字符串]) -  GT; utils的:: CmdResult;

和使用,以减少输入,但没有运气有两种。

顺便说一句,你需要#[功能(slice_patterns)] 因为&安培;![字符串]

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

由于弗朗西斯指出下面我转录这里有一个缺陷。它并没有完全符合实际的问题,我有,但是它帮助我用新鲜的眼光看。
切片模式要求是因为我试图处理未知函数与关闭。有一次,我删除了投诉就走了。我试图有点过于动态语言风格,我认为: - )

下面是完成code的实际工作使人们发现这个问题,可以看到工作code。

 键入行动= FN(安培; [字符串]) -  GT; utils的:: CmdResult;静态函数:放大器;静态[(放大器;静态STR,动作)] =安培;
    (酒吧,impl_bar ::调用),
    (富,impl_foo :: call_foo)
];FN find_action(PROG:放大器;字符串) - GT&;选项​​<作用> {
    匹配FUNCTIONS.binary_search_by(|及(名称,_)| name.cmp(PROG)){
        OK(IDX)=>有些(功能[IDX] .1)
        ERR(_)=>没有,
    }
}FN调用(PROG:放大器;弦乐,ARGS:放大器; [字符串]) - GT; I32 {
    让结果=匹配find_action(PROG){
        一些(动作)=>动作(参数),
        无=> ERR((1,格式(未知:{}!,PROG)))
    };    result.unwrap_or_else(|(N,味精)| {
        writeln(IO :: STDERR(),{},MSG).ok()!;
        ñ
    })
}


解决方案

仔细阅读错误消息:

 的src / main.rs:44:5:44:50错误:类型不匹配:
   预计`FN(安培;集合::字符串::字符串]) - GT;核心::结果::结果< I32(I32,集合::字符串::字符串)>`
发现`(集合::字符串::字符串,FN(安培;集合::字符串::字符串]) - GT;核心::结果::结果< I32(I32,集合::字符串::字符串)&GT {impl_foo ::通话})`

让我们简化一下:

 的src / main.rs:44:5:44:50错误:类型不匹配:
   预计`FN(安培; [字符串]) - GT;结果< I32(I32,字符串)>`
发现`(字符串,FN(安培; [字符串]) - GT;结果< I32(I32,字符串)> {impl_foo ::通话})`

这是什么讯息告诉你的是,你试图把字符串的元组和功能型成预计只有函数类型的数组。

您大概意思这样定义你的数组:

 静态函数:放大器;静态[(放大器;静态海峡,FN(安培; [字符串]) -  GT; utils的:: CmdResult)=&安培;
    (酒吧,impl_bar :: call_bar)
    (富,impl_foo ::调用),
];

I have seen:

and searched online. I do not want closures. I am trying to implement a classic dynamic(-ish) function lookup table.

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); // process results

But this does not compile:

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})`

and again for impl_bar::call_bar.

What am I missing? It appears to have something to do with the use of different modules since it clearly works for other people.

I also tried to define a type:

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

and use that to cut down on typing but no luck there either.

BTW, you need #![feature(slice_patterns)] because of the &[String].

Edit the next morning.....

As Francis points out below my transcription here had a flaw. It did not exactly match the real problem I had but it helped me see with fresh eyes. The slice pattern requirement is because I was trying to handle unknown functions with a closure. Once I removed that the complaint went away. I was trying to be a little too dynamic language style I think :-)

Below is the completed code that actually works so that people finding this question can see working code.

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
    })
}

解决方案

Read the error message carefully:

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})`

Let's simplify it:

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})`

What this message is telling you is that you're trying to put a tuple of String and a function type into an array that expects only the function type.

You probably meant to define your array like this:

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

这篇关于如何实现的鲁斯特功能的载体(数组,..)时的功能来自不同模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆