Elixir 基本数据类型

基本算数

与Python、Ruby等动态语言类似

iex> 1 + 2
3
iex> 5 * 5
25
iex> 10 / 2
5.0

注意10/2返回的是浮点数5.0而不是整数5。在Elixir中,/运算符总是返回一个浮点数。如果想得到一个整数形式的商或余数,可以调用div/2rem/2函数:

iex> div(5, 2)
2

iex> div(6, -4)
-1

iex> div(-99, 2)
-49

iex> rem(5, 2)
1

iex> rem(6, -4)
2

iex> div(100, 0)
** (ArithmeticError) bad argument in arithmetic expression

div/2rem/2函数的其中一个参数不为整数,或除数为0,将会引发ArithmeticError

Elixir中的函数是由函数名与参数个数区分的。div/2表示此函数接收2个参数。拥有相同的函数名但是参数个数不同则是完全不同的函数。

Elixir也支持转换二进制,八进制,十六进制的数:

iex> 0b1010
10
iex> 0o777
511
iex> 0x1F
31

浮点数要求小数点后至少有一位数,也支持e作为自然对数:

iex> 1.0
1.0
iex> 1.0e-10
1.0e-10

Elixir中的浮点数是双精度64位的。

你可以调用round/1函数来得到与某个浮点数最相近的整数,或者调用trunc/1函数来得到某个浮点数的整数部分。

iex> round(3.58)
4
iex> trunc(3.58)
3

布尔型

Elixir以truefalse作为布尔型:

iex> true
true
iex> true == false
false

Elixir提供了一系列的判定函数来检查某值的类型。例如,函数is_boolean/1可以用于检查某值是否是布尔型:

iex> is_boolean(true)
true
iex> is_boolean(1)
false

你也可以使用is_integer/1is_floot/1is_number/1来分别检查某参数是否是一个整数,浮点数或都不是。

原子

原子是一种常量,名字就是它的值,布尔值truefalse实际上就是原子

iex> :hello
:hello
iex> :hello == :world
false
iex> true == :true
true
iex> is_atom(false)
true
iex> is_boolean(:false)
true

字符串

Elixir中的字符串用双引号包围,并且以UTF-8格式编码:

iex> "hellö"
"hello"

Elixir也支持格式化字符串:

iex> "hellö #{:world}"
"hellö world"

字符串可以包含换行。可以用转义字符来显示它们:

iex> "hello
...> world"
"hello\nworld"
iex> "hello\nworld"
"hello\nworld"

可以使用IO模块中的IO.puts/1函数来打印字符串:

iex> IO.puts "hello\nworld"
hello
world
:ok

注意IO.puts/1函数在打印完之后返回了原子:ok作为结果。

Elixir中的字符串在内部以二进制来表示,并且按字节排序:

iex> is_binary("hellö")
true

我们还可以获得字符串的字节数:

iex> byte_size("hellö")
6

注意这个字符串的字节数是6,即使它只有5个字符。这是因为字符“ö”在UTF-8编码中占用了两个字节。我们可以使用String.length/1函数来获取基于字符数的字符串长度:

iex> String.length("hellö")
5

在字符串模块中包含了一系列基于Unicode标准对字符串进行处理的函数:

iex> String.upcase("hellö")
"HELLÖ"

匿名函数

函数被包含在fnend之间:

iex> add = fn a, b -> a + b end
#Function<12.71889879/2 in :erl_eval.expr/5>
iex> is_function(add)
true
iex> is_function(add, 2)
true
iex> is_function(add, 1)
false
iex> add.(1, 2)
3

在Elixir中,函数是“一等公民”,意味着它们可以像整数和字符串一样被当作参数传递给其它函数。例如,我们将变量add中的函数传递给函数is_function/1,得到返回值true。我们也可以调用is_function/2来检查函数的参数个数。

注意在调用匿名函数时变量名与括号间必须要有一个点(.)。

匿名函数是闭包,因此它们可以获取在函数定义时所包含的变量。让我们来定义一个新的匿名函数,它使用了我们之前定义的匿名函数add

iex> double = fn a -> add.(a, a) end
#Function<6.71889879/1 in :erl_eval.expr/5>
iex> double.(2)
4

记住函数中赋值的变量不会影响其外部环境:

iex> x = 42
42
iex> (fn -> x = 0 end).()
0
iex> x
42

捕获操作符&也可以被用于创建匿名函数。这种语法会在后面讨论。

列表

Elixir中使用方括号来定义列表的值。值可以是任意类型:

iex> [1, 2, true, 3]
[1, 2, true, 3]
iex> length [1, 2, 3]
3

两个列表可以相加或相减通过使用++/2--/2运算符:

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/1tl/1来得到。让我们将一个列表赋值给一个变量,然后获得它的头尾:

iex> list = [1, 2, 3]
iex> hd(list)
1
iex> tl(list)
[2, 3]

获取空列表的头尾会产生错误:

iex> hd []
** (ArgumentError) argument error

有时创建的列表会返回一个单引号包围的值。例如:

iex> [11, 12, 13]
'\v\f\r'
iex> [104, 101, 108, 108, 111]
'hello'

当Elixir发现一个可打印的ASCII数字列表,便会将其以字符列表形式打印出来。字符列表看上去和Erlang代码非常相似。当你在IEx中看见一个不确定类型的值,可以使用i/1来获得它的信息:

iex> i 'hello'
Term
  'hello'
Data type
  List
Description
  ...
Raw representation
  [104, 101, 108, 108, 111]
Reference modules
  List

记住在Elixir中单引号和双引号所代表的是不同的类型:

iex> 'hello' == "hello"
false

单引号是字符列表,双引号是字符串。

元组

Elixir用花括号来定义元组。类似列表,元组也可以包含任意值:

iex> {:ok, "hello"}
{:ok, "hello"}
iex> tuple_size {:ok, "hello"}
2

元组中的元素在内存中是连续存储的。这意味着可以很快地逐坐标访问一个元组中的元素或获取元组的大小。坐标从零开始:

iex> tuple = {"John", :man, 27}     
{"John", :man, 27}
iex(32)> elem(tuple, 1)
:man

可以使用put_elem/3将一个元素放到元组的任意位置:

iex> tuple = {:ok, "hello"}
{:ok, "hello"}
iex> put_elem(tuple, 1, "world")
{:ok, "world"}
iex> tuple
{:ok, "hello"}

注意put_elem/3返回了一个新的元组。存放在tuple变量中的原始元组没有改变,这是因为Elixir数据是不可变的。所以Elixir代码更容易推导,因为你从不需要担心是否有一段代码改变了你的数据结构。

列表还是元组?

列表和元组的区别是什么?

列表以链表的形式在内存中存储,即列表中的每个元素包含了它的值和指向下一个元素的指针,直到列表的末尾。我们把每对值和指针称为一个驿站(cons cell):

iex> list = [1 | [2 | [3 | []]]]
[1, 2, 3]

这意味着访问一个列表的长度是一个线性操作:我们需要贯穿整个列表来算出它的长度。更新一个列表只需要在它前面加上元素:

iex> [0 | list]
[0, 1, 2, 3]

而元组,是以连续的方式存储在内存中的。这意味着获得元组长度或通过坐标访问元素都很快。然而,更新或添加元素却很复杂,因为必须在内存中复制整个元组。

不同的特性决定了这些数据结构的用途。元组常用于返回函数的额外信息。例如,File.read/1是一个用于读取文件内容的函数,它返回了一个元组:

iex> File.read("path/to/existing/file")
{:ok, "... contents ..."}
iex> File.read("path/to/unknown/file")
{:error, :anoint}

如果提供给File.read/1的路径存在,那么它返回了一个元组,由原子:ok作为第一个元素,文件内容作为第二个。否则,返回的元组会包含:error和错误描述。

大多数时候,Elixir会引导你做正确的事。例如,elem/2函数可以访问元组,但是对于列表却没有定义相似的函数:

iex> tuple = {:ok, "hello"}
{:ok, "hello"}
iex> elem(tuple, 1)
"hello"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 〇、前言 本文共108张图,流量党请慎重! 历时1个半月,我把自己学习Python基础知识的框架详细梳理了一遍。 ...
    Raxxie阅读 18,892评论 17 410
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,674评论 0 38
  • 02.09 晚上和梅子老师在会所谈论明年开班的一些宣传图片和材料的制作。差不多后,我请她帮我拍照打卡下。其实早上一...
    春风拂看露华浓阅读 167评论 1 1
  • 前几天在豆瓣上看到一篇文章,是个男孩写的宿舍生活。大家经常一起做饭聚餐,有意思的是还在学校附近的河流里抓小龙虾。 ...
    流年芳华阅读 308评论 0 5
  • 江山水自流,天涯南冥鲎。昼夜放浪还修,大风卷带忧。云飞飘逸晚留,月明满眼秋,消散松絮柳。弱水三千沟,亦欲瓢灌丘。 ...
    柳欲山庄阅读 351评论 0 1