Erlang和Elixir,第2部分:数据类型
Elixir有大量可用的数据类型。 常用的基本类型integer
, float
, boolean
和string
在这里,但是atom
/ symbol, list
, tuple
和anonymous functions
。 您将在本教程中了解所有有关它们的信息。
开始之前:我们将在Elixir的交互模式下运行这些示例。 在终端中输入iex
进入交互模式。 有关更多信息,请阅读本指南的第1部分 。 ( Windows用户运行iex.bat --werl
。)
前言
Elixir的构建考虑了元编程。 所有这些都是基于宏构建的。 如果您不熟悉宏,它们只是执行特定任务的一条指令 。 也许不太困难,但是这里有一些真实的例子:
if worked? doIO.puts("You just used a macro")
endif :name? doIO.puts(:name)end
if
这里是我们众所周知的标准条件if ...结构的宏。 Elixir将在内部为您编译宏的结果。
元编程?
Elixir的基础是引用表达式的操纵。
元编程本质上意味着您可以从代码创建代码(程序实际上具有将自己的代码视为数据的能力……确实是一个巨大的步骤。)
Elixir程序可以表示为自己的数据结构。
例如,Elixir的构建基块由具有三个元素的tuple
表示(稍后将在tuples
详细介绍)。 函数调用sum(1,2,3)
的定义如下:
{:sum, [], [1, 2, 3]}
您可以通过使用quote
宏来检索任何宏的表示形式:
iex> quote do: sum(1, 2, 3)
{:sum, [], [1, 2, 3]}
注意:除quote
宏之外,还有unquote
宏-您可以在Elixir文档中阅读有关该主题的更多信息 。
因此,我们看到第一个元素是:sum
的函数名称,第二个元素是包含元数据(当前示例中为空白)的keyword list
(稍后会详细介绍),第三个是参数列表。
所有宏都是使用这些数据结构构建的,因此这意味着我们的代码可以具有修改和重新编译自己的代码的固有能力。 因此,您的应用程序现在可以编写自己的代码,检查代码中的错误并进行修复,甚至可以扫描添加的插件并检查其中的代码并即时对其进行修改。
人工智能的意义显然是巨大的,但首先,在本指南中,我们必须继续进行基础研究,并在开始更深入地研究之前,对Elixir使用的各种数据类型有牢固的基础。
基本类型
现在您已经在交互式控制台中,让我们看一下Booleans
。
iex> true
true
iex> true == false
false
支持true
和false
的标准行为。 要检查该值,我们使用Elixir提供的函数is_boolean
。
iex> is_boolean(true)
true
iex> is_boolean(1)
false
每种类型还具有这些谓词功能之一。 例如, is_integer/1
, is_float/1
或is_number/1
全部将检查参数是否为整数,浮点数或两者之一。
Elixir始终以这种方式引用函数,在斜杠后面加一个数字以表示该函数采用的参数数量。 因此is_boolean/1
需要1个参数,例如is_boolean(1)
。
注意 :如果您想随时在交互式Shell中访问帮助,只需键入h
,您就可以访问有关如何使用Elixir Shell的信息。 另外,您可以使用h is_integer/1
来接收有关is_integer/1
文档,从而找到有关Elixir的任何运算符或函数的信息。
在数学上,我们还可以执行以下功能:
iex> round(3.58)
4
iex> trunc(3.58)
3
在Elixir中,当对integer
执行除法integer
,返回始终为float
:
iex> 5 / 2
2.5
iex> 10 / 2
5.0
如果我们想获得除法的余数或进行整数除法,可以这样使用div/2
和rem/2
函数:
iex> div(10, 2)
5
iex> div 10, 2
5
iex> rem 10, 3
1
注意:函数调用不需要括号。
您也可以只将任何binary
, octal
或hexadecimal
数字输入到iex
。
iex> 0b1010
10
iex> 0o777
511
iex> 0x1F
31
原子(符号)
这些就像constants
,但它们的名称是它们自己的值。 一些语言将此称为符号。 布尔true
和false
也是符号的示例。
iex> :hello
:hello
iex> :hello == :world
false
元组
与lists
类似,并由花括号定义,它们可以包含任何数据,如下所示:
iex> {:ok, "hello"}
{:ok, "hello"}
iex> tuple_size {:ok, "hello"}
2
清单
与tuples
类似,您可以定义一个带有方括号的list
,如下所示:
iex> [1, 2, true, 3]
[1, 2, true, 3]
iex> length [1, 2, 3]
3
可以串联和减去两个列表:
iex> [1, 2, 3] ++ [4, 5, 6]
[1, 2, 3, 4, 5, 6]
iex> [1, true, 2, false, 3, true] -- [true, false]
[1, 2, 3, true]
要返回列表的开头或列表的末尾,我们使用hd
和tl
函数(head和tail的缩写)。
列表和元组之间有什么区别?
Lists
以链接列表的形式存储在内存中,链接列表是在线性操作中迭代和访问的值对列表。 因此,只要我们将其追加到list
,更新就会很快,但是如果我们在list
进行修改,则操作会较慢。
另一方面, Tuples
连续存储在内存中。 这意味着获取元组的总大小或仅访问一个元素很快。 但是在这里,与列表相比,追加到现有tuple
的速度很慢,并且需要在内存中复制整个tuple
。
匿名函数
我们可以使用fn
和end
关键字定义一个函数。
iex> myFunc = fn a, b -> a + b end
#Function<12.71889879/2 in :erl_eval.expr/5>
iex> is_function(myFunc)
true
iex> is_function(myFunc, 2)
true
iex> is_function(myFunc, 1)
false
iex> myFunc.(1, 2)
3
Elixir的手册将匿名功能称为“头等公民”。 这意味着您可以像整数或字符串一样将参数传递给其他函数。
因此,在我们的示例中,我们已将变量myFunc
的匿名函数声明为is_function(myFunc)
检查函数,该函数正确返回了true
。 这意味着我们已经成功创建了我们的功能。
我们还可以通过调用is_function(myFunc, 2)
来检查myFunc
函数的参数数量。
注意:要调用匿名函数,必须在变量和括号之间使用点( .
)。
弦乐
iex> "yo"
"yo"
#
符号也支持插值:
iex> "Mr #{:Smith}"
"Mr Smith"
对于串联,请使用<>
。
iex> "foo" <> "bar"
"foobar"
要获取字符串的长度,请使用String.length
函数:
iex> String.length("yo")
2
要基于模式拆分字符串,可以使用String.split
方法:
iex> String.split("foo bar", " ")
["foo", "bar"]iex> String.split("foo bar!", [" ", "!"])
["foo", "bar", ""]
关键字清单
通常在编程中,可以创建两个数据项(本质上是两个tuples
的键值对,就像这样,其中键是atom
:
iex> list = [{:a, 1}, {:b, 2}]
[a: 1, b: 2]
iex> list == [a: 1, b: 2]
true
Elixir具有将列表定义为[key: value]
的语法。 然后,我们可以使用Elixir中可用的任何其他运算符(例如++
追加到列表的后面或前面。
iex> list ++ [c: 3]
[a: 1, b: 2, c: 3]
iex> [a: 0] ++ list
[a: 0, a: 1, b: 2]
关键字列表要记住三个要点:
- 键必须是
atoms
。 - 密钥是按开发人员指定的顺序排列的。
- 可以多次给出密钥。
对于数据库查询, Ecto库在执行查询时会使用此方法,如下所示:
query = from w in Weather,where: w.prcp > 0,where: w.temp < 20,select: w
Elixir的if
宏也将其纳入其设计:
iex> if(false, [{:do, :this}, {:else, :that}])
:that
通常,当列表是函数的参数时,方括号是可选的。
地图
与关键字列表类似, maps
可以帮助您满足键值对的需求。 它们是通过%{}
语法创建的,如下所示:
iex> map = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> map[:a]
1
iex> map[2]
:b
iex> map[:c]
nil
它们类似于关键字列表,但不完全相同-有两个区别:
- 映射允许将任何值用作键。
- 地图的键不遵循任何顺序。
注意:将map
所有键设置为atoms
,关键字语法非常方便:
iex> map = %{a: 1, b: 2}
%{a: 1, b: 2}
匹配
与关键字列表不同,地图非常适合模式匹配。 当将map
用于模式时,它将始终与给定值的子集匹配。
iex> %{} = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> %{:a => a} = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> a
1
iex> %{:c => c} = %{:a => 1, 2 => :b}
** (MatchError) no match of right hand side value: %{2 => :b, :a => 1}
只要提供的地图中存在键,模式就将始终匹配。 因此,为了匹配所有内容,我们使用一个空的地图。
为了使地图更进一步, 地图模块提供了强大的API来操作地图:
iex> Map.get(%{:a => 1, 2 => :b}, :a)
1
iex> Map.to_list(%{:a => 1, 2 => :b})
[{2, :b}, {:a, 1}]
嵌套数据结构
数据通常需要层次结构和结构。 药剂提供支持maps
内maps
,或keyword lists
内maps
等。 使用put_in
和update_in
宏可以很方便地进行操作,它们可以按如下方式使用:
假设我们有以下内容:
iex> users = [ john: %{name: "John", age: 27, languages: ["Erlang", "Ruby", "Elixir"]}, mary: %{name: "Mary", age: 29, languages: ["Elixir", "F#", "Clojure"]} ] [john: %{age: 27, languages: ["Erlang", "Ruby", "Elixir"], name: "John"}, mary: %{age: 29, languages: ["Elixir", "F#", "Clojure"], name: "Mary"}]
因此,现在我们在表上有一些数据可以使用,每个用户的关键字列表都有一个包含名称,年龄和其他信息的地图。 如果要访问约翰的年龄,可以执行以下操作:
iex> users[:john].age 27
碰巧我们也可以使用以下相同的语法来更新值:
iex> users = put_in users[:john].age, 31
[john: %{age: 31, languages: ["Erlang", "Ruby", "Elixir"], name: "John"},mary: %{age: 29, languages: ["Elixir", "F#", "Clojure"], name: "Mary"}]
正则表达式
Elixir使用基于PCRE的Erlang的:re
模块。 您可以在文档中找到更多信息。
为了创建在药剂正则表达式,使用Regex.compile
法或特殊速记形式~r
或~R
# A simple regular expression that matches foo anywhere in the string
~r/foo/# A regular expression with case insensitive and Unicode options
~r/foo/iu
Regex模块具有大量有用的函数,可用于验证正则表达式,对其进行编译以及正确地进行转义。 这里有些例子:
iex> Regex.compile("foo")
{:ok, ~r"foo"}iex> Regex.compile("*foo")
{:error, {'nothing to repeat', 0}}iex> Regex.escape(".")
"\\."iex> Regex.escape("\\what if")
"\\\\what\\ if"iex> Regex.replace(~r/d/, "abc", "d")
"abc"iex> Regex.replace(~r/b/, "abc", "d")
"adc"iex> Regex.replace(~r/b/, "abc", "[\\0]")
"a[b]c"iex> Regex.match?(~r/foo/, "foo")
true
您还可以在map
运行正则表达式,并使用named_captures
方法检索结果:
iex> Regex.named_captures(~r/c(?<foo>d)/, "abcd")
%{"foo" => "d"}iex> Regex.named_captures(~r/a(?<foo>b)c(?<bar>d)/, "abcd")
%{"bar" => "d", "foo" => "b"}iex> Regex.named_captures(~r/a(?<foo>b)c(?<bar>d)/, "efgh")
nil
结论
Elixir是一个完全基于宏用法的功能齐全的元编程环境。 当它与元编程功能结合使用时,它强大的lists
, maps
和anonymous functions
可以帮助您将开发人员带入新的应用程序设计和数据结构水平。
我们可以看看我们的方法中的特定解决方案,由于采用DSL (特定领域语言)和Elixir的形式为Elixir提供了强大的财富,因此在非宏语言中可能需要创建许多行或代码类来创建。 Erlang的模块。
密钥对值存储操作, list
和基本数据操作只是提供给开发人员的全部内容的一小部分。 我们将在本系列的下一部分继续介绍所有这些细节。
翻译自: https://code.tutsplus.com/tutorials/elixir-walkthrough-part-2-data-types--cms-27510
Erlang和Elixir,第2部分:数据类型相关推荐
- Erlang和Elixir简介
Elixir是一种快速,动态和可扩展的语言,已Swift被初创企业人群和已建立企业的生产应用所采用. 仅举几例,Pinterest,Brightcove,Discord和Canvas都在Elixir上 ...
- CentOS 7.7安装Erlang和Elixir
安装之前,先看一下它们的简要说明 Erlang Erlang是一种开源编程语言,用于构建对高可用性有要求的大规模可扩展的软实时系统.它通常用于电信,银行,电子商务,计算机电话和即时消息中.Erlang ...
- Erlang和Elixir,第5部分:Phoenix框架
到目前为止,我们已经看到了如何通过Elixir语言使用Erlang VM的基本数据类型和编码原理. 现在,我们将全面介绍并使用Phoenix Web Framework创建一个可运行的Web应用程序. ...
- [elixir! #0023] 引擎盖下, `IO.puts` 如何运作
`IO.puts "Hello world!" 接触elixir时, 学会的第一行代码是 IO.puts "Hello world!". 出于好奇, 我观察了一 ...
- 30 分钟学 Erlang
30 分钟学 Erlang (一) Shawn_xiaoyu https://www.jianshu.com/p/b45eb9314d1e 本文写给谁看的? 那些已经有过至少一门编程语言基础,并且需要 ...
- 《Elixir in Action》书评及作者问答录
<Elixir in Action>是由Manning所出版的一本新书,本书为读者介绍了Elixir这门语言以及Erlang虚拟机,同时也讨论了与并发编程.容错以及与高可用性相关的话题.I ...
- Elixir:可能成为下一代Web开发语言
Elixir是一种动态函数式语言,设计用于构建可扩展.可维护的应用程序.Lau Taarnskov是一名有着20多年Web软件开发经验的开发人员.他认为,Elixir将会对Web开发领域产生重大影响. ...
- 小众却顽强的编程语言 Erlang ,你了解多少?
[CSDN 编者按]面向并发的编程语言 Erlang ,在全球范围内其实属于小众语言,但却拥有着强大的并行处理能力和容错机制,并在二十余载后的如今却仍能保持生机,你不想了解一下吗? 整理 | 弯月 责 ...
- Erlang 二十年,如何在编程语言中占据一席之地?
1998 年开源发布的 Erlang 项目,在全球范围内只是个小众编程语言. 根据 TIOBE 最新发布的语言排行榜,Erlang 仅排名在第 65 位,市场份额占有小于 0.1%.但是作为一门函数编 ...
最新文章
- 网络编程应用:基于TCP协议【实现文件上传】--练习
- Linux 混合编译opencv与opencv_contrib的android版本
- linux内核锁死怎么解决_解决Linux内核中的2038年问题
- ABAP术语-Business Components
- 16.2互联网媒体信息讽刺识别
- 精彩的javascript对象和数组混合相加
- miui android mmi,小米5miui9稳定版自改官包方法
- C语言自学之路十一(详解C语言操作符一)
- Win11录屏数据保存在哪里?Win11录屏数据保存的位置
- 屏幕录像制作gif动态图
- Robotium 介绍
- 开源节流 企业部署SaaS最实用的价值
- 一套完整的投资体系:判断好生意、发现好公司、找到好价格
- 音频codec调试心得
- springboot websocket 传递 头信息 协议头 token 的前后端解决方案
- 庄家出货前兆5种情况(风险必看)【转】
- 在钉钉上怎么手写_钉钉直播上课可以写字吗_钉钉直播写字板功能介绍_玩游戏网...
- 基于WIN32 API界面编程实现的华容道小游戏
- 用计算机写作与用笔写作,电脑写作vs手写作文,技术真能提高写作成绩吗?
- 华为无线设备配置静态负载均衡
热门文章
- 我的世界(3)-纯净服务器搭建全流程
- 寒假集训D14 Demo 随机点名
- 红米airdots掉了怎么查找_红米K30系列性价比挺高,但也不要瞎买,这款才是最好的选择!...
- 莫忘输赢-优秀网站、书籍、博文
- MacBook pro m1 上玩金铲铲,通过手机ipa脱壳重新签名
- eclipse快捷键(定位函数,查找类,查找方法)
- 信安 - 收藏集 - 掘金
- Oracle视图学习DBA_HIST_ACTIVE_SESS_HISTORY
- Y轴的数据莫名其妙不从0开始显示刻度, 而直接显示给定的y的数据
- 数字次数统计器----数字出现次数统计器