2017-12-26 12 views
1

줄리아의 매크로에 변수 값을 전달하고 싶습니다. 나는 다음을 시도했지만 작동하지 않았다 :줄리아의 매크로에 변수 값을 전달하는 방법은 무엇입니까?

macro m(a,b) 
    @show a,b 
    ex = quote 
    $a = eval($b) 
    end 
    @show ex 
    esc(ex) 
end 

b = 1 
@m a $b 

출력 : 당신은 매우 가까웠다

(a, b) = (:a, :($(Expr(:$, :b)))) 
ex = quote # REPL[20], line 4: 
    a = eval($(Expr(:$, :b))) 
end 
ERROR: unsupported or misplaced expression $ 

답변

2

! :)

매크로는 컴파일시 작동 기능을하고, 너무 종류의 주석을 가질 수 있지만, 자신의 입력에만 Expr의, Symbol s 또는 상수 값, 즉 될 수 있습니다되기 전에 Int, 매크로가 입력을 평가하지 않습니다를 함수가 호출되기 전에 호출되는 것처럼 호출되는 매크로는 구문에 대해 작동합니다.

julia> macro m(a::Symbol, b) # in ths method a should allways be a symbol 
      # use spaces and parens as needed to delimit and 
      # group args as needed, not commas in this case 
      @show a b   # or use this: @show(a, b) notice comma here 
      ex = quote   # there is no need to use eval here a macro 
       $a = $b  # will compile and evaluate the returning 
      end    # expression when invoked 
      @show ex 
      return esc(ex)  # esc will use surrounding scope instead of gensyms 
     end 
@m (macro with 1 method) 

가 반환 된 표현의 몸이 경우에, 매크로의 몸 안에 eval를 사용하지 마십시오 (이이 필요한 수의 경우는, 그러나 이것은 그들 중 하나가 아닙니다).

julia> x = 2 
2 

솔직히 @eval 또는 [email protected] 작업과 같은 매크로 (매뉴얼에 설명되어야한다, 내가 그 매크로 코드를 공부해야합니다) ',하지만 당신은 돈을 보간 비슷한 만드는 방법을 아직 모른다 간단한 예제를 위해 매크로를 호출 할 때 $이 필요합니다.

julia> @m y (x + 1) # parens for grouping, or @m(y, x + 1) 
a = :y    # :y is a symbol 
b = :(x + 1) 
ex = quote 
    #= REPL[17]:4 =# 
    y = x + 1 
end 
3 

당신이 위생적으로 대신 주위의 범위 변수를 사용하여이 경우, gensym의 생성됩니다 esc를 사용하지 않는 경우. 이 같은

julia> @m z rand(x, y) 
a = :z 
b = :(rand(x, y)) 
ex = quote 
    #= REPL[17]:4 =# 
    z = rand(x, y) 
end 
2×3 Array{Float64,2}: 
0.817233 0.623775 0.277464 
0.421573 0.443654 0.296359 

gensym의 모습 : '@ eval`와`BenchmarkTools를 언급에 대한

julia> gensym(:foo) 
Symbol("##foo#924") 
+1

감사합니다 @ btime'.. 비슷한 일을하고 싶지만 아직 코드를 이해하지 못했습니다. – Phuoc

+0

[MacroTools.jl] (https://github.com/MikeInnes/MacroTools.jl)을 확인하십시오. – SalchiPapa

관련 문제