自动创建多个方法

Geo*_*ery 4 julia

我可以定义一个function处理Integers 的:

function twice(a::Int64) a + a end
Run Code Online (Sandbox Code Playgroud)

此函数无法处理Floats。如果我想要,我需要定义另一种方法:

function twice(a::Float64) a + a end
Run Code Online (Sandbox Code Playgroud)

但是等等,这看起来完全一样,除了类型定义。所以,当我晚上做梦时,有可能用一个...宏来创建这样的方法定义(除了类型/类型组合之外,一切都相同)?就像是

@create_all_methods ("twice(a::$type ) a + a end", ["Int64", "Float64"])
Run Code Online (Sandbox Code Playgroud)
  1. 这是可能的,如果是,如何?

  2. 这个问题可能根本没有意义,因为function twice(a) a + a end无论如何都不会实现完全相同的事情吗?

提前感谢您的帮助。

小智 7

有多种方法可以实现这一目标。最简单的方法是省略aT的类型,然后你的方法看起来像:

function twice(a) a + a end
Run Code Online (Sandbox Code Playgroud)

这相当于

function twice(a::Any) a + a end
Run Code Online (Sandbox Code Playgroud)

但也许您不想为所有类型定义它,或者您已经有另一个定义twice(a::Any),因此您可以将您的定义限制为Int64and的公共超类型Float64。这个常见的超类型可以找到typejoin(Float64, Int64)并产生结果Real,所以你的定义现在是

function twice(a::Real) a + a end
Run Code Online (Sandbox Code Playgroud)

这也为Real诸如 的其他子类型创建了一个方法a::Int32,因此如果您真的只想要该方法Int64Float64您可以创建一个联合类型。然后该方法看起来像

    function twice(a::Union{Int64, Float64}) a + a end
Run Code Online (Sandbox Code Playgroud)

最后,确实可以通过宏实现您想要实现的目标。在这种情况下没有意义,但函数eval或宏@eval通常用于更复杂的情况。你的代码可能看起来像

for T in (Int64, Float64)
    @eval function twice(a::$T) a + a end
end
Run Code Online (Sandbox Code Playgroud)

如果您刚开始学习 Julia,我不建议您使用eval,因为使用eval.


DNF*_*DNF 6

为两种或多种输入类型创建方法的一种直接方法是使用Union

twice(a::Union{T1, T2, T3}) = a + a
Run Code Online (Sandbox Code Playgroud)

其中T1, T2, T3, 等。是具体类型,例如Intor Float64

更常见的是,您会为某些抽象超类型定义它,例如

twice(a::Number) = a + a
Run Code Online (Sandbox Code Playgroud)

但大多数时候,你应该从定义一个泛型函数开始

twice(a) = a + a
Run Code Online (Sandbox Code Playgroud)

然后在您发现有必要时添加类型。大多数时候不是。