美文网首页
Java & Groovy & Scala & Kotlin -

Java & Groovy & Scala & Kotlin -

作者: bookislife | 来源:发表于2017-06-08 00:41 被阅读0次

    Overview

    本节主要介绍各语言中脚本的实现和运行方式。所谓的脚本是使用一种特定的描述性语言,依据一定的格式编写的可执行文件。通常可以用于执行一些简单的代码。

    Java 篇

    Java 并不支持脚本

    Groovy 篇

    Groovy 中脚本后缀名也是 .groovy

    创建第一个脚本

    新建文件 scriptTest.groovy,文件内容如下

    println("Hello World")
    

    保存文件后在控制台 中执行以下语句

    groovy scriptTest.groovy
    

    成功的话可以看到命令行输出 Hello World 字符串。这就是脚本的优点,无需创建类,也无需编写可以 main() 方法就可以直接运行代码。

    在类或脚本中执行脚本

    Groovy 脚本在编译后实际也会转变为对应的 Java 类,所以上一节的例子在编译后会变成以下的代码

    public class scriptTest extends Script {
        public scriptTest() {
            CallSite[] var1 = $getCallSiteArray();
        }
    
        public scriptTest(Binding context) {
            CallSite[] var2 = $getCallSiteArray();
            super(context);
        }
    
        public static void main(String... args) {
            CallSite[] var1 = $getCallSiteArray();
            var1[0].call(InvokerHelper.class, scriptTest.class, args);
        }
    
        public Object run() {
            CallSite[] var1 = $getCallSiteArray();
            return var1[1].callCurrent(this, "Hello World");
        }
    }
    

    分析以上代码,可以看到 Groovy 脚本编译后实际是生成了一个继承自 Script 的类。该类有两个构造方法(空构造方法和以 Binding 为参数的构造方法),一个 main() 方法,一个 run() 方法,实际编写的代码其实是被编译到 run() 方法中。所以在其它程序中执行 Groovy 脚本就很容易了,只要 new 一个这个脚本类的实例并执行 run() 方法就可以了。

    def scope = new scopeScript()
    scope.run()
    

    这里特别要注意的是 Groovy 脚本名可以包含 - 这样的特殊字符,但是这种字符并不符合 Java 的类名规范,所以如果脚本名包含特殊字符时就无法通过以上方被执行代码,所以最简单的避免方式就是脚本名不要用特殊字符。

    本地域与绑定域

    Groovy 脚本中定义的变量有两种作用域,分别为绑定域 (Binding Scope) 和本地域 (Local Scope)。本地域为脚本中使用 def 定义的动态类型变量或用特定类型定义的静态类型变量。绑定域为没有任何前缀修改的变量。

    本地域

    String hello = "hello"
    def world = "world"
    

    绑定域

    helloworld = "hello world"
    

    本地域在编译后会被声明为 run() 方法中的临时变量,所以只能被脚本当中的语句调用,无法被脚本中定义的其它方法调用。

    绑定域可以通过外部的脚本对象的 binding 属性进行赋值,在编译后会被变为脚本类的成员变量,所以可以被脚本中定义的其它方法调用。

    编写 scopeScript.groovy 文件,内容如下

    package com.bookislife.jgsk.groovy._10_script
    
    //local scope
    String hello = "hello"
    def world = "world"
    
    //binding scope
    helloworld = "hello world"
    
    void otherMethod() {
        //  Wrong!! 无法访问本地域 hello 和 world
    //    println hello
    //    println world
        // 可以访问绑定域
        println(helloworld)
    }
    
    println "${hello} ${world}, ${helloworld}"
    
    //  脚本中定义的方法只能访问绑定域
    otherMethod()
    

    编写 Scripts.groovy 类文件,以此来调用 scopeScript.groovy 文件

    package com.bookislife.jgsk.groovy._10_script
    
    class Scripts {
    
        public static void main(String[] args) {
            //  Run Scripts
            def scope = new scopeScript()
    
            //  Binding Values
            scope.binding.hello = "goodbye"       //    hello is not a binding scope
            scope.binding.helloworld = "hello groovy"   //  helloworld is a binding scope
            scope.otherMethod()
        }
    }
    

    通过以上代码可以看到可以使用 binding 属性为脚本中的绑定域进行赋值,但是无法修改本地域。

    Scala 篇

    Scala 脚本不会被编译成类文件,所以没有 Groovy 脚本那么强大的功能。

    编写脚本

    编写脚本文件 scriptTest.scala

    println(s"Hello World, ${if (args.nonEmpty) args(0) else ""}")
    

    保存文件,在控制台下执行以下代码

    scala scriptTest.scala Peter
    

    成功的话会输出 "Hello World, Peter"。

    从以上代码可以看到 Scala 脚本中使用默认的数组 args 来存储输入的参数。

    在 IDEA 中运行脚本

    和 Groovy 不一样,Scala 脚本无法直接在 IDEA 中运行,IDEA 会报无法执行或者运行时报找不到符号。如果希望在 IDEA 中运行的话,需要先进行以下设置:

    1. 打开 "Run" -> "Edit Configurations"
    2. 点击左上角的 "+" 号,选择 "Scala Script"
    3. 输入任意 Name,在 "Script file" 一项中选择要运行的脚本文件
    4. 在 "Before launch" 一项中删除 "Make" 操作
    5. 上述完成后就可以运行脚本了


    Kotlin 篇

    Kotlin 脚本后缀为 .kts,是 Kotlin 1.0 新增加的功能。

    编写脚本

    编写脚本文件,scriptTest.kts,内容如下

    println("Hello World, ${if (args.isNotEmpty()) args[0] else ""}")
    

    保存后在命令行执行以下代码

    kotlinc -script scriptTest.kts Peter
    

    成功的话会输出 "Hello World, Peter"。

    同 Scala 一样,Kotlin 脚本也使用数组 args 来存储输入的参数。

    Summary

    • 除 Java 外都支持脚本,其中 Groovy 的功能最强
    • Idea 可以直接运行 Groovy 和 Kotlin 脚本,但不支持直接运行 Scala 脚本

    文章源码见 https://github.com/SidneyXu/JGSK 仓库的 _10_script 小节

    相关文章

      网友评论

          本文标题:Java & Groovy & Scala & Kotlin -

          本文链接:https://www.haomeiwen.com/subject/zwhzfxtx.html