<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                關聯類型是Rust類型系統中十分強力的一部分。它涉及到‘類型族’的概念,換句話說,就是把多種類型歸于一類。這個描述可能比較抽象,所以讓我們深入研究一個例子。如果你想編寫一個`Graph`特性,你需要泛型化兩個類型:點類型和邊類型。所以你可能會像這樣寫一個特性,`Graph`: ~~~ trait Graph<N, E> { fn has_edge(&self, &N, &N) -> bool; fn edges(&self, &N) -> Vec<E>; // etc } ~~~ 雖然這可以工作,不過顯得很尷尬,例如,任何需要一個`Graph`作為參數的函數都需要泛型化的`N'ode和`E'dge類型: ~~~ fn distance<N, E, G: Graph<N, E>>(graph: &G, start: &N, end: &N) -> u32 { ... } ~~~ 我們的距離計算并不需要`Edge`類型,所以函數簽名中`E`只是寫著玩的。 我們需要的是對于每一種`Graph`類型,都使用一個特定的的`N'ode和`E'dge類型。我們可以用關聯類型來做到這一點: ~~~ trait Graph { type N; type E; fn has_edge(&self, &Self::N, &Self::N) -> bool; fn edges(&self, &Self::N) -> Vec<Self::E>; // etc } ~~~ 現在,我們使用一個抽象的`Graph`了: ~~~ fn distance<G: Graph>(graph: &G, start: &G::N, end: &G::N) -> uint { ... } ~~~ 這里不再需要處理`E'dge類型了。 讓我們更詳細的回顧一下。 ## 定義關聯類型 讓我們構建一個`Graph`特性。這里是定義: ~~~ trait Graph { type N; type E; fn has_edge(&self, &Self::N, &Self::N) -> bool; fn edges(&self, &Self::N) -> Vec<Self::E>; } ~~~ 十分簡單。關聯類型使用`type`關鍵字,并出現在特性體和函數中。 這些`type`聲明跟函數定義一樣。例如,如果我們想`N`類型實現`Display`,這樣我們就可以打印出點類型,我們可以這樣寫: ~~~ use std::fmt; trait Graph { type N: fmt::Display; type E; fn has_edge(&self, &Self::N, &Self::N) -> bool; fn edges(&self, &Self::N) -> Vec<Self::E>; } ~~~ ## 實現關聯類型 就像任何特性,使用關聯類型的特性用`impl`關鍵字來提供實現。下面是一個`Graph`的簡單實現: ~~~ struct Node; struct Edge; struct MyGraph; impl Graph for MyGraph { type N = Node; type E = Edge; fn has_edge(&self, n1: &Node, n2: &Node) -> bool { true } fn edges(&self, n: &Node) -> Vec<Edge> { Vec::new() } } ~~~ 這個可笑的實現總是返回`true`和一個空的`Vec`,不過它提供了如何實現這類特性的思路。首先我們需要3個`struct`,一個代表圖,一個代表點,還有一個代表邊。如果使用別的類型更合理,也可以那樣做,我們只是準備使用`struct`來代表這3個類型。 接下來是`impl`行,它就像其它任何特性的實現。 在這里,我們使用`=`來定義我們的關聯類型。特性使用的名字出現在`=`的左邊,而我們`impl`的具體類型出現在右邊。最后,我們在函數聲明中使用具體類型。 ## 特性對象和關聯類型 這里還有另外一個我們需要討論的語法:特性對象。如果你創建一個關聯類型的特性對象,像這樣: ~~~ let graph = MyGraph; let obj = Box::new(graph) as Box<Graph>; ~~~ 你會得到兩個錯誤: ~~~ error: the value of the associated type `E` (from the trait `main::Graph`) must be specified [E0191] let obj = Box::new(graph) as Box<Graph>; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24:44 error: the value of the associated type `N` (from the trait `main::Graph`) must be specified [E0191] let obj = Box::new(graph) as Box; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ 我們不能這樣創建一個特性對象,因為我們并不知道關聯的類型。相反,我們可以這樣寫: ~~~ let graph = MyGraph; let obj = Box::new(graph) as Box<Graph<N=Node, E=Edge>>; ~~~ `N=Node`語法允許我們提供一個具體類型,`Node`,作為`N`類型參數。`E=Edge`也是一樣。如果我們不提供這個限制,我們不能確定應該`impl`那個來匹配特性對象。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看