这段代码的错误在哪里?

struct sparseHermitian{TI<:Integer,TM<:Number}

    # NOTE NOTE NOTE: diagonal elements here should have been divided by 2
    #                 and only the upper triangle of the off diagonal
    #                 elements should be given

    # number of rows in the matrix
    nRows::Int64
    # number of columns in the matrix
    nCols::Int64
    # row numbers of the first non-zero value in each column
    colPntrs::Vector{Int64}
    # row indices of non-zero elements
    rowIndcs::Vector{TI}
    # non-zero matrix element values
    nzVals::Vector{TM}

    # NOTE: optional, use for matrices with few unique matrix element values
    #       to save memory
    # non-zero matrix element pointers
    nzPntrs::Vector{TI}
    # is this a sparse pointer matrix? i.e. did you give nzPntrs?
    sparsePntrs::Bool

    # constructors

    # not a sparse matrix of pointers to matrix elements
    sparseHermitian{TI,TM}(nRows::Int64, nCols::Int64, colPntrs::Vector{Int64}, rowIndcs::Vector{TI}, nzVals::Vector{TM}) = new(nRows::Int64, nCols::Int64, colPntrs::Vector{Int64}, rowIndcs::Vector{TI}, nzVals::Vector{TM},Vector{TI}(),false)

    # a sparse matrix of pointers to matrix elements
    sparseHermitian{TI,TM}(nRows::Int64, nCols::Int64, colPntrs::Vector{Int64}, rowIndcs::Vector{TI}, nzVals::Vector{TM}, nzPntrs::Vector{TI}) = new(nRows::Int64, nCols::Int64, colPntrs::Vector{Int64}, rowIndcs::Vector{TI}, nzVals::Vector{TM}, nzPntrs::Vector{TI}, true)

end

返回的错误信息是, LoadError: UndefVarError: TI not defined

很奇怪,TI本来就不需要被定义吧

可以写一下最小复现例子,比如

struct Example{T}
    value::T

    Example{T}(value::T) = new{T}(value)
end

第二处函数的参数化 T 相当于局部变量,避免歧义换成 K 就能看出问题:

语法 value::T 的 T 为参数,要带上 where T,否则 T 应该是具体的变量,比如 Int64 之类,因此报错 UndefVarError。

纠正例子

struct Example{T}
    value::T

    Example{K}(value::K) where K = new{K}(value)
end

p.s. 题外话,题主如果是自己写代码,可以考虑增加可读性,避免一行写太长,比如:

function sparseHermitian{TI, TM}(
    nRows::Int64,
    nCols::Int64,
    colPntrs::Vector{Int64},
    rowIndcs::Vector{TI},
    nzVals::Vector{TM})
    return new( nRows, nCols, colPntrs, rowIndcs, nzVals, Vector{TI}(), false)
end

懒得手写可以直接用 JuliaFormatter

using JuliaFormatter
formatted_code = format_text("""
function sparseHermitian{TI, TM}(nRows::Int64, nCols::Int64, colPntrs::Vector{Int64}, rowIndcs::Vector{TI}, nzVals::Vector{TM})
return new(nRows, nCols, colPntrs, rowIndcs, nzVals, Vector{TI}(), false)
end
""")
println(formatted_code)
2 个赞

贴一个关于参数化类型的笔记:

1 个赞

还是不太明白。

原来的代码究竟该怎么改呢?原来的代码好像是0.7以前的julia写的,跟最新的julia不兼容。

错误逻辑:Example{T}(value::T) = new{T}(value)
正确写法:Example{T}(value::T) where T = new{T}(value)


加上后:

struct SparseHermitian{TI<:Integer,TM<:Number}
    # NOTE: diagonal elements should have been divided by 2
    # and only the upper triangle of the off-diagonal elements should be given

    nRows::Int64     # number of rows in the matrix
    nCols::Int64     # number of columns in the matrix
    colPntrs::Vector{Int64}  # row numbers of the first non-zero value in each column
    rowIndcs::Vector{TI}     # row indices of non-zero elements
    nzVals::Vector{TM}       # non-zero matrix element values

    nzPntrs::Vector{TI}      # non-zero matrix element pointers, optional for memory saving
    sparsePntrs::Bool        # is this a sparse pointer matrix?

    # constructors
    # not a sparse matrix of pointers to matrix elements
    SparseHermitian{TI,TM}(
        nRows::Int64,
        nCols::Int64,
        colPntrs::Vector{Int64},
        rowIndcs::Vector{TI},
        nzVals::Vector{TM},
    ) where {TI,TM} = new(
        nRows, nCols, colPntrs, rowIndcs, nzVals, Vector{TI}(), false )

    # a sparse matrix of pointers to matrix elements
    SparseHermitian{TI,TM}(
        nRows::Int64,
        nCols::Int64,
        colPntrs::Vector{Int64},
        rowIndcs::Vector{TI},
        nzVals::Vector{TM},
        nzPntrs::Vector{TI} ) where {TI,TM} = new{TI,TM}( 
        nRows, nCols, colPntrs, rowIndcs, nzVals, nzPntrs, true )
end
1 个赞