我可以定义一个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)
这是可能的,如果是,如何?
这个问题可能根本没有意义,因为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,因此如果您真的只想要该方法Int64,Float64您可以创建一个联合类型。然后该方法看起来像
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.
为两种或多种输入类型创建方法的一种直接方法是使用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)
然后在您发现有必要时添加类型。大多数时候不是。