如何调用数组或元组类型的关联函数?

How to call associated function with array or tuple type?

我可以为这样的数组定义关联函数 foo

pub trait T {
    fn foo();
}

impl<X> T for [X; 2] {
    fn foo() { panic!("Whatever") }
}

但是我现在如何调用这个函数呢?我注意到像 [usize;2]::foo() 这样的语法是无效的。

您可以使用完全限定语法 <Type as Trait>::function()。这是您的示例:

pub trait Trait {
    fn foo();
}

impl<X> Trait for [X; 2] {
    fn foo() {
        panic!("Whatever");
    }
}

fn main() {
    <[usize; 2] as Trait>::foo();
}

the playground 上查看。

简答: 您需要使用尖括号:<[usize; 2]>::foo().

长答案:

如果您查看 the reference,您会看到语法:

CallExpression :
      Expression ( CallParams? )

表达式 中,你有 PathExpression. There are two kinds of PathExpression s: PathInExpression and QualifiedPathInExpressionPathInExpressiona::b::c::<generics>::d::<generics> 等形式的简单路径。这就是您在键入时使用的内容,例如String::new()String::from("abc").

另一方面,

QualifiedPathInExpression 的形式为 QualifiedPathType (:: PathExprSegment)+,或者简单地说,QualifiedPathType 后跟两个冒号的一个或多个实例,然后是 PathExprSegementPathExprSegment 被定义为一个名称(标识符),可选地后跟两个冒号和泛型:即 foofoo::<a, b, c>.

QualifiedPathType 是什么?它被定义为 < Type (as TypePath)? >,或者用尖括号括起来的类型,可以选择后跟 as 和一个TypePath,与 PathExpression 非常相似,但有一些差异。

Type 是任何 Rust 类型语法:路径(例如 a::b<generics>a::b::<generics>、特征对象(dyn Trait)、impl Trait、元组((T1, T2, T3, ...))、数组([T; N])、切片([T])、引用(&T&mut T,可能有生命周期) , 等等。

所有这一切意味着当你调用一个方法时,除非方法类型是一个简单的路径——也就是说,具有 a::b::c 的形式,可能使用泛型,你 必须 将类型括在尖括号中 - <Type>::method()。这包括数组、切片、引用、元组、函数指针 (fn(Args) -> Ret) 等等。 [usize; 2]::foo() 不是有效的 Rust 语法,只有 <[usize; 2]>::foo() 是。

当然,使用这种形式还有一个原因:UFCS(通用函数调用语法)。当你想指定特征时(通常是为了消除歧义),你必须使用 <Type as Trait>::method() 的形式(这是 "(as TypePath)?”我们看到了)。