使用具体类型调用通用闭包
Call generic closure with concrete type
是否可以使用具有具体结构的具体类型调用泛型函数?
这是我想做的一个小例子:
trait T {}
trait T2 {}
struct S1 {}
struct S2 {}
impl T for S1 {}
impl T for S2 {}
fn test<V: T>(foo: &S1, bar: &S2, f: &Fn(&V)) {
f::<S1>(foo);
f(bar);
}
fn main() {
test(&S1{}, &S2{}, &|_| println!("called"));
}
我无法摆脱通用参数 V
因为我要解决的实际问题要复杂得多。此外,我无法创建包装特征,因为有时我的签名很弱,有时 f
需要更多特征。
这可能不是您想要的,但它确实有效:
trait T {}
trait T2 {}
struct S1 {}
struct S2 {}
impl T for S1 {}
impl T for S2 {}
fn test<F>(foo: &S1, bar: &S2, f: F)
where F: Fn (&T)
{
f(foo as &T);
f(bar as &T);
}
fn main() {
test(&S1{}, &S2{}, |_| println!("called"));
}
这会导致 foo 和 bar 被强制转换为一个 Trait 对象,这意味着它将携带一个 vtable 指针(可能并不理想)。它使 F 成为多态调用。
如果没有关于您的类型的更多信息,就很难理解您要做什么。
这是不可能的:
fn test<V: T>(foo: &S1, bar: &S2, f: &Fn(&V)) {
f::<S1>(foo);
}
实际上,函数签名表示:
- 请给我一个
f
,它采用特征 Fn
的特征对象,它引用 V
- 调用者 可以为
V
选择任何具体类型,只要它实现了特征 T
然后函数体说:
- 哈哈哈,开个玩笑,我将用具体类型
S1
调用它 f
,不管调用者选择了什么。
这不起作用,因为呼叫者选择的 V
可能不是 S1
。事实上,很可能 而不是 会是 S1
。
关于我能提供的唯一建议是接受另一个特征对象作为参数:
fn test(foo: &S1, bar: &S2, f: &Fn(&T)) {
f(foo);
f(bar);
}
但您已经排除了这种可能性,所以...
附带说明一下,我不确定您为什么将闭包作为特征对象。通常,我只接受通用的:
fn test<F>(foo: &S1, bar: &S2, f: F)
where F: Fn(&T),
这允许发生某种程度的单态化。
是否可以使用具有具体结构的具体类型调用泛型函数?
这是我想做的一个小例子:
trait T {}
trait T2 {}
struct S1 {}
struct S2 {}
impl T for S1 {}
impl T for S2 {}
fn test<V: T>(foo: &S1, bar: &S2, f: &Fn(&V)) {
f::<S1>(foo);
f(bar);
}
fn main() {
test(&S1{}, &S2{}, &|_| println!("called"));
}
我无法摆脱通用参数 V
因为我要解决的实际问题要复杂得多。此外,我无法创建包装特征,因为有时我的签名很弱,有时 f
需要更多特征。
这可能不是您想要的,但它确实有效:
trait T {}
trait T2 {}
struct S1 {}
struct S2 {}
impl T for S1 {}
impl T for S2 {}
fn test<F>(foo: &S1, bar: &S2, f: F)
where F: Fn (&T)
{
f(foo as &T);
f(bar as &T);
}
fn main() {
test(&S1{}, &S2{}, |_| println!("called"));
}
这会导致 foo 和 bar 被强制转换为一个 Trait 对象,这意味着它将携带一个 vtable 指针(可能并不理想)。它使 F 成为多态调用。
如果没有关于您的类型的更多信息,就很难理解您要做什么。
这是不可能的:
fn test<V: T>(foo: &S1, bar: &S2, f: &Fn(&V)) {
f::<S1>(foo);
}
实际上,函数签名表示:
- 请给我一个
f
,它采用特征Fn
的特征对象,它引用V
- 调用者 可以为
V
选择任何具体类型,只要它实现了特征T
然后函数体说:
- 哈哈哈,开个玩笑,我将用具体类型
S1
调用它f
,不管调用者选择了什么。
这不起作用,因为呼叫者选择的 V
可能不是 S1
。事实上,很可能 而不是 会是 S1
。
关于我能提供的唯一建议是接受另一个特征对象作为参数:
fn test(foo: &S1, bar: &S2, f: &Fn(&T)) {
f(foo);
f(bar);
}
但您已经排除了这种可能性,所以...
附带说明一下,我不确定您为什么将闭包作为特征对象。通常,我只接受通用的:
fn test<F>(foo: &S1, bar: &S2, f: F)
where F: Fn(&T),
这允许发生某种程度的单态化。