Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Julia 使用宏访问表达式中的值_Julia - Fatal编程技术网

Julia 使用宏访问表达式中的值

Julia 使用宏访问表达式中的值,julia,Julia,我想知道是否有可能定义一个宏,仅当值属于特定类型时才能修改表达式的值 下面是一个简单的例子: type Special x::Int end f1(s, n::Special) = println("f1", s, n) f2(s, n::Special) = println("f2", s, n) x1 = Special(3) x2 = Special(5) expr = :( f1("this is f1", x1), f2("this is f2", x2

我想知道是否有可能定义一个宏,仅当值属于特定类型时才能修改表达式的值

下面是一个简单的例子:

type Special
    x::Int
end

f1(s, n::Special) = println("f1", s, n)
f2(s, n::Special) = println("f2", s, n)

x1 = Special(3)
x2 = Special(5)

expr =  :(
    f1("this is f1", x1),
    f2("this is f2", x2)
    )
现在,宏可以检查函数参数的值,确定
x1
x2
属于
特殊类型
,运行一些函数来修改它们的值,例如将3更改为4,将5更改为2(可能涉及比较两个值),然后将表达式传递回调用方。最终结果相当于调用:

f1("this is f1", 4)
f2("this is f2", 2)
我发现可以通过以下方式访问宏中的值:

eval(eval(filter(x -> typeof(eval(x)) == Special, expr.args[1].args))[1]).x

=> 3

但是,尽管这样做是可行的,但它看起来是错误的,我可能做得不对,或者试图做得太离谱了……

不,您应该永远不要尝试检查宏中的类型或值。使用
eval
计算宏中某个内容的类型或值在非常有限的情况下可能有效,但在几乎所有实际使用中都会中断。相反,只需让宏插入对泛型函数的调用—这就是Julia擅长区分类型(作为方法分派)和值(在方法中)的地方:


谢谢你,马特。我正在重新思考我的方法……:)
munge_special(x::Special) = Special(x.x + 42)
munge_special(x) = x
macro do_something_special(x)
    return :(munge_special($(esc(x))))
end

julia> @do_something_special Special(2)
Special(44)

julia> @do_something_special 3
3