是否要为每一个需要查看的自定义类型都创建show方法才能被打印查看?

最近在看一些包学习julia

struct Combination{T} <: AbstractMatrix{T}
    A::Tuple
    cumlength::Vector{Int}
end

function Combination(A::Union{AbstractVector{T}, AbstractMatrix{T}}...) where {T}
    Combination{T}(A, cumsum([size(x, 2) for x in A]))
end

Base.size(c::Combination) = (size(c.A[1], 1), c.cumlength[end])
Base.size(c::Combination, i::Integer) = size(c)[i]

function Base.view(c::Combination, ::Colon, j)
    index = searchsortedfirst(c.cumlength, j)
    newj = index == 1 ? j : j - c.cumlength[index-1]
    view(c.A[index], :, newj)
end

# new cell
Combination([1,2,3], [4,5,6])
# 以上为复现需要的代码
# 该代码在notebook中即会出现CanonicalIndexError: getindex not defined for Combination{Int64}


# 以下为原始代码
# 上面的示例中我用`[1,2,3], [4,5,6]`简化了了y, Xexo,他们本质是两个向量。
iterations = Int[]
convergeds = Bool[]
if false
    Xall = Combination(y, Xexo, Xendo, Z)
else
    # 因为没有iv,所以运行这个
    Xall = Combination(y, Xexo)
    println(typeof(Xall))
    println("Xall")
    println(Xall)
end

以上的代码可以成功运行
但是我发现println("Xall")可以成功打印,而运行到println(Xall)却报如下错误:

`CanonicalIndexError: getindex not defined for Combination{Float64}

一开始我觉得很奇怪,Xall不是算出来了吗?为啥不能打印呢?
再测试了下发现在jupyter notebook中

Xall = Combination(y, Xexo)

也会报如上的错误,我还以为是Xall没计算成功。

Xall = Combination(y, Xexo);

这样就可以,所以我猜测是这个Xall没有show对应的函数之类的。
那么我的疑问是:

  • 1 我的猜想是否正确,如果正确,遇到这种情况,算不算julia的缺陷?因为我一开始真的猜不到报错的原因是这样
  • 2 julia这样的设计,岂不是要单独为每一个新类型设计show方法?否则就不能查看?那会不会给调试和开发代理很大的困难,工作量也大了很多?
  • 3 那么,如何知道当前的对象,到底能用哪些方法呢?

请尽量贴出能复现的完整精简代码。

抱歉,因为这个代码在包内部比较深,一开始我没能成功复现,现在已经更新了

看了更新内容后,大概明白意思了。

建议(EDIT):

  1. 表达可以简化,比如去掉 if 判断和无关变量等
# 正常调用
Xcall = Combination([1,2,3], [4,5,6]); # 抑制打印
println(typeof(Xall))
# 报错情形
println(Xall)
  1. 不需要翻源码,错误怎么来怎么写,比如 using 了哪个包。多余信息反而容易带来 X-Y 问题。 所以这是拆解某个包遇到的错误,抱歉理解错了。

  2. 如楼下说的,问题在继承了矩阵类型。因为声明了矩阵,所以应该支持矩阵相关的方法。这点设计很合理。

假设要求 AbstractMatrix 均支持 getindex,那么下边函数能通用于 AbstractMatrix 类型数据。

getfirst(mat::AbstractMatrix) = getindex(mat, 1)

类似复现

struct Foo{T} <: AbstractMatrix{T}
    a::Vector{Int}
end

Foo{Int}([1,2]); # 正常
Foo{Int}([1,2]) # 报错

根据你的建议,再次做了下编辑和补充。我始终想表达的是错误源来自于Combination(y, Xexo)没有打印函数,所以println(Xall)println(Combination([1,2,3], [4,5,6]))都会报同样的错误的。

这一点我get不到,也是我提问的难题所在,因为这些函数都是我自己一点点从包里拼出来的,不是单独using 一下包就有的,可能确实是我的能力不足。

可能因为你继承了AbstractMatrix所以要定义相关的函数吧,如果不继承应该随意

1 个赞