Julia 似乎没有使用字符串来执行插值 [英] Julia does not appear to be using string to perform interpolation

查看:17
本文介绍了Julia 似乎没有使用字符串来执行插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

官方文档说明:

连接和字符串插值都调用string()将对象转换成字符串形式

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

但是,以下最低限度的工作示例似乎证明并非如此:

However, the following minimum working example seems to demonstrate otherwise:

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.

The second last line evaluates to hello MyType(4) at the REPL, while the last line evaluates (as expected) to hello world.

那我做错了什么?

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

(I am still on v0.4 but the official doc versions indicate that shouldn't make any difference.)

推荐答案

文档完全正确:

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

也就是说,println("hello $m") 等价println(string("hello", m)).到代码被编译或解释时,它们已经是同一个东西了.

That is to say, println("hello $m") is equivalent to println(string("hello", m)). By the time the code is compiled or interpreted, they are the same thing.

但是,你的超载

Base.string(m::MyType) = "world"

不是重载 string 的正确方法.此方法仅涵盖类型为 MyType 的单个参数的情况.(这就是为什么,顺便说一句,您的代码似乎适用于连接:该特定示例涉及在单个参数上调用 string.如果您编写了 "$m,结果将是相同的".) 重载它的正确方法是

is not the correct way to overload string. This method only covers the case with a single argument of type MyType. (This is why, incidentally, your code seemed to work for concatenation: that particular example involved calling string on a single argument. The results would have been the same if you had written "$m".) The correct way to overload it is

Base.show(io::IO, m::MyType) = print(io, "world")

起初可能看起来很奇怪.这必须重载的原因是因为 string 委托给 print 而委托给 show.

which may seem weird at first. The reason this must be overloaded is because string delegates to print which delegates to show.

将您的最小工作示例更新为

After updating your minimum working example to

type MyType
    x::Int
end
Base.show(io::IO, m::MyType) = print(io, "world")
m = MyType(4)
println("hello $m")
println("hello " * string(m))

结果符合预期.

作为脚注,请注意您的示例可以更高效地编写为

As a footnote, note that your example can be more performantly written as

println("hello ", m)

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

which avoids the creation of intermediate strings. This illustrates why the system is set up so that string calls print which calls show: the IO method is more generic and can print to various forms of IO directly, whereas if it went the other way around, one would have to convert things into strings (requiring temporary allocation and thus poor performance) before sending to IO.

这篇关于Julia 似乎没有使用字符串来执行插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆