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

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

问题描述

官方文档规定:

串联和字符串插值都调用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.

将最小工作示例更新为

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.

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

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