Julia does not appear to be using string to perform interpolation

£可爱£侵袭症+ 提交于 2019-12-12 10:55:34

问题


The official docs state:

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))

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

So what am I doing wrong?

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


回答1:


The documentation is perfectly correct:

julia> expand(:(println("hello $m")))
:(println((Base.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.

However, your overload

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

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")

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))

the result is as expected.


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

println("hello ", m)

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.



来源:https://stackoverflow.com/questions/40066212/julia-does-not-appear-to-be-using-string-to-perform-interpolation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!