Elixir笔记(2)

集合: 列表(list)、元组(tuple)、关键字列表(keyword list)、映射(map)

列表

  • 列表是值的简单集合,可以包含不同的数据类型,而且也可能包含相同的值。
  • Elixir 内部用链表实现列表,获取列表长度是 O(n) 的操作。这也代表着,在列表的头部插入比在尾部插入要快。
  • 列表拼接使用 ++/2 操作符。
    • ++/2 格式的说明:在 Elixir 中(以及 Elixir 的基础语言 Erlang),函数和操作符的名字由两部分组成:名字(比如这里的 ++)和元数(arity)。元数是 Elixir 和 Erlang 代码非常核心的部分,它代表了给定函数接受的参数个数(比如这里的 2),元数和名字之间通过斜线分割。
  • 列表减法使用–/2 操作符
    • 减去不存在的值也是安全的
    • 如果列表中有重复的值,对于右边列表中的出现的每一个值,只会从左边列表(被减列表)中移除一个与之相等的值,即第一个出现的值
    • 这里比较是否相同使用的是严格比较(strict comparison)
  • 列表头/尾(head / tail):列表的头部是列表的第一个元素;尾部是除去第一个元素剩下的列表。
    • Elixir 提供了两个函数 hd 和 tl 来获取这两个部分
  • 可以使用模式匹配(pattern matching) 和 | 操作符来把一个列表分成头尾两部分
    • | 被称为管道操作符(Cons cell operator)
  • 变量名用小写字母开头
iex(10)> aList=[3.14,:pie,"Apple"]
[3.14, :pie, "Apple"]
iex(11)> ["Π"|aList]
["Π", 3.14, :pie, "Apple"]
iex(12)> aList
[3.14, :pie, "Apple"]
iex(13)> aList ++ [1,2,3]
[3.14, :pie, "Apple", 1, 2, 3]
iex(14)> aList=[1,2,3,3,4,5,5.0]
[1, 2, 3, 3, 4, 5, 5.0]
iex(15)> aList--[1,2,3,4,5]
[3, 5.0]
iex(16)> hd aList
1
iex(17)> tl aList
[2, 3, 3, 4, 5, 5.0]
iex(17)> tl aList
[2, 3, 3, 4, 5, 5.0]
iex(18)> [H|L]=[1,2,3,4,5]
** (MatchError) no match of right hand side value:

    [1, 2, 3, 4, 5]

    (stdlib 8.0.3) erl_eval.erl:796: :erl_eval.expr/6
    iex:18: (file)
iex(18)> [h|l]=[1,2,3,4,5]
[1, 2, 3, 4, 5]
iex(19)> [H|L]=[1,2,3,4,5]
** (MatchError) no match of right hand side value:

    [1, 2, 3, 4, 5]

    (stdlib 8.0.3) erl_eval.erl:796: :erl_eval.expr/6
    iex:19: (file)
iex(19)> h
1
iex(20)> l
[2, 3, 4, 5]

元组

元组在内存中的真实结构是数组指针。元组在内存中是一块连续的存储空间,但在这个连续空间里,存放的并不是具体的字符串、大列表或复杂的结构体,而是项的引用(Term References / 指针)。在 64 位系统上:每个指针的大小固定是 8 字节。在 32 位系统上:每个指针的大小固定是 4 字节

定义元组要用花括号。

元组一个很常见的用法是作为函数的返回值,来返回额外的信息。

关键字列表(Keyword list)

  • 关键字列表在底层就是一个普通的列表(List),只是这个列表里面的每一个元素都是一个二元元组。
  • 在 Elixir 中写下一段漂亮的关键字列表时,编译器在底层会自动把它转换成二元元组的列表
  • 允许重复的键
  • 保证元素的顺序:在列表里怎么排,在内存里就怎么放,顺序绝对不会乱。
  • 第 1 个元素:必须是 Atom(原子),充当键(Key)
  • 开发者常用的简写是语法糖:list = [a: 1, b: 2],冒号后必须加空格
iex(21)>keysList =[a: 1,a: 2,b: 3,c: 4]
[a: 1, a: 2, b: 3, c: 4]

iex(22)> is_tuple(hd  keysList)
true

关键字列表非常重要,它有以下的特性:

  • 键(key)都是原子(atom)
  • 键(key)是有序的(定义后,顺序不会改变)
  • 键(key)不必是唯一的

因为这些原因,关键字列表最常见的用法是作为参数传递给函数。

映射(Map)

Elixir 的映射(maps)是键值对结构的第一选择,使用 %{} 来定义映射

  • 和关键字列表(keywords)不同,映射允许任意类型的数据作为键,而且数据并不严格排序。
  • 变量也可以作为映射的键(key)
  • 如果重复的键添加到映射中,后面的值会覆盖之前的值
  • 在 Elixir 中,=> 被称为哈希箭头(Hash Rocket)运算符,是 Map(映射)中用来连接键(Key)和值(Value)的通用通用符号
    • 当Map 里面所有的键全都是原子时,Elixir 允许使用类似关键字列表的简写,把冒号挪到后面并省去 =>。
  • 映射供了自己更新和获取原子键(key)的语法
    • 更新语法只在更新一个已经存在于映射的键才有效!如果键不存在,则会抛出 KeyError 错误
    • 要创建一个新的键值对,则应当使用 Map.put/3,即使用Map.put函数,提供三个参数
iex(23)> m1=%{:width=>400,:height=>500}
%{width: 400, height: 500}
m2=%{width: 400,height: 500}
%{width: 400, height: 500}
iex(25)> m1===m2
true

iex(26)> %{m1 | width: 600}
%{width: 600, height: 500}
iex(27)> m1
%{width: 400, height: 500}
iex(28)> m1=%{m1 | width: 600}
%{width: 600, height: 500}
iex(29)> m1
%{width: 600, height: 500}

iex(30)> Map.put(m1,:weight,1000)
%{width: 600, height: 500, weight: 1000}
iex(31)> m1
%{width: 600, height: 500}
iex(32)> m1=Map.put(m1,:weight,1000)
%{width: 600, height: 500, weight: 1000}
iex(33)> m1
%{width: 600, height: 500, weight: 1000}

正文完
 0
评论(没有评论)