设为首页 加入收藏

TOP

elixir 入门笔记(三)
2017-10-09 13:49:47 】 浏览:4439
Tags:elixir 入门 笔记
llo
, "world"} :ok iex> flush :ok

也可以通过 receive/1 函数来接收

iex> send self(), {:hello, "world"}
{:hello, "world"}
iex> receive do
...> {:hi, msg} -> msg
...> {:hello, msg} -> msg
...> end
"world"

receive/1 函数收不到消息会阻塞,可以给它设置一个超时时间

iex> receive do
...> {:hello, msg} -> msg
...> after
...> 3000 -> "timeout"
...> end
"timeout"
  • 进程间的连接
    进程B连接进程A之后,进程A出现异常,进程B就能捕获,这样进程B就能处理进程A的异常
    进程连接的方式很简单,就是 spawn_link/1 函数

    iex> spawn fn -> raise "oops" end
    #PID<0.76.0>
    
    15: 18:22.804 [error] Process #PID<0.76.0> raised an exception
    ** (RuntimeError) oops
    :erlang.apply/2
    
    iex> spawn_link fn -> raise "oops" end
    ** (EXIT from #PID<0.73.0>) an exception was raised:
    ** (RuntimeError) oops
    :erlang.apply/2
    
    15: 18:31.533 [error] Process #PID<0.78.0> raised an exception
     ** (RuntimeError) oops
     :erlang.apply/2

    关注 Process模块 模块,里面提供了进程操作的函数

  • 进程中保存状态的方法:

    defmodule KV do
      def start do
        {:ok, spawn_link(fn -> loop(%{}) end)}
      end
    
      defp loop(map) do
        receive do
          {:get, key, caller} ->
            send caller, Map.get(map, key)
            loop(map)
          {:put, key, value} ->
            loop(Map.put(map, key, value))
        end
      end
    end
    iex> send pid, {:put, :hello, :world}
    #PID<0.62.0>
    iex> send pid, {:get, :hello, self()}
    {:get, :hello, #PID<0.41.0>}
    iex> flush
    :world

    实际使用时,可以用 Agent 模块 来简化上面的操作。

  • 模块属性

    elixir中模块的属性主要有3个作用:

    1. 作为一个模块的注释,通常附加上用户或虚拟机用到的信息
    2. 作为常量
    3. 在编译时作为一个临时的模块存储

    注释

    注释时,一些常用的模块属性如下:

    名称 含义
    @moduledoc 为当前模块提供文档
    @doc 为该属性后面的函数或宏提供文档
    @behaviour (注意这个单词是英式拼法)用来注明一个OTP或用户自定义行为
    @before\_compile 提供一个每当模块被编译之前执行的钩子。这使得我们可以在模块被编译之前往里面注入函数。

    常量

    作为常量:

    defmodule MyServer do
      @my_data 14
      def first_data, do: @my_data
      @my_data 13
      def second_data, do: @my_data
    end

    测试方法:

    iex> MyServer.first_data
    14
    
    iex> MyServer.second_data
    13

    临时存储

    模块中的变量只在编译时存在,所以用做临时存储,存储一些只在编译时使用的变量。
    示例:

    defmodule MyServer do
      @my_data 14
      def first_data, do: @my_data
      @my_data 13
      def second_data, do: @my_data
    end
    
    iex> MyServer.first_data #=> 14
    iex> MyServer.second_data #=> 13

    结构体

    1. 定义

      defmodule User do
        defstruct name: "harry", age: 32
      end
    2. 使用方式

      iex> j = %User{}
      %User{age: 32, name: "harry"}
      
      iex> j.name
      "harry"
      
      iex> j[:name]
      ** (UndefinedFunctionError) undefined function User.fetch/2
                   User.fetch(%User{age: 32, name: "harry"}, :name)
          (elixir) lib/access.ex:77: Access.get/3
      
      iex> j.__struct__
      User

    协议

    协议类似于其他语言中的接口,谁实现了协议,谁就可以使用协议,
    比如下面的例子,Integer 和 User 结构体实现了协议,就可以使用协议中的方法。

    defmodule User do
      defstruct name: "harry", age: 32
    end
    
    defprotocol Enough do
      def enough?(data)
    end
    
    defimpl Enough, for: Integer do
      def enough?(data) do
        if data > 0 do
          true
        else
          false
        end
      end
    end
    
    defimpl Enough, for: User do
      def enough?(data) do
        if data.age > 18 do
          true
        else
          false
        end
      end
    end

    使用示例:

    iex> Enough.enough?(11)
    true
    iex> Enough.enough?(0)
    false
    
    iex> u = %User{}
    %User{age: 32, name: "harry"}
    iex> Enough.enough?(u)
    true
    
    iex> u = %{u|age: 10}
    %User{age: 10, name: "harry"}
    iex> Enough.enough?(u)
    false
    
    iex> Enough.enough?("string")
     ** (Protocol.UndefinedErro
    首页 上一页 1 2 3 4 下一页 尾页 3/4/4
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇elixir mix 简介 下一篇一个数据库读写模型的设想

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目