- Mastering Elixir
- André Albuquerque Daniel Caixinha
- 694字
- 2021-08-05 10:42:50
Structs
Structs are an abstraction built on top of maps. We define a struct inside a module, with the defstruct construct. The struct's name is the name of the module it's being defined in (which means you can only define one struct per module). To defstruct, we pass a keyword list, which contains the key-value pairs that define the fields that struct has, along with their default values. Let's define a Folder struct:
$ cat examples/folder.ex
defmodule Folder do
defstruct name: "new folder", files_info: [], path: nil
end
We can now use it in our IEx session:
iex> %Folder{}
%Folder{files_info: [], name: "new folder", path: nil}
iex> %Folder{}.name
"new folder"
iex> %Folder{}.files_info
[]
Elixir already has a File module, which provides several functions to deal with files. One of them is the File.stat/2, which returns a %File.Stat{} struct with information about the provided path. The files_info field in our %Folder{} struct is a list, which will contain %File.Stat{} structs as elements. Let's initialize a folder with one file:
iex> folder = %Folder{files_info: [File.stat!("string_helper.ex")]}
%Folder{files_info: [%File.Stat{access: :read_write,
atime: {{2017, 12, 31}, {16, 58, 56}}, ctime: {{2017, 12, 30}, {3, 40, 29}},
gid: 100, inode: 3290229, links: 1, major_device: 65024, minor_device: 0,
mode: 33188, mtime: {{2017, 12, 30}, {3, 40, 29}}, size: 509, type: :regular,
uid: 1000}], name: "new folder", path: nil}
Note that this example assumes you have a "string_helper.ex" file in the directory where you started iex. Also note that we're using File.stat!, which works similarly to File.stat, but, instead of returning a {:ok, result} tuple, it returns the result itself.
We now have our %Folder{} struct with one file. We can now show you the syntax to update a struct, which is similar to the one used in maps (or you can use the functions from the Map module). Assuming you also have a "recursion.ex" file on your current working directory, you can use this syntax to update the struct:
iex> folder = %Folder{ folder | files_info: [File.stat!("recursion.ex") | folder.files_info]}
%Folder{files_info: [%File.Stat{access: :read_write,
atime: {{2017, 12, 30}, {20, 8, 29}}, ctime: {{2017, 12, 30}, {20, 8, 25}},
gid: 100, inode: 3278529, links: 1, major_device: 65024, minor_device: 0,
mode: 33188, mtime: {{2017, 12, 30}, {20, 8, 25}}, size: 270, type: :regular,
uid: 1000},
%File.Stat{access: :read_write, atime: {{2017, 12, 31}, {16, 58, 56}},
ctime: {{2017, 12, 30}, {3, 40, 29}}, gid: 100, inode: 3290229, links: 1,
major_device: 65024, minor_device: 0, mode: 33188,
mtime: {{2017, 12, 30}, {3, 40, 29}}, size: 509, type: :regular, uid: 1000}],
name: "new folder", path: nil}
iex> folder.files_info
[%File.Stat{access: :read_write, atime: {{2017, 12, 30}, {20, 8, 29}},
ctime: {{2017, 12, 30}, {20, 8, 25}}, gid: 100, inode: 3278529, links: 1,
major_device: 65024, minor_device: 0, mode: 33188,
mtime: {{2017, 12, 30}, {20, 8, 25}}, size: 270, type: :regular, uid: 1000},
%File.Stat{access: :read_write, atime: {{2017, 12, 31}, {16, 58, 56}},
ctime: {{2017, 12, 30}, {3, 40, 29}}, gid: 100, inode: 3290229, links: 1,
major_device: 65024, minor_device: 0, mode: 33188,
mtime: {{2017, 12, 30}, {3, 40, 29}}, size: 509, type: :regular, uid: 1000}]
As you can see, we now have two files in our %Folder{} struct.
We'll end our little tour of structs with two more bits of information. First, if you don't provide a default value when defining the fields of a struct, nil will be assumed as its default value. Second, you can enforce that certain fields are required when creating your struct. You do that with the @enforce_keys module attribute. If we wanted to make sure path was provided when creating our %Folder{} struct, we would define it as following:
$ cat examples/folder_with_enforce_keys.ex
defmodule Folder do
@enforce_keys :path
defstruct name: "new folder", files_info: [], path: nil
end
If you don't provide path when creating this struct, ArgumentError will be raised:
iex> %Folder{}
** (ArgumentError) the following keys must also be given when building struct Folder: [:path]
expanding struct: Folder.__struct__/1
iex:46: (file)
iex> %Folder{path: "/a/b/c/"}
%Folder{files_info: [], name: "new folder", path: "/a/b/c/"}
- Learning Python Web Penetration Testing
- Django+Vue.js商城項目實戰(zhàn)
- Spring 5企業(yè)級開發(fā)實戰(zhàn)
- 程序設(shè)計與實踐(VB.NET)
- Practical Internet of Things Security
- PostgreSQL技術(shù)內(nèi)幕:事務(wù)處理深度探索
- 精通軟件性能測試與LoadRunner實戰(zhàn)(第2版)
- Java程序員面試算法寶典
- 實戰(zhàn)Java高并發(fā)程序設(shè)計(第3版)
- Modular Programming in Java 9
- Unity 2017 Mobile Game Development
- OpenCV 4計算機視覺項目實戰(zhàn)(原書第2版)
- 移動互聯(lián)網(wǎng)軟件開發(fā)實驗指導(dǎo)
- 寫給大家看的Midjourney設(shè)計書
- 軟件測試分析與實踐