2017-05-09 2 views
2

내 자신의 유형에 대한 기본 문자열 메소드 (추악하기 때문에)를 덮어 쓰려고합니다.줄리아 코드 생성

이 함수

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 

는 I 코드의 비트를 사용하여 문자열 함수를 생성하려고이어서

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는 'for (: Foo)'라인의 데이터 타입입니다.

솔직히이 기능을 매크로로 사용하고 싶지만 어떻게 할 수 있는지조차 알 수 없습니다.

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

문자열로 코드 생성을 실제로하지 말아야합니다. 실제 메타 프로그래밍을 사용하십시오. https://docs.julialang.org/en/stable/manual/metaprogramming/ – StefanKarpinski

답변

6

오류 메시지는 (:Foo) == :Foo입니다. 반복 할 튜플을 원했기 때문에 (:Foo,)이 필요합니다. 즉, eval은이 작업을 수행하는 기본 방법이 아닙니다.

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

을 할 경우는 REPL에서 기본 인쇄를 변경됩니다, 그리고 당신은 repr와 문자열 버전을 얻을 수 있습니다.

+0

요점은 수십개를 쓰지 않으려한다는 것입니다. 그 기능을 손으로 그래서 코드 생성을 사용합니다. – Nozdrum

+3

@Nozdrum - 공용체 : Base.show (io :: IO, dt :: Union {Foo, Bar, Baz})'를 사용하십시오. –