gpt4 book ai didi

julia - 如何为自定义数组类型重载 Base.show?

转载 作者:行者123 更新时间:2023-12-01 01:40:08 30 4
gpt4 key购买 nike

假设我使用自己的自定义矢量类型制作自己的自定义矢量类型 show方法:

struct MyVector{T} <: AbstractVector{T}
v::Vector{T}
end

function Base.show(io::IO, v::MyVector{T}) where {T}
println(io, "My custom vector with eltype $T with elements")
for i in eachindex(v)
println(io, " ", v.v[i])
end
end

如果我尝试在 REPL 中创建这些对象之一,我会收到与我从未打算调用的函数相关的意外错误:
julia> MyVector([1, 2, 3])
Error showing value of type MyVector{Int64}:
ERROR: MethodError: no method matching size(::MyVector{Int64})
Closest candidates are:
size(::AbstractArray{T,N}, ::Any) where {T, N} at abstractarray.jl:38
size(::BitArray{1}) at bitarray.jl:77
size(::BitArray{1}, ::Integer) at bitarray.jl:81
...
Stacktrace:
[1] axes at ./abstractarray.jl:75 [inlined]
[2] summary(::IOContext{REPL.Terminals.TTYTerminal}, ::MyVector{Int64}) at ./show.jl:1877
[3] show(::IOContext{REPL.Terminals.TTYTerminal}, ::MIME{Symbol("text/plain")}, ::MyVector{Int64}) at ./arrayshow.jl:316
[4] display(::REPL.REPLDisplay, ::MIME{Symbol("text/plain")}, ::Any) at /Users/mason/julia/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:132
[5] display(::REPL.REPLDisplay, ::Any) at /Users/mason/julia/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:136
[6] display(::Any) at ./multimedia.jl:323
...

好的,无论如何我都会实现 Base.size所以它会让我一个人呆着:
julia> Base.size(v::MyVector) = size(v.v)

julia> MyVector([1, 2, 3])
3-element MyVector{Int64}:
Error showing value of type MyVector{Int64}:
ERROR: getindex not defined for MyVector{Int64}
Stacktrace:
[1] error(::String, ::Type) at ./error.jl:42
[2] error_if_canonical_getindex(::IndexCartesian, ::MyVector{Int64}, ::Int64) at ./abstractarray.jl:991
[3] _getindex at ./abstractarray.jl:980 [inlined]
[4] getindex at ./abstractarray.jl:981 [inlined]
[5] isassigned(::MyVector{Int64}, ::Int64, ::Int64) at ./abstractarray.jl:405
[6] alignment(::IOContext{REPL.Terminals.TTYTerminal}, ::MyVector{Int64}, ::UnitRange{Int64}, ::UnitRange{Int64}, ::Int64, ::Int64, ::Int64) at ./arrayshow.jl:67
[7] print_matrix(::IOContext{REPL.Terminals.TTYTerminal}, ::MyVector{Int64}, ::String, ::String, ::String, ::String, ::String, ::String, ::Int64, ::Int64) at ./arrayshow.jl:186
[8] print_matrix at ./arrayshow.jl:159 [inlined]
[9] print_array at ./arrayshow.jl:308 [inlined]
[10] show(::IOContext{REPL.Terminals.TTYTerminal}, ::MIME{Symbol("text/plain")}, ::MyVector{Int64}) at ./arrayshow.jl:345
[11] display(::REPL.REPLDisplay, ::MIME{Symbol("text/plain")}, ::Any) at /Users/mason/julia/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:132
[12] display(::REPL.REPLDisplay, ::Any) at /Users/mason/julia/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:136
[13] display(::Any) at ./multimedia.jl:323
...

嗯,现在要 getindex
julia> Base.getindex(v::MyVector, args...) = getindex(v.v, args...)

julia> MyVector([1, 2, 3])
3-element MyVector{Int64}:
1
2
3

什么?那不是我告诉它要做的打印格式!这里发生了什么?

最佳答案

问题是在 julia 中,Base 定义了一个方法 Base.show(io::IO ::MIME"text/plain", X::AbstractArray)这实际上比 Base.show(io::IO, v::MyVector) 更具体用于 display . This section of the julia manual describes the sort of custom printing that AbstractArray uses .所以如果我们想使用我们的自定义 show方法,我们需要做

julia> function Base.show(io::IO, ::MIME"text/plain", v::MyVector{T}) where {T}
println(io, "My custom vector with eltype $T and elements")
for i in eachindex(v)
println(io, " ", v.v[i])
end
end

julia> MyVector([1, 2, 3])
My custom vector with eltype Int64 and elements
1
2
3

另见: https://discourse.julialang.org/t/extending-base-show-for-array-of-types/31289

关于julia - 如何为自定义数组类型重载 Base.show?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58962304/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com