当前位置: 首页 > 科技观察

GroovyGrammarPromotion推广和Coercion强制转换学习

时间:2023-03-19 22:22:13 科技观察

1。引言本文是Groovy学习的第32篇,学习Groovy语法中提升和强制转换相关的知识点。(提升和强制)学习Groovy中各种数据类型的各种类型转换和类型转换。如果你不知道如何在Groovy中转换数据,你可以研究一下这篇文章的内容,应该能给你一些参考。2.提升和强制2.1数值转换整数提升:数值提升的规则在数学运算部分指定。[4.Groovy语法-Number和Boolean数据类型学习(zinyan.com)](https://img.ydisp.cn/news/20221229/h4dwdj2ffdidata-id="c7104f7d-RdRAN41R">bytecharshortintlongBigIntegerfloatdoubleBigDecimalbyteintintintintlongBigIntegerdoubledoubleBigDecimalcharintintintlongBigIntegerdoubledoubleBigDecimalshortintintlongBigIntegerdoubledoubleBigDecimalintintlongBigIntegerdoubledoubleBigDecimallonglongBigIntegerdoubledoubleBigDecimalBigIntegerBigIntegerdoubledoubleBigDecimalfloatdoubledoubledoubledoubledoubledoubleBigDecimalBigDecimal不同数值之间的Theimprovementis2.2闭包闭包类型转换在介绍闭包相关知识的时候,我们已经介绍了闭包中的各种转换,相关知识点可以通过:https://zinyan.com/?p=461,https://zinyan.com/?p=462,https://zinyan.com/?p=463了解一下。这里只是做一个简单的回顾和介绍。2.2.1SAM列表例如objects,the闭包转换SAM类型是一个类型that定义了一个抽象方法。比如我们创建一个接口:它的入参是一个T泛型。interfacePredicate{booleanaccept(Tobj)}一个只有一个抽象方法的抽象类:abstractclassZinyan{abstractStringgetName()voidhello(){println"Hello,$name"}}你可以使用as转换运算符任何闭包都被转换为SAM类型:Predicatefilter={it.contains'G'}asPredicateassertfilter.accept('Groovy')==trueGreetergreeter={'Groovy'}asGreetergreeter.hello()//输出:你好,Groovy从Groovy2.2.0开始,asType表达式是可选的。我们可以省略它,只写:Predicatefilter={it.contains'G'}assertfilter.accept('Groovy')==trueGreetergreeter={'Groovy'}greeter.hello()//output:Hello,GroovyPS:{it.contains'G'}上面是一个闭包对象,这意味着我们也可以使用方法指针,如下例所示:booleandoFilter(Strings){s.contains('G')}Predicatefilter=this.&doFilterassertfilter.accept('Groovy')==trueGreetergreeter=GroovySystem.&getVersiongreeter.hello()//Output:Hello,Groovy2.2.2callsmethodsthatacceptSAMtypeswithclosuresCloseSAMtypecoercion第二个可能更重要用例正在调用一个接受SAM类型的方法。想象一下下面的方法:publicListfilter(Listsource,Predicatepredicate){source.findAll{predicate.accept(it)}}然后,它可以在没有闭包的情况下调用创建接口的显式实现:assertfilter(['Java','Groovy'],{it.contains'G'}asPredicate)==['Groovy']从Groovy2.2.0开始,您还可以省略显式强制,并像使用闭包一样调用该方法:assertfilter(['Java','Groovy']){it.contains'G'}==['Groovy']这样做的好处是允许我们使用中的闭包语法,即将闭包放在括号外,提高了代码的可读性。2.2.3任意类型的强制闭包上面介绍了SAM单例对象的强制转换,这里介绍其他类型。除了SAM类型之外,闭包还可以强制转换为任何类型,尤其是特定接口。让我们定义以下接口:interfaceFooBar{intfoo()voidbar()}定义了一个接口对象,它有两个方法foo和bar。我们可以使用as关键字强制闭包进入接口:defimpl={println'ok';123}asFooBar这将生成一个所有方法都使用闭包实现的类:assertimpl.foo()==123impl.bar()//输出:好的,但您也可以对任何类强制闭包。例如,我们可以用class替换我们定义的接口,而不改变assert断言的结果:classFooBar{intfoo(){1}voidbar(){println'bar'}}defimpl={println'ok';123}asFooBarassertimpl.foo()==123impl.bar()PS:如果断言结果不满足,会产生新的错误,程序会停止。具有多种方法的类是不可行的。作为替代方案,Groovy允许将映射强制转换为接口或类。在这种情况下,Map的键被解释为方法名称,而值是方法实现。以下示例说明了将Map强制转换为迭代器:defmapmap=[i:10,hasNext:{map.i>0},next:{map.i--},]defiter=mapasIterator当然,这是一个相当人为的例子,但说明了这个概念。我们只需要实现那些实际被调用的方法,但是如果映射中不存在被调用的方法,则会抛出MissingMethodException或UnsupportedOperationException,具体取决于传递给调用的参数,如下例所示:interfaceX{voidf()voidg(intn)voidh(Strings,intn)}x=[f:{println"fcalled"}]asXx.f()//正常方法调用x.g()//MissingMethodExceptiontriggerx.g(5)//UnsupportedOperationException异常触发的异常类型取决于调用本身:MissingMethodException:如果调用的参数与接口/类中的参数不匹配,就会触发这个异常警告。UnsupportedOperationException:如果调用的参数与接口/类的重载方法之一匹配,将触发此异常警告。2.4将字符串强制转换为枚举Groovy允许对枚举值进行透明的字符串(或GString)强制转换。假设定义了以下枚举:enumState{up,down}那么您可以将字符串分配给枚举而无需使用显式强制转换:Statest='up'assertst==State.up您也可以使用GString作为Value:defval="up"Statest="${val}"assertst==State.up然而,这会抛出运行时错误(IllegalArgumentException):Statest='notanenumvalue'注意,也可以查到in在switch语句中使用隐式强制转换:StateswitchState(Statest){switch(st){case'up':returnState.down//显式赋值case'down':return'up'//隐式返回类型Mandatory}}特别地,看看case是如何使用字符串常量的。但是如果你调用一个使用带有String参数的枚举的方法,你仍然必须使用asas强制转换:assertswitchState('up'asState)==State.downassertswitchState(State.down)==State.up2。5自定义类型强制类可以通过实现asType方法来定义自定义强制策略。自定义强制转换是使用as运算符调用的,并且从不隐含。例如,假设您定义了两个类,Polar和Cartesian,如下例所示:一种方法是在Polar类中定义asType方法:defasType(Classtarget){if(Cartesian==target){returnnewCartesian(x:r*cos(phi),y:r*sin(phi))这允许使用as强制运算符:defsigma=1E-16defpolar=newPolar(r:1.0,phi:PI/2)defcartesian=polarasCartesianassertabs(cartesian.x-sigma)if(Cartesian==target){returnnewCartesian(x:r*cos(phi),y:r*sin(phi))}}PS:关键方法自定义类型转换为asType。实现asType方法,然后就可以自己定义各种类型的转换了。2.6Classtextvsvariablesandtheasoperatoras关键字只能在类有静态引用时使用,如下代码所示:interfaceGreeter{voidgreeter()}defgreeter={println'Hello,Groovy!'}asGreeter//Greeter是静态已知的greeter.greet()但是如果类是通过反射获得的,例如通过调用class.forName呢?Classclazz=Class.forName('Greeter')尝试使用as关键字来引用类将失败:greeter={println'Hello,Groovy!'}asclazz//throws://unabletoresolveclassclazz//@line9,column40.//greeter={println'Hello,Groovy!'}asclazz会出现异常错误,因为as关键字只对类文本有效。我们需要调用asType方法:greeter={println'Hello,Groovy!'}.asType(clazz)greeter.greet()3.总结至此,Groovy中关于强制类型提升的知识分享完毕。以上内容可以通过Groovy官网文档找到:[GroovyLanguageDocumentation(groovy-lang.org)](https://img.ydisp.cn/news/20221229/21uvlcp3rl0