文档章节

elixir官方入门教程 结构体

ljzn
 ljzn
发布于 2016/08/05 10:44
字数 729
阅读 40
收藏 0
点赞 0
评论 0

#结构体

  1. 定义结构体
  2. 访问和更新结构体
  3. 结构体的底层是映射

在第七章,我们学习过了映射:

iex> map = %{a: 1, b: 2}
%{a: 1, b: 2}
iex> map[:a]
1
iex> %{map | a: 3}
%{a: 3, b: 2}

结构体是建立在映射的基础之上,提供了编译时检查和默认值设置.

#定义结构体

可以使用defstruct结构定义结构体:

iex> defmodule User do
...>   defstruct name: "John", age: 27
...> end

defstruct中使用的关键词列表定义了结构体领域中的默认值.

结构体会以其定义所处于的模块来命名.比如上面的例子中,我们定义了一个名为User的结构体.

我们现在可以用与创建映射类似的语法来创建结构体User:

iex> %User{}
%User{age: 27, name: "John"}
iex> %User{name: "Meg"}
%User{age: 27, name: "Meg"}

结构体提供了编译时确认,也就是只有在defsturct中定义了的领域能够存在于一个结构体中:

iex> %User{oops: :field}
** (CompileError) iex:3: unknown key :oops for struct User

#获取与更新结构体

当我们讨论映射时,我们展示了如何获取和更新映射中的领域.对与结构体,还是同样的技术(同样的语法):

iex> john = %User{}
%User{age: 27, name: "John"}
iex> john.name
"John"
iex> meg = %{john | name: "Meg"}
%User{age: 27, name: "Meg"}
iex> %{meg | oops: :field}
** (KeyError) key :oops not found in: %User{age: 27, name: "Meg"}

当使用更新符号(|)时,VM会意识到没有新的键添加到结构体中,同时会允许底层的映射分享它们的结构.上述例子中,johnmeg在内存中分享着相同的键结构.

结构体也可用于模式匹配,需要同时匹配特定的键值和结构体的类型:

iex> %User{name: name} = john
%User{age: 27, name: "John"}
iex> name
"John"
iex> %User{} = %{}
** (MatchError) no match of right hand side value: %{}

#结构体的底层是映射

在上述例子中,模式匹配之所以能成功,是因为结构体的底层是被锁定了领域的映射.作为映射,结构体拥有一个"特殊"的领域叫做__struct__,里面是结构体的名字:

iex> is_map(john)
true
iex> john.__struct__
User

注意我们称结构体是裸露的映射,因为所有对映射生效的协议,结构体都不可用.例如,你既不能枚举也不能进入一个结构体:

iex> john = %User{}
%User{age: 27, name: "John"}
iex> john[:name]
** (UndefinedFunctionError) undefined function: User.fetch/2
iex> Enum.each john, fn({field, value}) -> IO.puts(value) end
** (Protocol.UndefinedError) protocol Enumerable not implemented for %User{age: 27, name: "John"}

然而,结构体也是映射,能够使用Map模块中的函数:

iex> kurt = Map.put(%User{}, :name, "Kurt")
%User{age: 27, name: "Kurt"}
iex> Map.merge(kurt, %User{name: "Takashi"})
%User{age: 27, name: "Takashi"}
iex> Map.keys(john)
[:__struct__, :age, :name]

结构体协议为Elixir开发者提供了一个重要特性:数据多态性.这是我们将在下一章探索的.

© 著作权归作者所有

共有 人打赏支持
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
总有你要的编程书单(GitHub )

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

汇智网
2017/11/22
0
0
elixir官方入门教程 学习资料

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

ljzn
2016/08/06
144
0
elixir官方入门教程 Erlang库

Erlang库 二进制模块 格式化文本输出 加密模块 图片模块 Erlang长期存储 数学模块 队列模块 随机模块 压缩模块 Elixir提供了与Erlang库优秀的互用性.事实上,Elixir不鼓励简单地包装Erlang库,...

ljzn
2016/08/06
59
0
elixir官方入门教程 模块

模块 编译 脚本模式 具名函数 函数捕获 默认参数 在Elixir中我们将一些函数集合到模块里。在之前的章节里我们已经使用了许多不同的模块,例如模块: 为了创造我们自己的模块,需要用到宏。我...

ljzn
2016/08/03
54
0
elixir官方教程 元编程(一) 引用与去引用

引用与去引用 引用(Quoting) 去引用(Unquoting) 释放(Escaping) 一个Elixir程序可以用它自己的数据结构来表现.本章,我们将会学习这些结构体的特点和如何组成它们.本章我们要学习的概念是为宏...

ljzn
2016/08/13
44
0
elixir官方入门教程 进程

进程 和 链接 任务 状态 在Elixir中,所有代码都运行在进程内。进程相互独立,并发地运行,通过传送信息来交流。进程不是Elixir中唯一的并发基础,但它意味着能够构建分布式的,可容错的程序...

ljzn
2016/08/04
34
0
开源电子书

目录 语言无关类 操作系统 智能系统 分布式系统 编译原理 函数式概念 计算机图形学 WEB服务器 版本控制 编辑器 NoSQL PostgreSQL MySQL 管理和监控 项目相关 设计模式 Web 大数据 编程艺术 ...

zting科技
2017/12/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

利用世界杯,读懂 Python 装饰器

Python 装饰器是在面试过程高频被问到的问题,装饰器也是一个非常好用的特性, 熟练掌握装饰器会让你的编程思路更加宽广,程序也更加 pythonic。 今天就结合最近的世界杯带大家理解下装饰器。...

p柯西
16分钟前
0
0
Xshell登录阿里云服务器ECS

Xshell登录阿里云服务器ECS 1. 参考资料: 1). 《阿里云服务器怎么用?阿里云服务器使用教程》 链接:http://www.cr173.com/html/50758_1.html 2). eagle-zhang的CSDN博客《Xshell连接不上阿...

SuShine
26分钟前
1
0
IDEA中的HTTP Client Editor测试API

在前后端分离项目,前后端通过api进行通信。如果用postman免费版进行api测试的话,由于无法保存测试脚本到文件,不方便前端查看。 你可以选择付费版。也可以利用IDEA自带的HTTP Client Edito...

hutaishi
28分钟前
0
0
解决“只能通过Chrome网上应用商店安装该程序”的方法

摘要 : 最近有些用户反映某个Chrome插件在安装的时候,提示“只能通过Chrome网上应用商店安装该程序”,为了解决这一问题,Chrome插件网带来了相关的解决方法。 某些用户在Chrome插件网下载了...

沧海一刀
30分钟前
0
0
通过UNIX域套接字传递文件描述符

  传送文件描述符是高并发网络服务编程的一种常见实现方式。Nebula 高性能通用网络框架即采用了UNIX域套接字传递文件描述符设计和实现。本文详细说明一下传送文件描述符的应用。 1. TCP服务...

Bwar
33分钟前
0
0
python操作Excle

# -*- coding: utf-8 -*-from openpyxl import load_workbook, Workbook#index:第几个sheet页,第一个sheet页的index为0def readExcle(filename,index): # 加载excle文件 wb = l......

淺陌离殇
34分钟前
0
0
Apache爆日志文件漏洞

全球使用最广泛的Web服务器Apache近日被爆出了一个安全漏洞,该漏洞可能导致攻击者控制服务器。 该漏洞包含在mod_rewrite 模块中的do_rewritelog()日志函数中。由于该函数还无法完全过滤写入...

问题终结者
今天
0
0
阿里巴巴内部开发手册

现代软件架构的复杂性需要协同开发完成,如何高效地协同呢?无规矩不成方圆,无规范难以协同,比如,制订交通法规表面上是要限制行车权,实际上是保障公众的人身安全,试想如果没有限速,没有...

zbbmaster
今天
0
0
34.任务计划cron chkconfig systemctl管理服务 unit target

10.23 linux任务计划cron 10.24 chkconfig工具 10.25 systemd管理服务 10.26 unit介绍 10.27 target介绍 10.23 linux任务计划cron: 在linux中任务计划是必不可少的,因为可能我们凌晨的时候...

王鑫linux
今天
0
0
logback.xml for spring boot

logback.xml config <?xml version="1.0" encoding="UTF-8"?><configuration> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.Colo......

qwfys
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部