如何实现的鲁斯特功能的载体(数组,..)时的功能来自不同模块 [英] How to implement a vector (array, ..) of functions in Rust when the functions come from different modules
问题描述
我所看到的:
- 锈阵列
- 防锈:迭代的功能载体
功能
和在线搜索。我不想关闭。我想实现一个经典的动态(-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屋!