我查看了一些Elixir项目,看到了类似的代码:
value = Dict.get(options, :key)
有没有办法缩短它并利用它
调度/协议?似乎有一些陈述
Elixir中的import
,use
,require
。
所以看起来应该可以编写短代码并让它 编译器应该使用Dict.get或String.get:
import Dict, String
# Getting :key from the Dict.
value = get options, :key
# Getting the second char from the String
char = get "some-string", 2
这种方法在Elixir中有效吗?即是否有可能写短
和紧凑的代码,而不是长的完全前缀的名称,如
A.B.C.do_something
?
答案 0 :(得分:4)
您可以使用别名明确地编写简短紧凑的代码。只要确保你不要混淆自己。查看offical documentation
iex(1)> alias Enum, as: E
nil
iex(2)> E.reduce [1,2,3,4], &(&1+&2)
10
至于你问题的第一部分。导入模块时,冲突将显示模糊错误。例如
iex(1)> import Map, only: [delete: 2]
iex(5)> delete %{a: 4,b: 5}, :a
iex(6)> import List, only: [delete: 2]
iex(8)> delete %{a: 4,b: 5}, :a
** (CompileError) iex:8: function delete/2 imported from both List and Map, call is ambiguous
(elixir) src/elixir_dispatch.erl:111: :elixir_dispatch.expand_import/6
(elixir) src/elixir_dispatch.erl:82: :elixir_dispatch.dispatch_import/5
因此,请确保仅使用only
关键字从模块导入有用的函数。另一个好的选择是利用import中的词汇范围。您可以在哪里指定要使用导入的位置,只有该部分才会生效。这是一个例子
defmodule Math do
def some_function do
import List, only: [duplicate: 2]
duplicate(:ok, 10)
end
def other_function do
duplicate(:ok, 10)#this will show error since import is only present inside some_function
end
end
或者protocol可能是你正在寻找的东西。文档将告诉你你需要知道什么,我在这里做了一个简短的总结。
defprotocol Get do
@doc "Returns the data,for given key"
def get(data,key)
end
然后,您可以根据需要的任何类型实现它
defimpl Get, for: Map do
def get(data,key), do: Map.get(data,key)
end
defimpl Get, for: Keyword do
def get(data,key), do: Keyword.get(data,key)
end
defimpl Blank, for: Any do
def blank?(data,key), do: raise(ArgumentError, message: "Give proper type for key")
end
答案 1 :(得分:2)
您还可以使用导入的组合:仅使用导入:除了获取您正在寻找的行为。查看here了解更多详情。
编辑:
另一种可能的方法发生在我身上。您还可以通过匿名函数创建一个较短的名称。像这样:
dget = &(Dict.get/2)
sget = &(String.get/2)
然后您的示例代码如下所示:
value = dget.(options, :key)
char = sget.("some-string", 2)
虽然这当然会起作用,但我认为它可能仍然不是你想要的。我将这个添加到我的答案中仅适用于可能遇到此Q& A有助于对可能的替代方案给出更完整的答案。