zoukankan      html  css  js  c++  java
  • Julia体验 语言特性 元编程,宏

    上接语言基础,就release-1.1来看,个人感觉这门语言和自己心中的理想国相距较远。这门语言因为受众不仅仅是程序员有很多让人迷惑的设计,但是奇怪的是它的语法等表象设计虽然暗示这不是专门为程序员准备的,内在的却提供了大量非程序员不可用的高级特性,库。

    乘着热情还在,我挑一些有趣的东西再写写。

    元编程

    元编程即对代码进行处理的代码,可以使用Meta.parse()解析出参数代码的类AST表示,也可以使用quote ... end简化:

    julia> multiStmt = Meta.parse(raw"a=1;b=2;t=a;a=b;b=t;println(a,b)")
    :($(Expr(:toplevel, :(a = 1), :(b = 2), :(t = a), :(a = b), :(b = t), :(println(a, b)))))
    
    julia> typeof(multiStmt)
    Expr
    
    julia> ast = quote
           x=1
           y=2
           res=x+y
           end
    quote
        #= REPL[21]:2 =#
        x = 1
        #= REPL[21]:3 =#
        y = 2
        #= REPL[21]:4 =#
        res = x + y
    end
    
    julia> typeof(ast)
    Expr
    

    使用dump()获得更可读的表示:

    julia> dump(multiStmt)
    Expr
      head: Symbol toplevel
      args: Array{Any}((6,))
        1: Expr
          head: Symbol =
          args: Array{Any}((2,))
            1: Symbol a
            2: Int64 1
        2: Expr
          head: Symbol =
          args: Array{Any}((2,))
            1: Symbol b
            2: Int64 2
        3: Expr
          head: Symbol =
          args: Array{Any}((2,))
            1: Symbol t
            2: Symbol a
        4: Expr
          head: Symbol =
          args: Array{Any}((2,))
            1: Symbol a
            2: Symbol b
        5: Expr
          head: Symbol =
          args: Array{Any}((2,))
            1: Symbol b
            2: Symbol t
        6: Expr
          head: Symbol call
          args: Array{Any}((3,))
            1: Symbol println
            2: Symbol a
            3: Symbol b
    

    expr有两部分,expr.head表示出这个表达式的类型,expr.args表示出剩余的参数:

    julia> multiStmt.head
    :toplevel
    
    julia> multiStmt.args
    6-element Array{Any,1}:
     :(a = 1)
     :(b = 2)
     :(t = a)
     :(a = b)
     :(b = t)
     :(println(a, b))
    

    如果我们typeof head会发现,它是一种名为Symbol的类型:

    julia> typeof(multiStmt.head)
    Symbol
    

    Symbol类型可以使用:name进行定义,也可以使用Symbol类型的构造创建:

    julia> :str
    :str
    
    julia> typeof(:str)
    Symbol
    
    julia> Symbol("str2")
    :str2
    
    julia> typeof(Symbol("str2"))==typeof(:str)
    true
    
    

    最后我们使用eval()h函数传入Expr类型参数求值:

    julia> eval(ast)
    3
    
    julia> eval(multiStmt)
    21
    

    这就给了我们一种使用代码操纵代码的方式:

    julia> add = Expr(:call,:-,:a,:b)
    :(a - b)
    
    julia> a = 1
    1
    
    julia> b= 2
    2
    
    julia> eval(add)
    -1
    

    Julia的宏由macro ... end定义

    julia> macro hello(name)
           return "hello,my name is "*name
           end
    @hello (macro with 1 method)
    
    julia> println(@hello("Andrew"))
    hello,my name is Andrew
    
    julia> println(@hello "Andrew")
    hello,my name is Andrew
    

    使用宏可以像函数一样加括号也可以宏名 参数1 参数2 ...
    类似C/C++的宏的概念,Julia的宏也是实施的替换操作
    所以上述println(@hello "Andrew")会被替换为println("hello, my name is Andrew"),可以使用@macroexpand获得展开后的结果

    julia> @macroexpand println(@hello "Andrew")
    :(println("hello,my name is Andrew"))
    
  • 相关阅读:
    Windows控制程序网站带宽及Qos(TOS或DSCP)
    VBA读取、增加自定义和修改文档属性
    使用Bazel构建C/C++项目
    GoogleTest入门
    八卦一下Starlark语言
    混合编译.c/.cpp与.cu文件
    Mac Mojave(10.14.1)执行Matlab的mex报错
    安装和配置bazel
    从44.556677想到的
    Oracle中如何实现Mysql的两表关联update操作
  • 原文地址:https://www.cnblogs.com/ysherlock/p/9502266.html
Copyright © 2011-2022 走看看