Julia 似乎没有使用字符串来执行插值

Julia does not appear to be using string to perform interpolation

官方文档状态:

Both concatenation and string interpolation call string() to convert objects into string form

但是,以下最小工作示例似乎证明了其他情况:

type MyType
    x::Int
end
import Base.string
Base.string(m::MyType) = "world"
m = MyType(4)
println("hello $m")
println("hello " * string(m))

倒数第二行在 REPL 中的计算结果为 hello MyType(4),而最后一行的计算结果(如预期的那样)为 hello world.

那我做错了什么?

(我仍在使用 v0.4,但官方文档版本表明应该没有任何区别。)

文档完全正确:

julia> expand(:(println("hello $m")))
:(println((Base.string)("hello ",m)))

也就是说,println("hello $m")等价于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)

这避免了创建中间字符串。这说明了为什么系统设置为string调用print而调用show:IO方法更通用,可以打印到各种直接使用 IO 形式,而如果反过来,则必须在发送到 IO 之前将其转换为字符串(需要临时分配,因此性能不佳)。