如何在不限制其维度的情况下为函数参数指定类型?
How can I specify a type for a function argument without restricting its dimensions?
在 Julia 中,我想将函数参数的类型指定为数组的数组。所以我有
function foo{T <: Any}(x::Array{Array{T}})
但是如果我在 REPL 中设置参数 x
,例如:
x = Array[[0,1],[1,2,3],[0,1,2,4]]
然后它会自动获得以下类型分配(例如),其中包括其维度:
x::Array{Array{T,N},1}
所以我得到错误
ERROR: `foo` has no method matching foo(::Array{Array{T,N},1}).
我根本不想限制数组维度,所以我认为解决方案可能类似于
function foo{T <: Any, N <: Number}(x::Array{Array{T,N},N})
但这也不起作用。
如何将参数类型指定为数组的数组?
给定一个数组 x = Array[isodd(i) ? [1i,2i] : [1.0i 2.0i] for i=1:10]
,Julia 将其类型报告为 Array{Array{T,N},1}
。这是骗人的,因为它似乎暗示存在一些 T
和一些 N
可以匹配上述类型。但事实并非如此:奇数元素的类型为 Array{Int,1}
,偶数为 Array{Float64,2}
。因此,当您尝试使用类型参数为 foo
编写方法时:
foo{T,N}(::Array{Array{T,N},1}) = T,N
x
的 T
和 N
是什么?显然,没有这样的 N — 它是 both 1 和 2!这些子数组的元素不是 Any
类型——它们是 both Int
和 Float64
。这同样适用于 Array[[0,1],[0,1,2]]
,即使在您的示例中您知道 T
和 N
是一致的,但 Julia 的类型系统不一致......并且您可能会推送不是 Int 的元素向量。
有很多方法可以解决这个问题。最好的方法是尝试确保您的数组始终具有具体(或至少统一)的元素类型,但这并不总是可能的。鉴于上面的示例 x
,您可以改写:x = Array{Int,1}[[0,1],[1,2,3],[0,1,2,4]]
.
另一种方法是更改您的函数签名:
foo{N}(x::Array{Array,N}) = 1 # Will *only* work for arrays like x above
foo{T<:Array, N}(x::Array{T,N} = 2 # Will work for all arrays of arrays
由于 invariance,第一个仅适用于您完全具有该类型的情况,而第二个将适用于所有数组的数组,包括类型不佳和具体的数组。
(编辑:作为最后的说明,N<:Number
不会匹配文字数字。它将匹配 类型 ,它们是 Number
的子类型,像 Real
或 Int
。目前没有办法表达类型参数必须是类型 Int
的 value 超出约定 N 是一个整数)。
在 Julia 中,我想将函数参数的类型指定为数组的数组。所以我有
function foo{T <: Any}(x::Array{Array{T}})
但是如果我在 REPL 中设置参数 x
,例如:
x = Array[[0,1],[1,2,3],[0,1,2,4]]
然后它会自动获得以下类型分配(例如),其中包括其维度:
x::Array{Array{T,N},1}
所以我得到错误
ERROR: `foo` has no method matching foo(::Array{Array{T,N},1}).
我根本不想限制数组维度,所以我认为解决方案可能类似于
function foo{T <: Any, N <: Number}(x::Array{Array{T,N},N})
但这也不起作用。
如何将参数类型指定为数组的数组?
给定一个数组 x = Array[isodd(i) ? [1i,2i] : [1.0i 2.0i] for i=1:10]
,Julia 将其类型报告为 Array{Array{T,N},1}
。这是骗人的,因为它似乎暗示存在一些 T
和一些 N
可以匹配上述类型。但事实并非如此:奇数元素的类型为 Array{Int,1}
,偶数为 Array{Float64,2}
。因此,当您尝试使用类型参数为 foo
编写方法时:
foo{T,N}(::Array{Array{T,N},1}) = T,N
x
的 T
和 N
是什么?显然,没有这样的 N — 它是 both 1 和 2!这些子数组的元素不是 Any
类型——它们是 both Int
和 Float64
。这同样适用于 Array[[0,1],[0,1,2]]
,即使在您的示例中您知道 T
和 N
是一致的,但 Julia 的类型系统不一致......并且您可能会推送不是 Int 的元素向量。
有很多方法可以解决这个问题。最好的方法是尝试确保您的数组始终具有具体(或至少统一)的元素类型,但这并不总是可能的。鉴于上面的示例 x
,您可以改写:x = Array{Int,1}[[0,1],[1,2,3],[0,1,2,4]]
.
另一种方法是更改您的函数签名:
foo{N}(x::Array{Array,N}) = 1 # Will *only* work for arrays like x above
foo{T<:Array, N}(x::Array{T,N} = 2 # Will work for all arrays of arrays
由于 invariance,第一个仅适用于您完全具有该类型的情况,而第二个将适用于所有数组的数组,包括类型不佳和具体的数组。
(编辑:作为最后的说明,N<:Number
不会匹配文字数字。它将匹配 类型 ,它们是 Number
的子类型,像 Real
或 Int
。目前没有办法表达类型参数必须是类型 Int
的 value 超出约定 N 是一个整数)。