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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                13-別名和代碼引用 ================= [別名](#131-%E5%88%AB%E5%90%8D) [require](#132-require) [import](#133-import) [別名機制](#134-%E5%88%AB%E5%90%8D%E6%9C%BA%E5%88%B6) [嵌套](#135-%E5%B5%8C%E5%A5%97) 為了實現軟件重用,Elixir提供了三種指令(directives)。 之所以稱之為“指令”,是因為它們的作用域是詞法作用域(lexicla scope)。 ## 13.1-別名 宏```alias```可以為任何模塊名設置別名。 想象一下Math模塊,它針對特殊的數學運算使用了特殊的列表實現: ```elixir defmodule Math do alias Math.List, as: List end ``` 現在,任何對```List```的引用將被自動變成對```Math.List```的引用。 如果還想訪問原來的```List```,需要前綴'Elixir': ```elixir List.flatten #=> uses Math.List.flatten Elixir.List.flatten #=> uses List.flatten Elixir.Math.List.flatten #=> uses Math.List.flatten ``` >Elixir中定義的所有模塊都在一個主Elixir命名空間。 但是為方便起見,我們平時都不再前面加‘Elixir’。 別名常被使用于定義快捷方式。實際上不帶```as```選項去調用```alias```會 自動將這個別名設置為模塊名的最后一部分: ```elixir alias Math.List ``` 就相當于: ```elixir alias Math.List, as: List ``` 注意,別名是**詞法作用域**。即,你在某個函數中設置別名: ```elixir defmodule Math do def plus(a, b) do alias Math.List # ... end def minus(a, b) do # ... end end ``` 例子中```alias```指令只在函數```plus/2```中有用,```minus/2```不受影響。 ## 13.2-require Elixir提供了許多宏,用于元編程(寫能生成代碼的代碼)。 宏也是一堆代碼,但它在編譯時被展開和執行。 就是說為了使用一個宏,你需要確保它定義的模塊和實現在編譯期時可用。 要使用宏,需要用```require```指令引入定義宏的模塊: ```elixir iex> Integer.odd?(3) ** (CompileError) iex:1: you must require Integer before invoking the macro Integer.odd?/1 iex> require Integer nil iex> Integer.odd?(3) true ``` Elixir中,```Integer.odd?/1```函數被定義為一個宏,它可以被當作衛兵表達式(guards)使用。 為了調用這個宏,首先得用```require```引用了_Integer_模塊。 總的來說,宏在被用到之前不需要早早被require引用進來,除非我們想讓這個宏在整個模塊中可用。 嘗試調用一個沒有引入的宏會導致報錯。 注意,像```alias```指令一樣,```require```也是詞法作用域的。 下文中我們會進一步討論宏。 ## 13.3-import 當想輕松地訪問別的模塊中的函數和宏時,可以使用```import```指令加上宏定義模塊的完整名字。 例如,如果我們想多次使用List模塊中的```duplicate```函數,我們可以這么import它: ```elixir iex> import List, only: [duplicate: 2] nil iex> duplicate :ok, 3 [:ok, :ok, :ok] ``` 這個例子中,我們只從List模塊導入了函數```duplicate/2```。 盡管```only:```選項是可選的,但是推薦使用。 除了```only:```選項,還有```except:```選項。 使用選項```only:```,還可以傳遞給它```:macros```或```:functions```。 如下面例子,程序僅導入Integer模塊中所有的宏: ```elixir import Integer, only: :macros ``` 或者,僅導入所有的函數: ```elixir import Integer, only: :functions ``` 注意,```import```也是**詞法作用域**,意味著我們可以在某特定函數中導入宏或方法: ```elixir defmodule Math do def some_function do import List, only: [duplicate: 2] # call duplicate end end ``` 在此例子中,導入的函數```List.duplicate/2```只在那個函數中可見。 該模塊的其它函數中都不可用(自然,別的模塊也不受影響)。 注意,若import一個模塊,將自動require它。 ## 13.4-別名機制 講到這里你會問,Elixir的別名到底是什么,它是怎么實現的? Elixir中的別名是以大寫字母開頭的標識符(像String, Keyword等等),在編譯時會被轉換為原子。 例如,別名‘String’會被轉換為```:"Elixir.String"```: ```elixir iex> is_atom(String) true iex> to_string(String) "Elixir.String" iex> :"Elixir.String" String ``` 使用```alias/2```指令,其實只是簡單地改變了這個別名將要轉換的結果。 別名如此這般工作,是因為在Erlang虛擬機中(以及上面的Elixir),模塊名是被表述成原子的。 例如,我們調用一個Erlang模塊的機制是: ```elixir iex> :lists.flatten([1,[2],3]) [1, 2, 3] ``` 這也是允許我們動態調用模塊函數的機制: ```elixir iex> mod = :lists :lists iex> mod.flatten([1,[2],3]) [1,2,3] ``` 一句話,我們只是簡單地在原子```:lists```上調用了函數```flatten```。 ## 13.5-嵌套 介紹了別名,現在可以講講嵌套(nesting)以及它在Elixir中是如何工作的。 考慮下面的例子: ```elixir defmodule Foo do defmodule Bar do end end ``` 該例子定義了兩個模塊_Foo_和_Foo.Bar_。 后者在_Foo_中可以用_Bar_為名來訪問,因為它們在同一個詞法作用域中。 如果之后開發者決定把Bar模塊挪到另一個文件中,那它就需要以全名(Foo.Bar)或者別名來指代。 換句話說,上面的代碼等同于: ```elixir defmodule Elixir.Foo do defmodule Elixir.Foo.Bar do end alias Elixir.Foo.Bar, as: Bar end ``` ## 13.6-多個 到Elixir v1.2,可以一次使用alias,import,require多個模塊。這在建立Elixir程序的時候很常見,特別是使用嵌套的時候是最有用了。例如,假設你的程序所有模塊都嵌套在```MyApp```下,需要使用別名``` MyApp.Foo```,```MyApp.Bar```和```MyApp.Baz```,可以像下面一次完成: ```elixir alias MyApp.{Foo, Bar, Baz} ``` ## 13.7-```use``` use用于請求在當前上下文中允許使用其他模塊,是一個宏不是指令。開發者頻繁使用```use```宏在當前上下文范圍內引入其他功能,通常是模塊。 例如,在編寫測試時需要使用ExUni框架,開發者需要使用```ExUnit.Case``` 模塊: ```elixir defmodule AssertionTest do use ExUnit.Case, async: true test "always pass" do assert true end end ``` 在后面,```use```請求需要的模塊,然后調用```__using__/1```回調函數,允許模塊在當前上下文中注入這些代碼。總體說,如下模塊: ```exlixir defmodule Example do use Feature, option: :value end ``` 會編譯成 ```exlixir defmodule Example do require Feature Feature.__using__(option: :value) end ``` 在以后章節我們可以看到,別名在宏機制中扮演了很重要的角色,來保證宏是干凈的(hygienic)。 討論到這里,模塊基本上講得差不多了。之后會講解模塊的屬性。
                  <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>

                              哎呀哎呀视频在线观看