假如定义了一个module
里面有很多函数,这些函数我都需要,所以在模块尾部我需要一个一个export他们,在别的地方使用又要显式import他们。
我想用这样的方法定义函数:
pub function foo()
end
这样我就不用export了,但是没有pub这个关键字,我想问一下有没有办法写一个宏,使得函数定义和export在一条语句里依次执行,这样就可以少写很多代码了
假如定义了一个module
里面有很多函数,这些函数我都需要,所以在模块尾部我需要一个一个export他们,在别的地方使用又要显式import他们。
我想用这样的方法定义函数:
pub function foo()
end
这样我就不用export了,但是没有pub这个关键字,我想问一下有没有办法写一个宏,使得函数定义和export在一条语句里依次执行,这样就可以少写很多代码了
试着写了一个
macro public(ex)
if ex.head == :function || ex.head == :(=)
eval(ex)
if ex.args[1] isa Symbol
:(export $(ex.args[1]))
else
:(export $(ex.args[1].args[1]))
end
else
@error "not a defination of function"
end
end
Thank you
那个,如果我要export模块里的结构体我该怎么重写这个宏??
可以用
ex = Meta.parse("""struct foo
end""")
看一下传入的Expr是怎样构成的,ex.head是什么,找到 foo 对应的位置,写个if判断一下ex.head, 构造一个 :(export foo)
顺便问一下,这个宏在把参数代入时是不是会做一些处理,比如把ex当作一个表达式Expr来处理,而不是纯文本
感谢你的提醒,这个宏照你的参考了一下,做出来了
macro pub(ex)
eval(ex)
if ex.head == :struct
:(export $(ex.args[2]))
elseif ex.head == :function || ex.head == :(=)
if ex.args[1] isa Symbol
:(export $(ex.args[1]))
else
:(export $(ex.args[1].args[1]))
end
end
end
就是在定义模块时在下面显式导入才能用
module foo
import ..@pub
#code
end
是的,传入的参数是表达式或者符号
但是如果你全部都要导出,那你为什么要用module呢?module的目的就是控制不要导出啊。
如果是想写inline的export,可以看下InlineExport.jl,这个syntax日后应该会进入Julia里。也就是export可以直接写定义前面,不需要写两遍名字了就。
纯属好奇,不断尝试作死
应该是 eval
的问题,改成 __module__.eval
eval(expr)
Evaluate an expression in the global scope of the containing module. Every
Module
(except those defined withbaremodule
) has its own 1-argument definition ofeval
, which evaluates expressions in that module.
非常感谢,终于解决了
我又改进了一下,加入泛型的struct和function
macro pub(ex)
__module__.eval(ex)
#function
if ex.head == :function || ex.head == :(=)
if ex.args[1].head == :where
:(export $(ex.args[1].args[1].args[1]))
else
:(export $(ex.args[1].args[1]))
end
elseif ex.head == :struct# struct
if ex.args[2] isa Symbol
:(export $(ex.args[2]))
else
:(export $(ex.args[2].args[1]))
end
else
@error "not a define of struct or function"
end
end
你并不需要显示地一个一个import这些函数,只需要类似于using Images
就可以了
那你有没有考虑过两个模块里有同名,同参数的函数时该怎么办
在那种情况下确实是需要显示导入的,但是这并不意味着你需要显示导入所有名称(包括那些不冲突的)。