字典
散列表和散列字典都实现了 Dict
的行为。
关键字模块也实现了,但是关键字列表允许出现重复的值,但是要用 Keyword
模块才能访问。
1 | defmodule Demo do |
1 | iex> hd = [one: 1,two: 2,three: 3] |> Enum.into HashDict.new |
其他kpi类似Dict.get(kw_list, :likes)
获取Dict.drop(hashdict, [:where, :likes])
移除Dict.put(hashdict, :also_likes, "Ruby")
增加Dict.merge(map, hashdict)
合并
等等..
散列表模式匹配和更新
散列表
格式: %{_key, _value}
模式匹配
匹配代码类似如下:
1 | iex(1)> people = [ |
更新值
散列表是不可变的,所以更新后会产生新的列表。
更新散列表语法:new_map = %{ old_map, | key => value, ...}
具体代码:
1 | iex> m = %{a: 1, b: 2, c: 3} |
使用结构体
当你想创建一个带类型的散列表,具有固定的字段集合以及与之对应的默认值的散列表,并且能像匹配内容一样进行模式匹配的时候,我们可以使用- 结构体
,defstruct
。
在模块内部使用 defstruct
宏来定义散列表的性质。
1 | defmodule Demo do |
1 | iex> jack = %Demo{name: "jack", age: 19, allow_in: true} |
另一种方式访问结构体
散列表能够通过 some_map[:name] 的方式访问,而我们前面的结构体是通过点符号。
由于散列表实现了 Access
协议(定义了使用方括号访问属性的能力),而结构体没有,所以我们可以通过添加简单的指令来使结构体拥有这项功能。
方式:@derive Access
改造下之前的代码:
1 | defmodule Demo do |
然后你就可以通过方括号访问里面的属性了。
嵌套结构体
1 | defmodule Customer do |
1 | iex> report = %BugReport{owner: %Customer{name: "Dave", company: "Pragmatic"}, details: "broken"} |
但是更新时候特别麻烦,我们可以用 Elixir
的嵌套字典访问函数。
put_in
可以设定嵌套结构里面的值。
1 | put_in(report.owner.company, "PragProg") |
update_in
可以让我们在结构体的某个值上执行一个函数。
1 | update_in(report.owner.name, &("Mr." <> &1)) |
另外还有两个嵌套函数,get_in
,get_and_update_in
,可以访问iex
的文档获得更多资料。
动态嵌套访问
get_in
, put_in
, 等函数都接收一个键列表作为单独的参数,动态获取亲淘结构体中的字段。
类似如下:
1 | IO.inspect get_in(person, [:son, :son, :name]) |
获取孙子的名字。 : )
put_in
类似
1 | IO.inspect put_in(person, [:son, :son, :name], "shadan") |
给孙子取个名字。 : )
HashSet
1 | iex> set1 = Enum.into 1..5, HashSet.new |
而已看出 Set
并为维护顺序。
忘记对象的思想
记住 Elixir
是门函数式的编程语言。
当用到 defstruct
的时候,有面向对象编程经验的人会觉得这不就是 类
的概念么?
但是,请忘记过去面向对象的思想,做一个纯粹的开发。