Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Elixir中调用apply(String.t…)_Elixir - Fatal编程技术网

在Elixir中调用apply(String.t…)

在Elixir中调用apply(String.t…),elixir,Elixir,如果模块名为字符串,如何调用模块的方法?我知道如何使用apply。如果模块的名称是字符串,如何使用它?您必须将字符串转换为atom。所有Elixir模块都位于Elixir名称空间中(基本上是为了防止名称冲突),因此表示Elixir模块的原子都以Elixir开头。: iex(1)>defm模块,do:def foo,do:IO.puts“BAR” iex(2)>name=“M” iex(3)>apply(String.to_atom(“Elixir.”名称),:foo,[]) 酒吧 您必须将字符串

如果模块名为字符串,如何调用模块的方法?我知道如何使用apply。如果模块的名称是字符串,如何使用它?

您必须将字符串转换为atom。所有Elixir模块都位于
Elixir
名称空间中(基本上是为了防止名称冲突),因此表示Elixir模块的原子都以
Elixir开头。

iex(1)>defm模块,do:def foo,do:IO.puts“BAR”
iex(2)>name=“M”
iex(3)>apply(String.to_atom(“Elixir.”名称),:foo,[])
酒吧

您必须将字符串转换为atom。所有Elixir模块都位于
Elixir
名称空间中(基本上是为了防止名称冲突),因此表示Elixir模块的原子都以
Elixir开头。

iex(1)>defm模块,do:def foo,do:IO.puts“BAR”
iex(2)>name=“M”
iex(3)>apply(String.to_atom(“Elixir.”名称),:foo,[])
酒吧

Elixir模块在使用和打印时,从名称中省略
Elixir.
开头部分。编译Elixir和Erlang模块时,它们会生成一个beam文件。为了避免同名Elixir和Erlang的名称冲突,需要使用此前缀

当您编写和读取代码时,您不必考虑这一点,因为它是自动处理的。请注意,左侧和右侧都是原子。处理特殊符号时需要引号,模块只是以大写字母开头的原子,在这种情况下,可以省略

iex(1)> :"Elixir.SomeModule" == SomeModule
true
iex(2)> :"Elixir.SomeModule" == Elixir.SomeModule
true
由于编译器会自动为您处理这些前缀,因此建议您在将字符串转换为模块名时也让编译器处理这些前缀

这可以通过使用
Module.concat/1
Module.safe\u concat/1
来完成。它们之间的区别在于,第一个使用
二进制\u to_atom/2
,第二个使用
二进制\u to_现有的\u atom/2
将字符串转换为原子。原子不是垃圾收集的,因此将随机用户输入作为
二进制\u to \u atom/2
或其等效药剂
String.to \u atom/1
的参数提供是危险的,因为这可能导致VM崩溃。在这个特定的用例中,如果您试图从一个不存在的模块调用一个函数,您将遇到错误

知道这一点后,
Module.safe\u concat/1
功能是最合适的,因为:

  • 它让编译器处理
    长生不老药。
    前缀
  • 它无法通过达到节点上允许的原子数限制而使VM崩溃
  • 如果您提供的字符串与现有模块不对应,则会生成错误
成功案例:

iex(1)> Module.safe_concat(["String"]).upcase("xyz")        
"XYZ"
当模块名称中有输入错误时引发错误:

iex(2)> Module.safe_concat(["Strign"]).upcase("xyz")
** (ArgumentError) argument error
    :erlang.binary_to_existing_atom("Elixir.Strign", :utf8)
    (elixir 1.12.0-dev) src/elixir_aliases.erl:126: :elixir_aliases.safe_concat/1

Elixir模块在使用和打印时,在其名称中省略
Elixir.
前导部分。编译Elixir和Erlang模块时,它们会生成一个beam文件。为了避免同名Elixir和Erlang的名称冲突,需要使用此前缀

当您编写和读取代码时,您不必考虑这一点,因为它是自动处理的。请注意,左侧和右侧都是原子。处理特殊符号时需要引号,模块只是以大写字母开头的原子,在这种情况下,可以省略

iex(1)> :"Elixir.SomeModule" == SomeModule
true
iex(2)> :"Elixir.SomeModule" == Elixir.SomeModule
true
由于编译器会自动为您处理这些前缀,因此建议您在将字符串转换为模块名时也让编译器处理这些前缀

这可以通过使用
Module.concat/1
Module.safe\u concat/1
来完成。它们之间的区别在于,第一个使用
二进制\u to_atom/2
,第二个使用
二进制\u to_现有的\u atom/2
将字符串转换为原子。原子不是垃圾收集的,因此将随机用户输入作为
二进制\u to \u atom/2
或其等效药剂
String.to \u atom/1
的参数提供是危险的,因为这可能导致VM崩溃。在这个特定的用例中,如果您试图从一个不存在的模块调用一个函数,您将遇到错误

知道这一点后,
Module.safe\u concat/1
功能是最合适的,因为:

  • 它让编译器处理
    长生不老药。
    前缀
  • 它无法通过达到节点上允许的原子数限制而使VM崩溃
  • 如果您提供的字符串与现有模块不对应,则会生成错误
成功案例:

iex(1)> Module.safe_concat(["String"]).upcase("xyz")        
"XYZ"
当模块名称中有输入错误时引发错误:

iex(2)> Module.safe_concat(["Strign"]).upcase("xyz")
** (ArgumentError) argument error
    :erlang.binary_to_existing_atom("Elixir.Strign", :utf8)
    (elixir 1.12.0-dev) src/elixir_aliases.erl:126: :elixir_aliases.safe_concat/1

我只是想澄清一下-我认为您不需要
字符串。为了_atom(“Elixir.”name)
,模块名已经正确地转换为这种形式了@PawełDawczak我不确定我是否明白。模块名为,但
String.to_atom(“M”)
返回
:M
,而不是
M
,它基本上由编译器处理并转换为
Elixir.M
。这里我们手头没有编译器。我的观点是,我不认为你需要这样做:
apply(String.to_atom(“Elixir.”name),:foo,[])
,因为这样做很好:
apply(M,:foo,[])
,比如:
apply(Kernel,:+,[1,2])。=>3
只是为了澄清-我不认为你需要
String.to_atom(“Elixir.”name)
,模块名称已正确转换为此表单@PawełDawczak我不确定我是否明白。模块名为,但
String.to_atom(“M”)
返回
:M
,而不是
M
,它基本上由编译器处理并转换为
Elixir.M
。这里我们手头没有编译器。我的观点是,我认为您不需要这样做:
apply(String.to_atom(“Elixir.”name),:foo,[])
,因为这样做很好:
apply(M,:foo,[])
,比如:
apply(内核,:+,[1,2])\