请问类似Base. show这类函数是普通函数还是构造函数?这类函数是怎么工作的?
比如你定义一个复合类型:struct A{T}
a::T
b::T
end
Base. show(io::IO, z::A) =println(io, z.a,“<>”,z.b)
A(1,2)
1<>2
就是说你在对A实例化的时候,Base. show函数作用到了A上?关键是Base. show 函数看起来像一个普通函数,可是并没有显式调用。它是怎么作用到A上的?
类似的函数如index
请问类似Base. show这类函数是普通函数还是构造函数?这类函数是怎么工作的?
比如你定义一个复合类型:struct A{T}
a::T
b::T
end
Base. show(io::IO, z::A) =println(io, z.a,“<>”,z.b)
A(1,2)
1<>2
就是说你在对A实例化的时候,Base. show函数作用到了A上?关键是Base. show 函数看起来像一个普通函数,可是并没有显式调用。它是怎么作用到A上的?
类似的函数如index
在REPL里执行,默认会自动显式调show打印结果,后面加;就不打印了。
我想知道具体是怎么样的一个执行过程。
有没有一个函数可以看见具体的执行路线?
类似的
doc 里面的一个类似例子。
struct A <: AbstractArray{Int,1}
a::Int
end
Base. size(s::A) = (s.a,)
Base. getindex(T::A, i::Int) = i*i
A(4)
4_element A:
2
4
6
8
实例化A时,julia是怎么调用的size 和getindex?
好难理解,没有显式调用函数,却调用了,内部是怎么操作的?
Base. show
是 REPL 执行语句时默认调用的,具体的执行位置见代码,
想看调用栈可以这样,调用函数时在合适的地方调用 stacktrace()
显示调用栈。
julia> struct A{T}
a::T
b::T
end
julia> Base. show(io::IO, z::A) = begin println(io, z.a,"<>",z.b); stacktrace() |> display end
julia> A(1,1)
1<>1
21-element Array{Base.StackTraces.StackFrame,1}:
show at REPL[15]:1 [inlined]
show(::IOContext{REPL.Terminals.TTYTerminal}, ::MIME{Symbol("text/plain")}, ::A{Int64}) at sysimg.jl:194
display(::REPL.REPLDisplay, ::MIME{Symbol("text/plain")}, ::Any) at REPL.jl:131
display(::REPL.REPLDisplay, ::Any) at REPL.jl:135
display(::Any) at multimedia.jl:287
#invokelatest#1 at essentials.jl:697 [inlined]
invokelatest at essentials.jl:696 [inlined]
print_response(::IO, ::Any, ::Any, ::Bool, ::Bool, ::Any) at REPL.jl:154
print_response(::REPL.AbstractREPL, ::Any, ::Any, ::Bool, ::Bool) at REPL.jl:139
(::getfield(REPL, Symbol("#do_respond#40")){Bool,getfield(REPL, Symbol("##50#59")){REPL.LineEditREPL,REPL.REPLHistoryProvider},REPL.LineEditREPL,REPL.LineEdit.Prompt})(::Any, ::Any, ::Any) at REPL.jl:713
#invokelatest#1 at essentials.jl:697 [inlined]
invokelatest at essentials.jl:696 [inlined]
run_interface(::REPL.Terminals.TextTerminal, ::REPL.LineEdit.ModalInterface, ::REPL.LineEdit.MIState) at LineEdit.jl:2273
run_frontend(::REPL.LineEditREPL, ::REPL.REPLBackendRef) at REPL.jl:1034
run_repl(::REPL.AbstractREPL, ::Any) at REPL.jl:191
(::getfield(Base, Symbol("##720#722")){Bool,Bool,Bool,Bool})(::Module) at client.jl:355
#invokelatest#1 at essentials.jl:697 [inlined]
invokelatest at essentials.jl:696 [inlined]
run_main_repl(::Bool, ::Bool, ::Bool, ::Bool, ::Bool) at client.jl:339
exec_options(::Base.JLOptions) at client.jl:277
_start() at client.jl:425
run_interface
后一个 inlined 的函数就是我上面给出的连接中的 respond
。
你试试直接把代码写入一个文件foo.jl
里, 然后命令行执行julia foo.jl
会不会发生调用?
REPL是一个交互式工具,它会自动帮你调用一些函数,感兴趣可以看看源码https://github.com/JuliaLang/julia/tree/master/stdlib/REPL/src