<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                7-鍵值列表-圖-字典 ================ [鍵值列表](#71) [圖](#72-%E5%9B%BEmaps) [字典](#73-%E5%AD%97%E5%85%B8dicts) 到目前還沒有講到任何關聯性數據結構,即那種可以將一個或幾個值關聯到一個key上。 不同語言有不同的叫法,如字典,哈希,關聯數組,圖,等等。 Elixir中有兩種主要的關聯性結構:鍵值列表(keyword list)和圖(map)。 ## 7.1-鍵值列表 在很多函數式語言中,常用二元元組的列表來表示關聯性數據結構。在Elixir中也是這樣。 當我們有了一個元組(不一定僅有兩個元素的元組)的列表,并且每個元組的第一個元素是個 **原子**, 那就稱之為鍵值列表: ```elixir iex> list = [{:a, 1}, {:b, 2}] [a: 1, b: 2] iex> list == [a: 1, b: 2] true iex> list[:a] 1 ``` >當原子key和關聯的值之間沒有逗號分隔時,可以把原子的冒號拿到字母的后面。這時,原子與后面的數值之間要有一個空格。 如你所見,Elixir使用比較特殊的語法來定義這樣的列表,但實際上它們會映射到一個元組列表。 因為它們是簡單的列表而已,所有針對列表的操作,鍵值列表也可以用。 比如,可以用```++```運算符為列表添加元素: ```elixir iex> list ++ [c: 3] [a: 1, b: 2, c: 3] iex> [a: 0] ++ list [a: 0, a: 1, b: 2] ``` 上面例子中重復出現了```:a```這個key,這是允許的。 以這個key取值時,取回來的是第一個找到的(因為有序): ```elixir iex> new_list = [a: 0] ++ list [a: 0, a: 1, b: 2] iex> new_list[:a] 0 ``` 鍵值列表十分重要,它有兩大特點: - 有序 - key可以重復(!仔細看上面兩個示例) 例如,[Ecto庫](https://github.com/elixir-lang/ecto)使用這兩個特點 寫出了精巧的DSL(用來寫數據庫query): ```elixir query = from w in Weather, where: w.prcp > 0, where: w.temp < 20, select: w ``` 這些特性使得鍵值列表成了Elixir中為函數提供額外選項的默認手段。 在第5章我們討論了```if/2```宏,提到了下方的語法: ```elixir iex> if false, do: :this, else: :that :that ``` do: <block>和else: <block> 就是鍵值列表!事實上代碼等同于: ```elixir iex> if(false, [do: :this, else: :that]) :that ``` 當鍵值列表是函數最后一個參數時,方括號就成了可選的。 為了操作關鍵字列表,Elixir提供了 [鍵值(keyword)模塊](http://elixir-lang.org/docs/stable/elixir/Keyword.html)。 記住,鍵值列表就是簡單的列表,和列表一樣提供了線性的性能。 列表越長,獲取長度或找到一個鍵值的速度越慢。 因此,關鍵字列表在Elixir中一般就作為函數調用的可選項。 如果你要存儲大量數據,并且保證一個鍵只對應最多一個值,那就使用圖。 對鍵值列表做模式匹配: ```elixir iex> [a: a] = [a: 1] [a: 1] iex> a 1 iex> [a: a] = [a: 1, b: 2] ** (MatchError) no match of right hand side value: [a: 1, b: 2] iex> [b: b, a: a] = [a: 1, b: 2] ** (MatchError) no match of right hand side value: [a: 1, b: 2] ``` 盡管如此,對列表使用模式匹配很少用到。因為不但要元素個數相等,順序還要匹配。 ## 7.2-圖(maps) 無論何時想用鍵-值結構,圖都應該是你的第一選擇。Elixir中,用```%{}```定義圖: ```elixir iex> map = %{:a => 1, 2 => :b} %{2 => :b, :a => 1} iex> map[:a] 1 iex> map[2] :b ``` 和鍵值列表對比,圖有兩主要區別: - 圖允許任何類型值作為鍵 - 圖的鍵沒有順序 如果你向圖添加一個已有的鍵,將會覆蓋之前的鍵-值對: ```elixir iex> %{1 => 1, 1 => 2} %{1 => 2} ``` 如果圖中的鍵都是原子,那么你也可以用鍵值列表中的一些語法: ```elixir iex> map = %{a: 1, b: 2} %{a: 1, b: 2} ``` 對比鍵值列表,圖的模式匹配很是有用: ```elixir iex> %{} = %{:a => 1, 2 => :b} %{:a => 1, 2 => :b} iex> %{:a => a} = %{:a => 1, 2 => :b} %{:a => 1, 2 => :b} iex> a 1 iex> %{:c => c} = %{:a => 1, 2 => :b} ** (MatchError) no match of right hand side value: %{2 => :b, :a => 1} ``` 如上所示,圖A與另一個圖B做匹配。 圖B中只要包含有圖A的鍵,那么兩個圖就能匹配上。若圖A是個空的,那么任意圖B都能匹配上。 但是如果圖B里不包含圖A的鍵,那就匹配失敗了。 圖還有個有趣的功能:它提供了特殊的語法來修改和訪問原子鍵: ```elixir iex> map = %{:a => 1, 2 => :b} %{:a => 1, 2 => :b} iex> map.a 1 iex> %{map | :a => 2} %{:a => 2, 2 => :b} iex> %{map | :c => 3} ** (ArgumentError) argument error ``` 使用上面兩種語法要求的前提是所給的鍵是切實存在的。最后一條語句錯誤的原因就是鍵```:c```不存在。 未來幾章中我們還將討論結構體(structs)。結構體提供了編譯時的保證,它是Elixir多態的基礎。 結構體是基于圖的,上面例子提到的修改鍵值的前提就變得十分重要。 [圖模塊](http://elixir-lang.org/docs/stable/elixir/Map.html)提供了許多關于圖的操作。 它提供了與鍵值列表許多相似的API,因為這兩個數據結構都實現了字典的行為。 >圖是最近連同[EEP 43](http://www.erlang.org/eeps/eep-0043.html)被引入Erlang虛擬機的。 Erlang 17提供了EEP的部分實現,只支持_一小部分_圖功能。 這意味著圖僅在存儲不多的鍵時,圖的性能還行。 為了解決這個問題,Elixir還提供了 [HashDict模塊](http://elixir-lang.org/docs/stable/elixir/HashDict.html)。 該模塊提供了一個字典來支持大量的鍵,并且性能不錯。 ## 7.3-字典(Dicts) Elixir中,鍵值列表和圖都被稱作字典。 換句話說,一個字典就像一個接口(在Elixir中稱之為行為behaviour)。 鍵值列表和圖模塊實現了該接口。 這個接口定義于[Dict模塊](http://elixir-lang.org/docs/stable/elixir/Dict.html), 該模塊還提供了底層實現的一個API: ```elixir iex> keyword = [] [] iex> map = %{} %{} iex> Dict.put(keyword, :a, 1) [a: 1] iex> Dict.put(map, :a, 1) %{a: 1} ``` 字典模塊允許開發者實現自己的字典形式,提供一些特殊的功能。 字典模塊還提供了所有字典類型都可以使用的函數。 如,```Dicr.equal?/2```可以比較兩個字典類型(可以是不同的實現)。 你會疑惑些程序時用keyword,Map還是Dict模塊呢?答案是:看情況。 如果你的代碼期望接受一個關鍵字作為參數,那么使用簡直列表模塊。 如果你想操作一個圖,那就使用圖模塊。 如果你想你的API對所有字典類型的實現都有用, 那就使用字典模塊(確保以不同的實現作為參數測試一下)。
                  <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>

                              哎呀哎呀视频在线观看