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

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.

主站蜘蛛池模板: 绥化市| 建湖县| 广平县| 彭水| 正蓝旗| 阳山县| 静宁县| 卓资县| 定南县| 古交市| 天台县| 伊宁市| 油尖旺区| 饶河县| 柳州市| 务川| 金塔县| 望谟县| 云南省| 五寨县| 阿拉善左旗| 无棣县| 彭山县| 监利县| 土默特右旗| 偃师市| 阜平县| 从江县| 康定县| 射阳县| 邛崃市| 宁都县| 临潭县| 化州市| 新安县| 洛南县| 焦作市| 德格县| 隆尧县| 大新县| 梅河口市|