5

In Julia, I want to specify the type of a function argument as an array of arrays. So I have

function foo{T <: Any}(x::Array{Array{T}})

but if I set the argument x in the REPL, for example:

x = Array[[0,1],[1,2,3],[0,1,2,4]]

then it automatically gets the following type assignment (for example), which includes its dimensions:

x::Array{Array{T,N},1}

so that I get the error

ERROR: `foo` has no method matching foo(::Array{Array{T,N},1}).

I don't want to restrict the array dimensions at all, so was thinking that the solution maybe something along the lines of

function foo{T <: Any, N <: Number}(x::Array{Array{T,N},N})

but this doesn't work either.

How can I specify the argument type to be an array of arrays?

4

1 回答 1

7

给定一个数组数组x = Array[isodd(i) ? [1i,2i] : [1.0i 2.0i] for i=1:10],Julia 将其类型报告为Array{Array{T,N},1}。这是欺骗性的,因为它似乎暗示存在一些TN上述类型匹配的一些。但事实并非如此:奇数元素是 type Array{Int,1},偶数元素是Array{Float64,2}。因此,当您尝试foo使用类型参数编写方法时:

foo{T,N}(::Array{Array{T,N},1}) = T,N

是什么TN为了x什么?显然,没有这样的 N——它既是1又是 2!而且这些子数组的元素不是类型Any——它们都是 Intand 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

第一个仅适用于由于不变性而恰好具有该类型的情况,而第二个将适用于所有 Arrays of Arrays,无论是类型不佳的还是具体的。

(编辑:最后一点,N<:Number不会匹配文字数字。它将匹配属于, like或的子类型的类型目前没有办法表示类型参数必须是超出约定的类型N 是一个整数)。NumberRealIntInt

于 2015-01-21T18:54:21.617 回答