1

是否可以使用具有具体结构的具体类型调用泛型函数?

这是我想做的一个小例子:

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需要更多特征。

4

2 回答 2

4

这是不可能的:

fn test<V: T>(foo: &S1, bar: &S2, f: &Fn(&V)) {
    f::<S1>(foo);
}

实际上,函数签名说:

  • 请给我一个f接受 trait 的 trait 对象的 trait 对象,该对象Fn引用 aV
  • 调用者可以为 选择任何具体类型,V只要它实现了 traitT

然后函数的主体说:

  • 哈哈哈,开个玩笑,不管调用者选择什么,我都会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),

这允许发生某种程度的单态化。

于 2017-03-28T18:54:04.297 回答
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 成为多态调用。

如果没有有关您的类型的更多信息,就很难理解您要做什么。

于 2017-03-28T18:52:42.200 回答