簡體   English   中英

泛型和關聯類型有什么區別?

[英]What is the difference between generics and associated types?

我的印象是這兩件事在語義上是不同的。

但是,這是可能的:

struct Foo;

trait Bar<T> {
  fn resolve(&self) -> T;
}

impl Bar<isize> for Foo {
  fn resolve(&self) -> isize {
    return 0isize;
  }
}

impl Bar<usize> for Foo {
  fn resolve(&self) -> usize {
    return 1usize;
  }
}

#[test]
fn test_foo() {
  let foo = Foo;
  assert!((&foo as &Bar<isize>).resolve() == 0isize);
  assert!((&foo as &Bar<usize>).resolve() == 1usize);
}

雖然這不是:

struct Foo;

trait Bar {
  type T;
  fn resolve(&self) -> Self::T;
}

impl Bar for Foo {
  type T = isize;
  fn resolve(&self) -> isize {
    return 0isize;
  }
}

impl Bar for Foo {
  type T = usize;
  fn resolve(&self) -> usize {
    return 1usize;
  }
}

#[test]
fn test_foo() {
  let foo = Foo;
  assert!((&foo as &Bar<T = isize>).resolve() == 0isize);
  assert!((&foo as &Bar<T = usize>).resolve() == 1isize);
}

它產生:

<anon>:8:1: 13:2 error: conflicting implementations for trait `Bar` [E0119]
<anon>: 8 impl Bar for Foo {
<anon>: 9   type T = isize;
<anon>:10   fn resolve(&self) -> isize {
<anon>:11     return 0isize;
<anon>:12   }
<anon>:13 }

我想念什么嗎?

我要達到的目的是否有特殊的語法,或者真的有...技術...泛型和關聯類型之間的區別?

在某種情況下,關聯類型比使用泛型有明顯的好處(而不是純粹的代碼美化)嗎?

我將重復我的評論:確實,類型參數和關聯的類型在語義上是不同的。 但是,這就是為什么它們都存在於語言中的要點-它們各自完成各自的工作,因此這不是“僅”語義上的差異,而是它們作為類型參數與其他事物分開存在的全部原因。

請注意,我什至沒有觸及語法差異。 當然,語法上的差異是絕對自然的。 畢竟,這些是單獨的功能。 如果它們沒有語法差異,那么您將如何區分它們? 它們的句法差異與語義差異緊密相關,因為關聯類型的定義方式清楚地表明,與類型參數的“輸入”位置相比,它們具有“輸出”位置,但是從技術上講,類型參數和關聯類型(以及隱式的Self ,參數,順便說一句)。

對於發現此問題的其他任何人,類型參數和關聯的類型之間也存在另一個技術區別。

如果嘗試使用關聯的類型實現特征,則可能會看到錯誤:

src/lib.rs:10:1: 15:2 error: the impl does not reference any types
defined in this crate; only traits defined in the current crate can
be implemented for arbitrary types [E0117]

如果在板條欄中導出了特征,則:

pub trait BarParam<TRtn> {
  fn bar() -> TRtn;
}

pub trait BarAssoc {
  type TRtn;
  fn bar() -> Self::TRtn;
}

您會發現導入這些特征的板條箱將只能實現:

impl<'a> BarParam<Foo> for &'a str {
  fn bar() -> Foo {
    return Foo;
  }
}

嘗試實施時:

impl<'a> BarAssoc for &'a str {
  type TRtn = Foo;
  fn bar() -> Foo {
    return Foo;
  }
}

將導致上面的錯誤。

坦白說,我不太確定這是怎么回事,因此,如果您這樣做,一定要添加評論或其他答案。 但這是寫板條箱時避免關聯類型的明顯原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM