Julia:制作自定义类型的空/初始化多维数组

A.Y*_*iha 5 initialization multidimensional-array composite-types julia type-constructor

我正在制作一种我自己的类型,KeyVal定义如下:

type KeyVal
    first::Int
    second::Float64
end
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建一个空/或初始化为零的矩阵,其元素的类型为KeyVal。通常与我做的其他类型

myMat = zeros(KeyVal, (10,3))
Run Code Online (Sandbox Code Playgroud)

但这行不通,因为没有zeros为这种复合类型定义。所以我尝试通过以下方式定义我自己的 zeros 函数:

import Base.zeros

function zeros(KeyVal,dims)
    if length(dims) > 1
        n=dims[1]
        m=dims[2]
        temp = repeat([KeyVal(0,0.0)], outer=m*n)
        temp = reshape(temp, (n,m))
        return temp
    elseif length(dims) == 1
        n=dims[1]
        temp= repeat([KeyVal(0,0.0)], outer=n)
        temp = reshape(temp, (n))
        return temp
    end
end
Run Code Online (Sandbox Code Playgroud)

这将添加到其他先前定义的方法列表中zeros。但是使用它会产生错误:

myMat = zeros(KeyVal, (N,M))

MethodError: no method matching zero(::Type{KeyVal})
Closest candidates are:
    .....
Run Code Online (Sandbox Code Playgroud)

我想知道我是否可以以某种方式解决这个问题,或者是否可以在类型构造函数中发出信号,以便任何涉及该类型的数据结构KeyVal都在 (first = 0, second = 0.0) 处初始化。

以前我尝试将矩阵定义为:

myMat2 = Array{KeyVal,(N,M)}
Run Code Online (Sandbox Code Playgroud)

这将创建矩阵,除了它的所有元素都是#undef,在这种情况下,我无法访问 的任何元素myMat2

myMat2[1,1]
UndefRefError: access to undefined reference
Run Code Online (Sandbox Code Playgroud)

tim*_*tim 4

T您可以创建任何类型和维度的未初始化数组N您可以使用以下

\n\n
Array{T, N}(undef, dims...)\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于一维和二维数组的特殊情况,您可以使用别名VectorMatrix,例如,

\n\n
julia> m = Matrix{KeyVal}(undef, 2,2)\n2\xc3\x972 Array{KeyVal,2}:\n #undef  #undef\n #undef  #undef\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后您可以照常设置元素,例如,

\n\n
m[1,2] = KeyVal(1,2)\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您的类型实现一个有意义zero,您可以定义

\n\n
Base.zero(::Type{KeyVal}) = KeyVal(0,0)\n
Run Code Online (Sandbox Code Playgroud)\n\n

zeros正常工作

\n\n
julia> zeros(KeyVal, (2,2))\n2\xc3\x972 Array{KeyVal,2}:\n KeyVal(0,0.0)  KeyVal(0,0.0)\n KeyVal(0,0.0)  KeyVal(0,0.0)\n
Run Code Online (Sandbox Code Playgroud)\n\n

警告:

\n\n

zeros使用fill!它用同一实例的副本填充数组。相反,请使用下面的理解式或不包含引用的不可变类型(isbits为 true)。后一种方法可能也更快,因为数组可以存储为一个连续的内存块。在这种情况下,您也可以fill(KeyVal(0,0), dims..)直接使用而不是定义zero. 在 0.6 上,newstruct关键字默认创建不可变类型。

\n\n

编辑:

\n\n

另一种可能性是使用理解

\n\n
julia> m = [KeyVal() for i=1:3, j=1:2]\n3\xc3\x972 Array{KeyVal,2}:\n KeyVal(0,0.0)  KeyVal(0,0.0)\n KeyVal(0,0.0)  KeyVal(0,0.0)\n KeyVal(0,0.0)  KeyVal(0,0.0)\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了方便起见,我之前定义了外部构造函数

\n\n
KeyVal() = KeyVal(0,0)\n
Run Code Online (Sandbox Code Playgroud)\n