该文档是完全正确的:
julia> expand(:(println("hello $m")))
:(println((Base.string)("hello ",m)))
也就是说,println("hello $m")
is 相等的 to println(string("hello", m))
。当代码被编译或解释时,它们是同一件事。
然而,你的超载
Base.string(m::MyType) = "world"
不是正确的超载方式string
。此方法仅涵盖具有单个类型参数的情况MyType
。 (顺便说一句,这就是为什么您的代码似乎适用于串联:该特定示例涉及调用string
就一个论点而言。如果你写的话结果会是一样的"$m"
.) 正确的重载方法是
Base.show(io::IO, m::MyType) = print(io, "world")
乍一看这可能看起来很奇怪。必须重载的原因是因为string
代表print
其委托给show
.
将您的最小工作示例更新为
type MyType
x::Int
end
Base.show(io::IO, m::MyType) = print(io, "world")
m = MyType(4)
println("hello $m")
println("hello " * string(m))
结果正如预期的那样。
作为脚注,请注意您的示例可以更高效地编写为
println("hello ", m)
这避免了创建中间字符串。这说明why该系统的设置是为了string
calls print
哪个调用show
:IO 方法更通用,可以直接打印到各种形式的 IO,而如果反过来,则必须在发送到 IO 之前将内容转换为字符串(需要临时分配,因此性能较差)。