与朱莉娅代码生成

时间:2017-05-09 13:52:29

标签: julia

我想为我自己的类型覆盖默认的字符串方法(因为我发现它们很难看)。

此函数将用于生成字符串

function prettyPrint(value::Any)
  names::Vector{Symbol} = fieldnames(value)
  nameCount::Int64 = length(names)
  stringBuilder::IOBuffer = IOBuffer()
  print(stringBuilder, string(typeof(value).name) *"(")
  for (index, name) in enumerate(names)
    print(stringBuilder, string(name) * "=" * string(getfield(value, name)))
    if index != nameCount
      print(stringBuilder, ", ")
    end
  end
  print(stringBuilder, ")")
  takebuf_string(stringBuilder)
end

让我们定义样本类型

type Foo
  a::Int64
  b::String
  c::Float64
end

然后我尝试使用这段代码生成字符串函数

import Base.string

for dataType in (:Foo)
  eval(quote
       function string(dt::$dataType)
        prettyPrint(dt)
       end
       end)
end

foo = Foo(1, "2", 3.0)
println(string(foo))

这会因为一条冗长的错误消息而崩溃,告诉我什么都不能用。

ERROR: LoadError: MethodError: no method matching start(::Symbol)
Closest candidates are:
  start(!Matched::SimpleVector) at essentials.jl:170
  start(!Matched::Base.MethodList) at reflection.jl:258
  start(!Matched::IntSet) at intset.jl:184
  ...
 in anonymous at .\<missing>:?
 in include_from_node1(::String) at .\loading.jl:488
 in process_options(::Base.JLOptions) at .\client.jl:265
 in _start() at .\client.jl:321
while loading ~\codegeneration.jl, in expression starting on line 24

第24行是(:Foo)&#39; -line中数据类型的&#39;

说实话,我希望这个功能可以作为一个宏,但我甚至不知道我会怎么做。

macro PrettyPrint(someType)
   ? someType is an expression, how do I get to the type
   ? how do I even know what part of the expression is the type

end
@PrettyPrint type Foo
 a::Int64 ... end

1 个答案:

答案 0 :(得分:6)

您收到的错误消息是(:Foo) == :Foo。我想你想要一个元组迭代,所以你需要(:Foo,)。也就是说,eval不是首选方式。

如果你这样做

function Base.show(io::IO, dt::Foo)
    print(io,prettyprint(dt))
end

它将更改repl中的默认打印,您可以使用repr获取字符串版本。