如何在Rust中调用通用特征方法

6

有这些相当人为的类型定义

trait Generic<T> {
    fn some(&self) -> T;
}

impl<T> Generic<T> for i32
where
    T: Default,
{
    fn some(&self) -> T {
        T::default()
    }
}

我想要显式地调用 some 方法并指定类型 T。下面的代码显然不起作用,因为该方法本身不是泛型。

fn main() {
    let int: i32 = 45;
    println!( "some: {}", int.some<bool>() );
}

如何正确地调用 some


1
编译器无法推断类型,因为 println! 宏接受通用类型。这里有一些想法:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8f59a103f21f101be18b1e5e0805d644 - Ömer Erden
@ÖmerErden 很棒的答案!但是为什么 &int.some() as &bool 能够工作,而 int.some() as bool 不能? - Mooh
您不能直接将 T 强制转换为目标类型,请参见:https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions - Ömer Erden
1个回答

6

你必须像你尝试的那样指定确切的类型。不幸的是,你的函数不是一般化的,相反,你的实现是通用的,所以你需要执行以下操作:

fn main() {
    let int: i32 = 45;
    println!("some: {}", <i32 as Generic<bool>>::some(&int));
    // Or,
    println!("some: {}", Generic::<bool>::some(&int));
}

或者,您可以定义一个帮助程序trait:

trait HasSome {
    fn other_some<T>(&self) -> T where Self: Generic<T> {
        <Self as Generic<T>>::some(self)
    }
}
impl<T> HasSome for T {} // Blanket impl. 

Playground


另外需要注意的是,在指定类型或函数的泛型时,您需要使用“涡轮鱼尖号”::<>操作符:

let foo = Vec::<i32>::new(); // Vec<i32>
let foo = my_generic_function::<usize>(); // Calls my_generic_function with usize
let foo = Option::<usize>::None;
let foo = None::<usize>;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接