是否可以使用具体结构调用具体类型的泛型函数?
这是我想要做的一个小例子:
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
需要更多的特征。
答案 0 :(得分:3)
这是不可能的:
fn test<V: T>(foo: &S1, bar: &S2, f: &Fn(&V)) {
f::<S1>(foo);
}
实际上,函数签名说:
f
一个特征Fn
的特征对象,该特征引用V
V
的任何具体类型,只要它实现特征T
然后函数的主体说:
f
来称呼S1
,无论来电者选择了什么。这不起作用,因为来电者选择的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),
这允许发生某种程度的单态化。
答案 1 :(得分:1)
这可能不是您想要的,但它确实有效:
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成为多态调用。
如果没有关于您的类型的更多信息,很难理解您正在尝试做什么。