Gadfly有一个漂亮的宏,可以为一些大型类型生成一个复制构造函数和可选的参数构造函数:
# Generate large types where each field has a default value to which it's
# initialized.
macro varset(name::Symbol, table)
@assert table.head == :block
table = table.args
names = Any[]
vars = Any[]
parameters = Any[]
parameters_expr = Expr(:parameters)
for row in table
if isa(row, Expr) && row.head == :line
continue
end
if isa(row, Symbol)
var = row
typ = :Any
default = :nothing
elseif row.head == :tuple
@assert 2 <= length(row.args) <= 3
var = row.args[1]
typ = row.args[2]
default = length(row.args) > 2 ? row.args[3] : :nothing
else
error("Bad varset systax")
end
push!(names, var)
push!(vars, :($(var)::$(typ)))
push!(parameters, Expr(:kw, var, default))
parameters_expr = Expr(:parameters, parameters...)
end
new_with_defaults = Expr(:call, :new, names...)
ex =
quote
type $(name)
$(vars...)
function $(name)($(parameters_expr))
$(new_with_defaults)
end
# shallow copy constructor
function $(name)(a::$(name))
b = new()
for name in fieldnames($(name))
setfield!(b, name, getfield(a, name))
end
b
end
end
function copy(a::$(name))
$(name)(a)
end
end
esc(ex)
end
我想添加一个部分复制构造函数,它允许您提供一个对象和一些部分参数。它将复制提供的对象并仅覆盖您提供的字段。
我怎样才能定义如下内容?伪代码肥胖型:
function $(name)(a::$(name), $(parameters_expr))
b = new(a)
for name in names
if getfield(b, name) != default
setfield!(b, name, new_val)
end
end
end