【问题标题】:Is it possible to create types in Julia at runtime?是否可以在运行时在 Julia 中创建类型?
【发布时间】:2014-11-22 23:37:03
【问题描述】:

假设我想拥有表单的功能

abstract RecordType
function CreateRecordType(fields_names::Vector{ASCIIString}, type_name::ASCIIString)
    # magic that creates the type type_name with string fields field_names
end

例如,CreateRecordType(["name","age"], "Person") 将创建一个具有以下定义的新类型:

type Person <: RecordType
    name::ASCIIString
    age::ASCIIString
end

这可能在 Julia 中实现吗?

【问题讨论】:

    标签: julia


    【解决方案1】:

    方法一:解析得到一个AST,然后求值

    可能最简单的方法是创建一个你想要的字符串,然后解析它以获得一个 AST,然后评估 AST。您可以在函数内执行任何或所有操作。这里有一个可能的简单实现,可以做到这一切

    function CreateRecordType(typeName::ASCIIString,fieldNames::Array{ASCIIString,1},fieldTypes::Array{ASCIIString,1})
       s::ASCIIString = "type $typeName <: RecordType\n";
    
       for i = 1:length(fieldNames)
          s = s*"$(fieldNames[i])::$(fieldTypes[i])\n"
       end
       eval(parse(s*"end"));
       return;
    end
    

    使用它...

    julia> abstract RecordType;
    
    julia> CreateRecordType("Person",["name","age"],["ASCIIString","Int64"])
    
    julia> bubba = Person("Bubba",2)
    Person("Bubba",2)
    
    julia> print(bubba.age)
    2
    

    这可能没有它应该的效率那么高,相反,您可以查看 parse 生成的 AST,然后创建 Expr 以直接生成 AST 而不是使用 parse 而不是使用 a字符串。

    方法2:直接制作AST

    这是创建 AST 的另一种形式,它更安全一些,因为它需要类型和符号而不是不透明的字符串。这是通过尝试上面提到的各种解析的输出而创建的。使用 Dict 而不是 2 个数组可能会更好,因为字段和类型必须始终成对。

    function createTypeAST(typeName::Symbol,parentType::Type,fields::Dict{Symbol,DataType})
       e = Expr(:type,true)
       push!(e.args,Expr(:<:));
       push!(e.args[2].args,typeName);
       push!(e.args[2].args,parentType);
       push!(e.args,Expr(:block))
       for field in fields
          push!(e.args[3].args,:($(field[1])::$(field[2])));
       end
       return e;
    end
    

    第二种形式在行动

    julia> x = createTypeAST(:P1,RecordType,Dict(:a => Int64))
    :(type P1<:RecordType
            a::Int64
        end)
    
    julia> eval(x)
    
    julia> y = P1(1)
    P1(1)
    
    julia> y.a
    1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-03
      • 1970-01-01
      • 2011-08-08
      相关资源
      最近更新 更多