我是 Julia 的新手,仍然试图弄清楚一切。
我想将输入变量类型限制为可以包含 int 和 float 的数组。
我真的很感激任何帮助。
function foo(array::??)
最佳答案
正如我在评论中提到的,出于性能原因,您不想混合它们。但是,如果您的数组可以是浮点数或整数,但您不知道它会是哪一个,那么最好的方法是使其在参数类型上分派(dispatch):
function foo{T<:Number,N}(array::Array{T,N})
这将使它为每种数字类型的数组编译一个单独的函数(仅在需要时),并且由于编译器会知道该类型,因此无论您是否给它foo([0.1,0.3,0.4])
,它都会运行该函数的优化版本。 , foo([1 2 3])
, foo([1//2 3//4])
, ETC。更新 Julia 0.6+ 中的语法
function foo(array::Array{T,N}) where {T<:Number,N}
为了更通用,您可以使用
Array{Union{Int64,Float64},N}
作为一种类型。这将允许浮点数和整数,您可以使用它的构造函数arr = Array{Union{Int64,Float64},2}(4,4) # The 2 is the dimension, (4,4) is the size
你也可以允许调度像这样的奇怪的事情function foo{T,N}(array::Array{T,N})
即只需删除对 T
的限制.但是,由于编译器无法提前知道数组的任何元素是 Int 还是 Float,因此无法很好地对其进行优化。所以一般来说你不应该这样做......但是,让我解释一种方法,您可以使用它并且仍然可以获得性能不错的东西。它也可以通过多次调度工作。本质上,如果你用一个严格类型分派(dispatch)的函数调用来封装你的内部循环,那么在进行所有硬计算时,它可以准确地知道它是什么类型并优化代码。这最好用一个例子来解释。假设我们想做:
function foo{T,N}(array::Array{T,N})
for i in eachindex(array)
val = array[i]
# do algorithm X on val
end
end
您可以使用 @code_warntype
查看那val
不会编译为 Int64 或 Float64,因为直到运行时它才会知道每个 i
的类型是什么.如果您查看 @code_llvm
(或 @code_native
对于程序集)您会看到生成了一个非常长的代码来处理这个问题。我们可以做的是定义function inner_foo{T<:Number}(val::T)
# Do algorithm X on val
end
然后将 foo 定义为function foo2{T,N}(array::Array{T,N})
for i in eachindex(array)
inner_foo(array[i])
end
end
虽然这对您来说看起来相同,但它与编译器有很大不同。请注意 inner_foo(array[i])
为它看到的任何数字类型调度一个特殊编译的函数,因此在 foo2 算法中 X 被有效计算,唯一非有效的部分是 inner_foo 上方的包装(所以如果你所有的时间都花在 inner_foo 上,你将基本上得到最大表现)。这就是为什么 Julia 是围绕多分派(dispatch)构建的:它的设计允许您尽可能将事物推送到优化的函数中。 Julia 因此而快。用它。
关于julia - 如何声明可以具有 int 和 floats 的数组类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39380285/