文档章节

elixir官方入门教程 类型规格与行为

ljzn
 ljzn
发布于 2016/08/06 16:46
字数 1166
阅读 54
收藏 0

#类型规格与行为

  1. 类型与规格
  2. 函数规格
  3. 自定义类型
  4. 静态代码分析
  5. 行为
  6. 定义行为
  7. 采用行为

#类型与规格

Elixir是一门动态类型语言,所以Elixir中的所有类型都会在运行时被判定.尽管如此,Elixir拥有类型规格,这是一个符号,用于:

  1. 声明自定义数据类型;
  2. 声明函数类型签名(规格).

##函数规格

Elixir默认提供一些基础类型,例如Integerpid,还有更复杂的类型:例如,round/1函数,它能将一个浮点数近似于一个整数,以一个number作为参数(integerfloat),返回一个integer.你能在它的文档中看到,round/1的类型签名是:

round(number) :: integer

::意味着左边的函数的_返回值_会是右边的类型.函数规格是使用@spec指令来写的,放在函数定义上面.函数round/1可以这样写:

@spec round(number) :: integer
def round(number), do: # implementation...

Elixir也支持复合类型.例如,一个整数列表的类型是[integer].你可以在类型规格文档中看到所有的Elixir内置类型.

##自定义类型

Elixir提供了一些有用的内置类型,但自定义合适的类型也很方便.方法是在定义模块时使用@type指令.

假设我们有一个LousyCalculator模块,它能进行普通的算术操作(求和,乘积等等),但是,它返回的不是一个数,而是一个元组,第一个元素是计算结果,第二个元素是随机的评论.

defmodule LousyCalculator do
  @spec add(number, number) :: {number, String.t}
  def add(x, y), do: {x + y, "You need a calculator to do that?!"}

  @spec multiply(number, number) :: {number, String.t}
  def multiply(x, y), do: {x * y, "Jeez, come on!"}
end

如你所见,元组是复合类型,每个元组是通过其中的类型来区分的.想知道为什么String.t不写作string,请查看类型规格中的标记文档.

我们可以这样定义函数规格,但是一直重复{number, String.t}很烦人.我们可以使用@type指令来声明我们自定义的类型.

defmodule LousyCalculator do
  @typedoc """
  Just a number followed by a string.
  """
  @type number_with_remark :: {number, String.t}

  @spec add(number, number) :: number_with_remark
  def add(x, y), do: {x + y, "You need a calculator to do that?"}

  @spec multiply(number, number) :: number_with_remark
  def multiply(x, y), do: {x * y, "It is like addition on steroids."}
end

@typedoc指令类似于@doc@moudledoc指令,用于注释自定义类型.

通过@type定义的类型可以被导出并在定义模块之外使用:

defmodule QuietCalculator do
  @spec add(number, number) :: number
  def add(x, y), do: make_quiet(LousyCalculator.add(x, y))

  @spec make_quiet(LousyCalculator.number_with_remark) :: number
  defp make_quiet({num, _remark}), do: num
end

如果你想将自定义类型设为私有的,可以用@typep替代@type.

##静态代码分析

类型规格的作用不止是额外注释.例如,Erlang工具Dialyzer就用类型规格来进行静态代码分析.这就是我们为什么在QuietCalculator中定义了一个私有函数make_quiet/1.

#行为

许多模块共享一样的公共API.看看插头,它是一个用于在网络应用中组合模块的规格.每个_插头_模块至少必须实现两个公共函数:init/1call/2.

行为提供了一种方法:

  • 定义需要被一个模块实现的一套函数;
  • 确保模块实现了所有函数

你可已将行为类比于例如Java的面向对象语言中的接口:一系列必须由模块实现的函数签名.

##定义行为

假设我们要实现一系列的语法解析器,解析结构化数据:例如,JSON解析器或YAML解析器.它们会有相同的行为:都提供了parse/1函数和extensions/0函数.parse/1函数将返回一个结构化数据的Elixir表述,而extensions/0函数会返回一个用于每种数据类型的文件扩展名列表,(例如.json用于JSON文件).

我们可以创建一个Parser行为:

defmodule Parser do
  @callback parse(String.t) :: any
  @callback extensions() :: [String.t]
end

接受了Parser行为的模块必须实现由@callback命令定义的所有函数.如你所见,@callback需要一个函数名以及一个如之前用@spec命令定义的函数规格.

##接受行为

接受行为很直接:

defmodule JSONParser do
  @behaviour Parser

  def parse(str), do: # ... parse JSON
  def extensions, do: ["json"]
end
defmodule YAMLParser do
  @behaviour Parser

  def parse(str), do: # ... parse YAML
  def extensions, do: ["yml"]
end

如果一个接受了给定行为的模块没有实现行为中的回调要求,那么就会生成一个编译时警告.

© 著作权归作者所有

共有 人打赏支持
ljzn
粉丝 29
博文 69
码字总数 96245
作品 0
南平
程序员
Elixir 学习资源

Elixir 官网 getting started官方入门学习资源 官方文档 hex 包管理系统 elixir sips 比较不错视频课程 Elixir China 中文论坛 官方wiki Elixir by Example Awesome Elixir Elixir Quiz 通过...

lidashuang
2017/11/29
0
0
elixir官方入门教程 介绍

介绍 安装 交互模式 运行脚本 提出疑问 欢迎! 在本教程中我们将教给你Elixir的基础,语法,如何定义模块,如何操作常用数据结构的特性等等.本章将确保Elixir安装好了,并且你能够成功运行Elixir的...

ljzn
2016/08/06
70
0
elixir官方教程Mix与OTP(一) Mix入门

Mix入门 我们的第一个项目 编辑项目 执行测试 环境 探索 在本教程中,我们将学习如何构建一个完整的Elixir应用,包括监督树,配置,测试等等. 这个应用的功能是分布式键值仓库.我们将把键值对安排...

ljzn
2016/08/07
1K
2
elixir官方入门教程 学习资料

下一步该去哪 构建你的第一个Elixir项目 元编程 社区与其它资源 Erlang基础 想要学习更多?继续阅读! 构建你的第一个Elixir项目 为了开始你的第一个项目,Elixir装载了一个叫做Mix的构建工具....

ljzn
2016/08/06
144
0
总有你要的编程书单(GitHub )

目录 IDE IntelliJ IDEA 简体中文专题教程 MySQL 21分钟MySQL入门教程 MySQL索引背后的数据结构及算法原理 NoSQL Disque 使用教程 Neo4j .rb 中文資源 Redis 命令参考 Redis 设计与实现 The ...

汇智网
2017/11/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

idea 通过jpa自动生成实体类

引入jpa包 打开persistence窗口 右键选择连接数据库 如果数据库没配置,则可以在下图选项中配置 选择好数据库和实体类的生成地址

斩神魂
27分钟前
1
0
tcpdump 命令

TCPDUMP简介 tcpdump 是一个很常用的网络包分析工具,可以用来显示通过网络传输到本系统的 TCP/IP 以及其他网络的数据包。tcpdump 使用 libpcap 库来抓取网络报,这个库在几乎在所有的 Linu...

寰宇01
35分钟前
2
0
软件的Alpha、Beta、RC、GA版本的区别

Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用。 Beta:也是测试版,这个阶段的版本会一直加入新的功能。在Alpha版之后推出。 RC:(Release Candidate) 顾名思义...

乔老哥
36分钟前
2
0
慢雾安全海贼王:从DApp亡灵军团,细说区块链安全

本文转载自微信公号“万向区块链”,为慢雾安全负责人海贼王在万向区块链实验室举办的2018上海区块链国际周-技术开放日上的演讲速记整理。 这张图总结了智能合约攻防的各个方面,分为两大部分...

万向区块链
42分钟前
13
0
Matlab编程之——卷积神经网络CNN代码解析

卷积神经网络CNN代码解析 deepLearnToolbox-master是一个深度学习matlab包,里面含有很多机器学习算法,如卷积神经网络CNN,深度信念网络DBN,自动编码AutoE ncoder(堆栈SAE,卷积CAE)的作...

酒逢知己千杯少
42分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部