【发布时间】:2019-02-10 22:51:38
【问题描述】:
我正在编写一个模拟框架。为此,我需要接受一个可用作替代另一个函数的函数并将其存储。我当前的设计通过强制相同的输入和输出类型来做到这一点,但它在强制正确的生命周期方面完全失败了。
相反,我需要编写一个通用函数,它接受一个基函数及其替代:
fn main() {
selector(foo, baz, "local", false);
selector(bar, baz, "local", false);
selector(foo, bar, "local", false); // SHOULD FAIL, bar is NOT substitute of foo
}
fn foo(_: &str) -> &'static str {
"foo"
}
fn bar(s: &str) -> &str {
s
}
fn baz(_: &str) -> &'static str {
"baz"
}
// DOES NOT COMPILE
// fn selector<U, V, F: Fn(U) -> V, G: F>(base: F, subs: G, arg: U, use_base: bool) -> V {
// match use_base {
// true => base(arg),
// false => subs(arg),
// }
// }
// COMPILES, but is too weak
fn selector<U, V, F: Fn(U) -> V, G: Fn(U) -> V>(base: F, subs: G, arg: U, use_base: bool) -> V {
match use_base {
true => base(arg),
false => subs(arg),
}
}
“替代”是指一个函数,它至少接受 base 接受的每个参数,并且每个参数都返回至少在每个地方都可用的值,其中从 base 返回的值是。例如:
fn foo(_: &str) -> &'static str {
"foo"
}
fn bar(s: &str) -> &str {
s
}
fn baz(_: &str) -> &'static str {
"baz"
}
baz 是foo 和bar 的替代品,因为它返回的字符串既可以用来代替'static,也可以依赖于借用。 bar不是替代foo,因为借用值不能用来代替'static。
我想创建这样的东西,但它无法编译:
// FAILURE
// V
fn selector<U, V, F: Fn(U) -> V, G: F>(base: F, subs: G) {...}
问题是我无法表达F 和G 之间的关系。 Rust 似乎没有具体类型的超类型的概念。
【问题讨论】: