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

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                14-模塊屬性 =========== [作為注釋](#141-%E4%BD%9C%E4%B8%BA%E6%B3%A8%E9%87%8A) [作為常量](#142-%E4%BD%9C%E4%B8%BA%E5%B8%B8%E9%87%8F) [作為臨時存儲](#143-%E4%BD%9C%E4%B8%BA%E4%B8%B4%E6%97%B6%E5%AD%98%E5%82%A8) 在Elixir中,模塊屬性(attributes)主要服務于三個目的: 1. 作為一個模塊的注釋,通常附加上用戶或虛擬機用到的信息 2. 作為常量 3. 在編譯時作為一個臨時的存儲機制 讓我們一個一個講解。 ## 14.1-作為注釋 Elixir從Erlang帶來了模塊屬性的概念。例子: ```elixir defmodule MyServer do @vsn 2 end ``` 這個例子中,我們顯式地為該模塊設置了 _版本(vsn即version)_ 屬性。 屬性標識```@vsn```是預定義的屬性名稱,會被Erlang虛擬機的代碼裝載機制使用: 讀取并檢查該模塊是否在某處被更新了。 如果不注明版本號,會被自動設置為這個模塊函數的md5 checksum。 Elixir有個好多系統保留的預定義屬性。比如一些常用的: - @moduledoc 為整個模塊提供文檔說明 - @doc 為該屬性后面的函數或宏提供文檔說明 - @behaviour (注意這個單詞是英式拼法)用來注明一個OTP或用戶自定義行為 - @before_compile 提供一個每當模塊被編譯之前執行的鉤子。這使得我們可以在模塊被編譯之前往里面注入函數。 @moduledoc和@doc是很常用的屬性,推薦經常使用(寫文檔)。 Elixir視文檔為一等公民,提供了很多方法來訪問文檔。 讓我們回到上幾章定義的Math模塊,為它添加文檔,然后依然保存在math.ex文件中: ```elixir defmodule Math do @moduledoc """ Provides math-related functions. ## Examples iex> Math.sum(1, 2) 3 """ @doc """ Calculates the sum of two numbers. """ def sum(a, b), do: a + b end ``` 上面例子使用了heredocs注釋。heredocs是多行的文本,用三個引號包裹,保持里面內容的格式。 下面例子演示在iex中,用h命令讀取模塊的注釋: ```elixir $ elixirc math.ex $ iex iex> h Math # Access the docs for the module Math ... iex> h Math.sum # Access the docs for the sum function ... ``` Elixir還提供了[ExDoc工具](https://github.com/elixir-lang/ex_doc), 利用注釋生成HTML頁文檔。 你可以看看[模塊](http://elixir-lang.org/docs/stable/elixir/Module.html) 里面列出的模塊屬性列表,看看Elixir還支持那些模塊屬性。 Elixir還是用這些屬性來定義 [typespecs](http://elixir-lang.org/docs/stable/elixir/Kernel.Typespec.html): - @spec 為一個函數提供specification - @callback 為行為回調函數提供spec - @type 定義一個@spec中用到的類型 - @typep 定義一個私有類型,用于@spec - @opaque 定義一個opaque類型用于@spec 本節講了一些內置的屬性。當然,屬性可以被開發者、被一些類庫擴展用來支持自定義的行為。 ## 14.2-作為常量 Elixir開發者經常會將模塊屬性當作常量定義使用: ```elixir defmodule MyServer do @initial_state %{host: "147.0.0.1", port: 3456} IO.inspect @initial_state end ``` >不同于Erlang,默認情況下用戶定義的屬性不會被存儲在模塊里。屬性值僅在編譯時存在。 開發者可以通過調用```Module.register_attribute/3```來使屬性的行為更接近Erlang。 訪問一個未定義的屬性會報警告: ```elixir defmodule MyServer do @unknown end warning: undefined module attribute @unknown, please remove access to @unknown or explicitly set it to nil before access ``` 最后,屬性也可以在函數中被讀取: ```elixir defmodule MyServer do @my_data 14 def first_data, do: @my_data @my_data 13 def second_data, do: @my_data end MyServer.first_data #=> 14 MyServer.second_data #=> 13 ``` 注意,在函數內讀取某屬性,讀取的是該屬性當前值的快照。換句話說,讀取的是編譯時的值,而非運行時。 后面我們將看到,這個特點使得屬性可以作為模塊在編譯時的臨時存儲。 ## 14.3-作為臨時存儲 Elixir組織中有一個項目,叫做[Plug](https://github.com/elixir-lang/plug)。 這個項目的目標是創建一個通用的Web庫和框架。 >類似于ruby的rack Plug庫允許開發者定義它們自己的plug,可以在一個web服務器上運行: ```elixir defmodule MyPlug do use Plug.Builder plug :set_header plug :send_ok def set_header(conn, _opts) do put_resp_header(conn, "x-header", "set") end def send_ok(conn, _opts) do send(conn, 200, "ok") end end IO.puts "Running MyPlug with Cowboy on http://localhost:4000" Plug.Adapters.Cowboy.http MyPlug, [] ``` 上面例子我們用了```plug/1```宏來連接各個在處理請求時會被調用的函數。 在內部,每當你調用```plug/1```時,Plug把參數存儲在@plug屬性里。 在模塊被編譯之前,Plug執行一個回調函數,這個函數定義了處理http請求的方法。 這個方法將順序執行所有保存在@plug屬性里的plugs。 為了理解底層的代碼,我們需要宏。因此我們將回顧一下元編程手冊里這種模式。 但是這里的重點是怎樣使用屬性來存儲數據,讓開發者得以創建DSL(領域特定語言)。 另一個例子來自ExUnit框架,它使用模塊屬性作為注釋和存儲: ```elixir defmodule MyTest do use ExUnit.Case @tag :external test "contacts external service" do # ... end end ``` ExUnit中,@tag標簽被用來注釋該測試用例。之后,這些標簽可以作為過濾測試用例之用。 例如,你可以避免執行那些被標記成```:external```的測試,因為它們執行起來很慢。 本章帶你一窺Elixir元編程的冰山一角,講解了模塊屬性在開發中是如何扮演關鍵角色的。 下一章將講解結構體和協議。
                  <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>

                              哎呀哎呀视频在线观看