CoreJava 新闻api map遍历 string soap pyspark uiviewcontroller onclick seo android项目实例 mysql降序 python与机器学习 wps临时文件 当前时间减一天 input边框颜色 python字典get python运算符优先级 python中import用法 java程序 p2pover 方正流行体 找茬辅助 快捷精灵 netreflector 模拟按键 r330不能识别墨盒 web聊天室 txplatform jquery手册 edquota 回收站在哪个盘 ocr文字识别软件免费下载 ps祛痘 刷新当前页面 ps旋转图层 class选择器 打开组策略的命令 win10画图在哪里 聊呗电脑版 python贪吃蛇
当前位置: 首页 > 学习教程  > 编程语言

第十章、Groovy静态语言特性

2020/12/5 10:05:05 文章标签:

文章目录1、选择静态特性动机1.1、Groovy的角色类型1.2、类型检查是动态语言吗2、使用TypeChecked2.1、查找类型2.2、解决方法调用2.3、检查赋值2.4、类型推断2.5、groviness类型检查2.6、闭包类型检查2.7、重新审视类型检查的动态特性2.8、类型检查代码和动态代码混合3、流类型…

文章目录

    • 1、选择静态特性动机
      • 1.1、Groovy的角色类型
      • 1.2、类型检查是动态语言吗
    • 2、使用@TypeChecked
      • 2.1、查找类型
      • 2.2、解决方法调用
      • 2.3、检查赋值
      • 2.4、类型推断
      • 2.5、groviness类型检查
      • 2.6、闭包类型检查
      • 2.7、重新审视类型检查的动态特性
      • 2.8、类型检查代码和动态代码混合
    • 3、流类型
      • 3.1、最小上界
      • 3.2、 Smart instance of inference
      • 3.3、闭包分享变量
    • 4、静态编译
      • 4.1、@CompileStatic
      • 4.2、 方法调度
    • 5、静态类型检查扩展
      • 5.1、@DelegatesTo
      • 5.2、限制
    • 6、总结

1、选择静态特性动机

1.1、Groovy的角色类型

  • groovy是有类型,只是默认了

    • /**
       * 方法类型测试
       * @author liangchen* @date 2020/11/13
       */
      class TypeTest extends GroovyTestCase {
      
          void testMethod(){
             assert "2:Hello" == this.greet("Hello")
             assert "1:World" == this.greet((Object)"World")
          }
      
          /**
           * 默认类型是bject
           * @param message
           * @return
           */
          def greet(message){
              return  "1:$message"
          }
      
          def greet(String message) {
              return  "2:$message"
          }
      
      }
      
      

1.2、类型检查是动态语言吗

    • package com.jack.groovy.ch10
      
      /**
       * @author liangchen* @date 2020/11/13
       */
      class Duck101  {
      
          def methodMissing(String name, Object args) {
              println "$name!"
          }
      
      }
      def duck = new Duck101()
      duck.quack()
      

2、使用@TypeChecked

  • 例子

    • import groovy.ant.AntBuilder
      import groovy.transform.TypeChecked
      
      class Actor11{
          String firstName, lastName
          @TypeChecked
          String getFullName() { "$firstName $lastName" }
      
          void makePeace(){
              new AntBuilder().echo('Peace was never an option')
          }
      }
      
      def magneto = new Actor11(firstName: "Ian", lastName: 'MacKellen')
      assert magneto.fullName == 'Ian MacKellen'
      magneto.makePeace()
      

2.1、查找类型

  • @TypeChecked 编译器提示拼写错误
    • image-20201113173108023

2.2、解决方法调用

2.3、检查赋值

  • 赋值类型不对
@TypeChecked
    void testAssignmentsShouldThrowCompilationErrors(){
        Set set = new Object()
        byte b = 200L
    }
    
  • 赋值

    • /**
       * @author liangchen* @date 2020/11/13
       */
      
      enum MyEnum{
          var,val
      }
      
      @groovy.transform.TypeChecked
      void testAssignmentsWithCoercion(){
        // 字符串字段转成枚举
          MyEnum val = 'val'
          assert val == MyEnum.val
      
          String blue = java.awt.Color.BLUE
          assert blue == 'java.awt.Color[r=0,g=0,b=255]'
      
          boolean nonEmpty = new Date()
          Boolean empty = ''
          assert nonEmpty
          assert !empty
      
          Class stringClass = 'java.lang.String'
          assert stringClass.interfaces.size() == 3
      }
      
      testAssignmentsWithCoercion()
      

2.4、类型推断

  • 数组转list

    • import groovy.transform.TypeChecked
      
      @TypeChecked
      void printAuthors(){
          def authors = ['Dierk', 'Guillaume']
          printToUpperCase(authors)
      }
      
      void printToUpperCase(List<String> authors) {
          authors.each {println it.toUpperCase()}
      }
      

2.5、groviness类型检查

  • 构造函数参数不正确

    • @groovy.transform.TypeChecked
      
      void oneDimensional(){
          java.awt.Dimension d = [100]
      }
      
      shouldFail(ClassCastException){
          oneDimensional()
      }
      
      

2.6、闭包类型检查

2.7、重新审视类型检查的动态特性

  • import groovy.time.TimeCategory
    import groovy.xml.MarkupBuilder
    
    // --- doCompute并没打开TimeCategory类,而调用者打开TimeCategory,被调用者可以使用TImeCategory功能
    class VacationHelper {
        static duration() {
            use(TimeCategory){
                doCompute()
            }
        }
    
        static doCompute(){
            1.week - 1.day
        }
    }
    assert VacationHelper.duration().toString() == '6 days'
    
    
    //------ 10.29 使用ExpandoMetaClass, 动态定义方法, 接力的感觉
    class Spy {
        static {
            def mc = new ExpandoMetaClass(Spy, false, true)
            mc.initialize()
            Spy.metaClass = mc
        }
        String name = "James"
    
        void methodMissing(String name, args) {
            if (name.startsWith("changeNameTo")) {
                println "Adding method $name"
                String newName = name.substring(12)
                def newMethod = {
                    delegate.name = newName
                }
                //定义方法
                Spy.metaClass."$name" = newMethod
                newMethod()
            } else {
                throw new MissingMethodException(name, this.class, args)
            }
    
        }
    }
    
    def spy = new Spy()
    assert  "James" == spy.name
    spy.changeNameToAustin()
    assert "Austin" == spy.name
    
    spy.changeNameToMaxwell()
    assert "Maxwell" == spy.name
    
    spy.changeNameToAustin()
    assert "Austin" == spy.name
    
    // 10.30 ============输出xml格式文本
    
    def xml = new MarkupBuilder(writer)
    xml.html{
        head{
            title('An XHTML Page')
        }
        body{
          dev{
              dev("start")
          }
        }
    }
    d
    

2.8、类型检查代码和动态代码混合

  • /**
     * @author liangchen* @date 2020/11/18
     */
    
    class HTMLExample{
    
        @TypeChecked(TypeCheckingMode.SKIP)
        private static String buildPage(String pageTitle) {
            def xml = new MarkupBuilder()
            xml.html{
                head{title(pageTitle)}
            }
    
    
        }
    
        @TypeChecked
        static String page404(){
            buildPage '404 - Not Found'
        }
    }
    HTMLExample.page404()
    
    
    

3、流类型

package com.jack.groovy.ch10

import groovy.transform.TypeChecked

/**
 * @author liangchen* @date 2020/11/18
 */

//@TypeChecked
def flowTyping() {
    // 一个变量名,会有不同类型值, 这个var的类型是动态
    def var = 'A String'
    var = var.toUpperCase()
    var = var.length()
    var = String.valueOf(var)
    var = 2*var

}

interface Flying{
    void fly()
}
class Bird implements  Flying{
    void fly(){
        println "I'm flying"
    }
}
class Canary extends Bird{
    void sing(){
        println "Tweet!"
    }
}


/**
 *引用也是 
 */
@TypeChecked
void aviary(){
    def o = new Bird()
    o.fly()
    o = new Canary()
   
    o.fly()
    o.sing()
}
aviary()

3.1、最小上界

  1. 子类可以赋值给父类
  • package com.jack.groovy.ch10
    
    
    import groovy.transform.TypeChecked
    
    /**
     * @author liangchen* @date 2020/11/18
     */
    
    interface Polite{
        void greet()
        void thank()
    }
    
    class Person implements Polite {
    
        @Override
        void greet() {
            String name
            println "Hello , I'm $name!"
        }
    
        @Override
        void thank() {
            println "Thanks!"
        }
    
    }
    class Owl implements Polite{
    
        @Override
        void greet() {
            hoot()
        }
    
        @Override
        void thank() {
            hoot()
        }
        void hoot(){
            println "Hoot"
        }
    }
    @TypeChecked
    void main(){
        def list = [new Person(name:"Bill"), new Owl()]
        Polite p1 = list[0]
        Polite o1 = list[1]
        Owl o2 = list[1] as Owl
        Person p2 = list[0] as Person
    
    }
    //@TypeChecked, Date 和 Hello 公用父类是Serializable, 就会去这类去找是否存在time属性
    void leastUpperBoundOnConditional() {
        def o = new Date()
        if (Math.random()) {
            
            o = 'Hello'
        }
        o.time
    }
    

3.2、 Smart instance of inference

  • 相对java,groovy不需要显式转换

  • //java
    if(obj instanceof Person){
      value = ((Person)obj).getName();
    }
    //groovy
    if(obj instanceof Person){
      value = obj.getName();
    }
    

3.3、闭包分享变量

  • package com.jack.groovy.ch10
    
    import groovy.transform.TypeChecked
    
    /**
     * @author liangchen* @date 2020/11/18
     */
    
    // 表示外部变量可以在闭包中修改
    def captureOfALocalVariable() {
        def msg = 'Hello'
        def cl = { msg = 'Hi!' }
        assert msg == 'Hello'
        cl()
        assert msg == 'Hi!'
    }
    captureOfALocalVariable()
    
    // 10.38 toUpperCase, 类型不对
    //@TypeChecked
    void notAllowed(){
        def var = "String"
        def cl = {var  = new Date()}
        cl()
        var = var.toUpperCase()
    }
    //notAllowed() 报错
    
    // 10.39, valid assignment of closure-shared
    
    class A{
        void foo() {}
    }
    class B extends A{
        void bar(){}
    }
    void main(){
        def var = new A()
        def cl = {var = new B()}
        cl()
        var.foo()
    }
    main()
    

4、静态编译

4.1、@CompileStatic

  • 静态编译更快

  • package com.jack.groovy.ch10
    
    import groovy.transform.CompileStatic
    
    /**
     * @author liangchen* @date 2020/11/18
     */
    
    // 引用测试jar
    @Grab ('org.gperfutils:gbench:0.4.3-groovy-2.4')
    
    
    def dynamicFib(n) {
        n < 1 ? 1 : dynamicFib(n - 1) + dynamicFib(n - 2)
    }
    
    int primFib(int n) {
        n < 1 ? 1 : primFib(n - 1) + primFib(n - 2)
    }
    
    @CompileStatic
    int staticFib(int n) {
        n < 1 ? 1 : staticFib(n - 1) + staticFib(n - 2)
    
    }
    
    def r = benchmark {
        'Dynamic Groovy' {
            dynamicFib(10)
        }
        'Primitive optimized Groovy' {
            primFib(10)
        }
        'Statically compiled Groovy' {
            staticFib(10)
        }
    }
    r.prettyPrint()
    
    
    //输出
    Environment
    ===========
    * Groovy: 3.0.6
    * JVM: Java HotSpot(TM) 64-Bit Server VM (25.231-b11, Oracle Corporation)
        * JRE: 1.8.0_231
        * Total Memory: 213 MB
        * Maximum Memory: 3641 MB
    * OS: Mac OS X (10.15.4, x86_64)
    
    Options
    =======
    * Warm Up: Auto (- 60 sec)
    * CPU Time Measurement: On
    
                                user  system   cpu  real
    
    Dynamic Groovy              3680      11  3691  3711
    Primitive optimized Groovy   997       4  1001  1008
    Statically compiled Groovy   425       4   429   434
    

4.2、 方法调度

  • 因为groovy没有声明类型,所以的类型是通过值进行推断的,java则是相反,它根据声明的类型推断

  • package com.jack.groovy.ch10
    
    /**
     * @author liangchen* @date 2020/11/18
     */
    //
    public class Greeter {               // Java!
    
        static void greet(Object o) {
    
            System.out.println("Hello, object "+o);
    
        }
    
        static void greet(String s) {
    
            System.out.println("Hello, string " + s);
    
        }
    
        public static void main(String...args) {
    
            Object o = "Bob";
    
            String s = "Bob";
    
            greet(o);
    
            greet(s);
    
        }
    
    }
    // 在java环境输出是
    //Hello, object Bob
    //Hello, string Bob
    
    // groovy环境输出是
    //Hello, string Bob
    
    //Hello, string Bob
    
    // 10.43,静态方法不能够被动态方法影响到
    class MyFrammework{
        static int sizeOf(String s){
            s.size()
        }
    
        @CompileStatic
        static int staticSizeOf(String s) {
            s.size()
        }
    
    }
    
    String s = "a Happy new year!"
    s.metaClass.size = { -> 5 }
    assert s.size() == 5
    // 返回动态方法
    assert MyFrammework.sizeOf(s) == 5
    // 静态方法,原始子串长度
    assert MyFrammework.staticSizeOf(s) == 17
    

5、静态类型检查扩展

  • package com.jack.groovy.ch10
    
    import groovy.transform.Canonical
    
    /**
     * @author liangchen* @date 2020/11/19
     */
    
    @Canonical
    class Booking{
        String meetingRoom
        String className
        Date start, end
    }
    
    def book(meeting) {
        [room:{name ->
            [between:{ sd ->
                [and:{ed ->
                    [to:{to ->
                        def b = new Booking(meetingRoom:name, className: to,start: sd, end: ed)
                        println b
                        b
                    }]
                }]
            }]
        }]
    }
    
    def meeting
    
    class TimeCategory{
    
        static Date getAm(Integer self) {
            def d = Calendar.instance
            d.set(Calendar.MINUTE, 0)
            d.set(Calendar.SECOND, 0)
            d.set(Calendar.HOUR_OF_DAY, self)
            d.time
        }
    }
    
    use(TimeCategory){
        // 涉及一个固定流程,xml的dtd模板
        book meeting room 'Honolulu' between 9.am and 12.am to 'B2'
    }
    
    

5.1、@DelegatesTo

  • package com.jack.groovy.ch10
    
    /**
     * @author liangchen* @date 2020/11/19
     */
    // 10.45 使用@DelegateTo.Target, 自动识别类型,自动替换closure
    
    class Address{
        String country
    }
    
    class WishList{
        List<String> items
    }
    
    def validate(@DelegatesTo.Target def o, @DelegatesTo Closure rule) {
        rule.delegate = o
        rule()
    }
    
    void validateAll() {
        def a = new Address(country: 'Australia')
        validate(a) {
            if (country[0] == 'X') {
                println "No countries start with that"
            }
        }
        def wl = new WishList(items: ['iphone', 'iphone'])
        validate(wl) {
            if (items != items.toUnique()) {
                println 'Item appeared twice'
            }
        }
    
    }
    validateAll()
    

5.2、限制

6、总结

  1. 主要是静态语言的特性

本文链接: http://www.dtmao.cc/news_show_450149.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?