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

时间:2016-10-16 02:25:57

标签: string julia string-interpolation

官方文件声明:

  

串联和字符串插值调用string()将对象转换为字符串形式

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

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,但官方文档版本表明不应该有任何区别。)

1 个答案:

答案 0 :(得分:9)

文档完全正确:

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之前,必须将事物转换为字符串(需要临时分配,因此性能不佳)。