在泛型类型上调用特征方法的语法差异

时间:2018-01-07 20:22:16

标签: rust

我试图了解Trait::<T as Trait>::方法调用语法的必要性。特别是,我正在查看this answer中的以下函数:

fn clone_into_array<A, T>(slice: &[T]) -> A
where
    A: Default + AsMut<[T]>,
    T: Clone,
{
    assert_eq!(
        slice.len(),
        std::mem::size_of::<A>() / std::mem::size_of::<T>()
    );

    let mut a = Default::default();
    <A as AsMut<[T]>>::as_mut(&mut a).clone_from_slice(slice);
    a
}

似乎中间的两个方法调用行可以重写为:

let mut a = A::default();
a.as_mut().clone_from_slice(slice);

我相信这更具可读性,因为我们已经知道A实现了DefaultAsMut<[T]>,我们可以直接调用as_mut作为方法,而不必通过明确a

但是,我错过了一个很好的理由,因为链接的答案更详细地写了吗?它被认为是好风格吗?在某些条件下两者在语义上是不同的吗?

1 个答案:

答案 0 :(得分:1)

我同意你的重写 - 它们更清晰,是我推荐的功能。

  

我错过了一个很好的理由,因为链接的答案更详细地写了吗?

我的猜测是作者只是厌倦了写这个功能而停了下来。如果他们再看一遍,他们可能会把它改进得更短。

  

它被认为是好风格吗?

我认为除此之外,还有一般的社区风格偏好,除了一般&#34;短期更好,直到它不是&#34;。

  

在某些情况下两者在语义上是否不同?

他们不应该。

有时需要<>::语法 ,否则它将是不明确的。一个例子from a recent question

let array = <&mut [u8; 3]>::try_from(slice);

另一个时候,你没有一个名字很好的中间类型,或者中间类型在多个特征上是不明确的。一个gross example来自where子句,但显示与表达式相同的问题:

<<Tbl as OrderDsl<Desc<Expr>>>::Output as LimitDsl>::Output: QueryId,

另见: