官术网_书友最值得收藏!

Bringing structs and protocols together

Now that we have the %Folder{} struct defined, we can define its implementation for the Size protocol.

We'll first define the implementation for the %File.Stat{} struct, as we can then use this to implement the protocol for %Folder{}. Here's the implementation for %File.Stat{}:

$ cat examples/size_implementations_file_stat_and_folder.ex
defimpl Size, for: File.Stat do
def size(file_stat), do: file_stat.size
end

# ...

With this in place, our implementation for our %Folder{} struct is as follows:

$ cat examples/size_implementations_file_stat_and_folder.ex
# ...

defimpl Size, for: Folder do
def size(folder) do
folder.files_info
|> Enum.map(&Size.size(&1))
|> Enum.sum()
end
end

To find out the size of a folder, we sum the size of each file it contains. As such, this implementation iterates through our files_info list, using the Size implementation for %File.Stat{} to get the size of each file, summing all the sizes in the end. In the following snippet, we can see this implementation being used on the folder variable we just defined:

iex> Size.size(folder)
779

With this, we can see the full power of mixing structs and protocols, which lets us have polymorphic functions based on the data type of their arguments. We now have a common interface, Size.size(data), that allows us to find out the size of pretty much anything we want, provided that we implement the Size protocol for the data type we're interested in.

主站蜘蛛池模板: 桂东县| 京山县| 宜宾市| 营口市| 新源县| 淮阳县| 无棣县| 湖州市| 荥经县| 长武县| 西乌珠穆沁旗| 富平县| 嘉禾县| 商河县| 鸡西市| 花莲县| 织金县| 津市市| 怀远县| 阿瓦提县| 定日县| 湘乡市| 浦城县| 读书| 平昌县| 娱乐| 南城县| 旬邑县| 宁乡县| 临汾市| 韶关市| 陇南市| 盐城市| 增城市| 灵川县| 吴旗县| 扎鲁特旗| 贺州市| 大竹县| 松潘县| 茶陵县|