仅使用Elixir或在Elixir上导入函数时除外 [英] Specify arity using only or except when importing function on Elixir

查看:108
本文介绍了仅使用Elixir或在Elixir上导入函数时除外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Elixir,并且当我使用,当从模块导入函数时除指定一个数字。为什么?

eg

  import:math,only:[sqrt :1] 

  import:math,除外:[sin:1,cos:1] 


解决方案

在整个Erlang生态系统中,函数由名字+ arity来标识。在大多数其他语言中,您可以按名称重载函数。换句话说,在Erlang世界中,foo / 1(即foo(one_arg))是一个完全不同于foo / 2的函数(如in,foo(one_arg,two_arg)),但是在Python或Rubyfoo是完整的函数标识,它可以用灵活的参数调用。


$ b

约定是为了命名函数意味着同一个事物名称相同,特别是在递归定义迭代函数的情况下:

  factorial(N) - >阶乘(1,N)。 

阶乘(A,0) - >一个;
阶乘(A,N) - >阶乘(A * N,N - 1)。

注意有两个段,这意味着这里有两个完全独立的定义。我们可以这么写:

  fac(N) - > sum(1,N)。 

sum(A,0) - >一个;
sum(A,N) - >总和(A * N,N - 1)。

但是您会注意到第二个版本在字符笔画方面的节省大大超过了卷积它的语义 - 第二个版本的内部函数名称是一个彻头彻尾的谎言!

约定是命名相关的函数同样的东西,但实际上通过arity重载函数不是允许在Erlang生态系统中。为了让这样的重载可以接受,需要在编译Erlang字节码的语言的编译器中增加重要的功能,这对于痛苦的努力毫无意义的浪费。目前的情况与我们在动态类型语言中所能达到的一样好(没有它变成一个静态类型的函数语言......这完全是另一个讨论)。

最终的结果是,你必须准确地指定你要导入的函数,无论是在Erlang还是Elixir中,这意味着通过名称+ arity来标识它。认识到通用惯例是使用相同的名称来执行相同的功能,但具有不同的参数计数(通常只是编写一系列curried定义以包含通用默认值),Elixir提供了一种快捷方式,可以按组来包含函数而不是枚举他们。



所以,当你 import:math,只有:[sqrt:1] 你只需要 math:sqrt / 1 并将模块的其余部分取出(是否存在 math:sqrt / 2 ),您将忽略它)。当你 import:math时,除了[sin:1,cos:1] ,你把所有的东西都拿来 math:sin / 1 数学:cos / 1 (是否存在数学:sin / 2 你会采取它)。名字+ arity是一个独特的身份。想象一下可用功能的一个大KV商店。键是 {module,func,arity} ,这意味着它们是系统的原子值。如果你对Erlang很熟悉,这可能会让你感到熟悉,因为你总是处理元组 {Module,Function,Args}


I'm studying Elixir and when I use only or except operators when importing functions from a module I need to specify an arity number. Why?

e.g.

import :math, only: [sqrt: 1]

or

import :math, except: [sin: 1, cos: 1]

解决方案

Across the Erlang ecosystem functions are identified by name + arity. In most other languages you can overload functions by name. In other words, in the Erlang world foo/1 (that is, foo(one_arg)) is a completely different function than foo/2 (as in, foo(one_arg, two_arg)), but in Python or Ruby "foo" is the complete function identity and it can be invoked with a flexible number of arguments.

The convention is to name functions that mean the same thing the same name, especially in the case of recursively defined iterative functions like:

factorial(N) -> factorial(1, N).

factorial(A, 0) -> A;
factorial(A, N) -> factorial(A * N, N - 1).

Notice there are two periods, meaning there are two completely independent definitions here. We could just as well write:

fac(N) -> sum(1, N).

sum(A, 0) -> A;
sum(A, N) -> sum(A * N, N - 1).

But you will notice that the second version's savings in terms of character strokes is drastically outweighed by the convolution of its semantics -- the second version's internal function name is an outright lie!

The convention is to name related functions the same thing, but in actuality overloading functions by arity is not allowed in the Erlang ecosystem. To make such overloading acceptable would require significant feature additions to the compiler of a language that compiles to Erlang's bytecode, and that would be a pointless waste of painful effort. The current situation is about as good as we can get in a dynamically typed functional language (without it becoming a statically typed functional language... and that's another discussion entirely).

The end result is that you have to specify exactly what function you want to import, whether in Erlang or Elixir, and that means identifying it by name + arity. Recognizing that the common convention is to use the same name for functions that do the same thing but have different argument counts (often simply writing a cascade of curried definitions to enclose common defaults), Elixir provides a shortcut to including functions by groups instead of enumerating them.

So when you import :math, only: [sqrt: 1] you only take math:sqrt/1 and left the rest of the module out (were there a math:sqrt/2 you would have ignored it). When you import :math, except: [sin: 1, cos: 1] you take everything but math:sin/1 and math:cos/1 (were there a math:sin/2 you would have taken it). The name + arity is a distinct identity. Imagine a big KV store of available functions. The keys are {module, func, arity}, meaning they are an atomic value to the system. If you're familiar with Erlang even a little this may strike you as familiar, because you deal with the tuple {Module, Function, Args} all the time.

这篇关于仅使用Elixir或在Elixir上导入函数时除外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆