标题 | 用Kotlin实现变量联动 |
范文 | 摘要:变量联动指的是一个变量发生变化,其他变量也会发生变化。用Kotlin可以在语言层面实现变量联动。 关键词:变量联动;Kotlin;Getter;Setter 中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2020)29-0214-03 1 背景 在编写程序的过程中,为了逻辑上的统一,经常需要一个变量的值发生变化,另一个变量的值也要产生变化,反之亦然。这两个变量就属于联动关系。 很多语言难以从语言层面实现这个功能,只能每次改变其中一个变量值的时候同时用代码改变另一个变量值,这样就显得很哕唆。而Kotlin作为现代语言,就可以在语言层面实现这个功能。 2 变量联动 编程时经常一个变量的值发生变化,另一个变量的值也要变化。比如有三个变量表达一个人的姓、名和姓名,当姓发生变化时,姓名也要发生变化: String xing,ming,xingming; xmg=”张”; xmgmmg=xing+ming; 如果更改过于频繁,可以把这两条语句提炼成一个方法,更改姓的时候同时更改姓名,然后在需要更改姓的时候调用这个方法就可以了。 然而更改名的时候也要更改姓名,那么就需要另一个方法在更改名的时候同时更改姓名。如果直接更改姓名,还需要一个方法在更改姓名的时候把姓名分割,然后更改姓和名两个变量。 这样就需要3个方法来实现变量联动,显得很烦琐。而Kotlin就可以很优雅地实现这个功能。 3 Kotlin简介 Kotlin由JetBrains公司开发,如今Kotlin已经支持Android开发,并提供了一系列的Android开发插件。它是一门静态语言,支持多种平台,包括移动端、服务端以及浏览器端,此外,Kotlin还是一门融合了面向对象与函数式编程的语言,支持泛型、安全的空判断,并且Kotlin与Java可以做到完全的交互。 4 Getter与Setter Kotlin可以通过Getter在读取变量时做出干预。如: var test:String=”” get0=”aaa” 其中get()就是Getter,读取test变量所得到的是这个方法的返回值。那么 fun main(args:Array test="123" print(test) ) 的结果是输出aaa,虽然test的真正值是123。 同樣,Kotlin可以通过Setter在给变量赋值时做出干预。如: var test:String2”” set(value){field=”aaa'} 其中set0就是Setter,value是被赋的值,field称为后备字段,它代表test真正的值。那么 fun main(args:Array test="123" print(test) ) 的结果是输出aaa,虽然感觉上test被赋值成123,但在Set-ter中field被赋值成aaa,那么test的值就是aaa。 Setter经常被用于预处理所赋的值,如表达分数的值不能是负数: var score=0 set(value){field= if(value <0)0 else value} fun main(args: Array score=8 print(score) score=-5 print(score) } 的结果是80,虽然score第二次被赋值成-5,但在set方法中由于value的值是-5,小于0,然后field被赋值成0,所以score的真正的值是0。 需要注意的是在Getter与Setter中必须用field,不能用变量名,否则会陷入死循环。另外因为val修饰的变量是只读变量,所以val变量不能有Setter。 5 用Getter或Setter实现简单的变量联动 如果要让变量a2是变量a的两倍,可以用如下代码实现: classtf var a=0 var a2=0 getO=a*2 ) fun main(args: Array var x=t0 x.a=4 print(x.a2) ) 会输出8,保证了a2是a的二倍。但如果给a2赋值,a的值却不会自动变成a2的一半。 也可以用Setter处理这个问题,代码如下: classtf var a=0 set(value){ field=value a2=a*2 ) var a2=0 ) 同样,如果给a2赋值,a的值不会自动变成a2的一半。 6 用Setter实现姓名变量联动 对姓名问题而言,可以这样写xmg和nung的Setter: class xmf var xing:String=”” set(value){ field=value xingming=value+ming ) var ming:String= " " set(value) [ field=value xingming=xing+value ) var xingming:String=”” ) fun main(args: Array var x=xm0 x.xing=”张 x.rmng=”強” print(x.xingming) ) 输出的结果是张强,虽然没有明确给xmgming赋值,但在xing和rmng的Setter中却给xingming赋值了,这样就保证了3个变量的逻辑上的一致性。 对于xmgmmg的Setter,稍显复杂,因为它要给xmg和mmg两个变量赋值: var xingming:String= set(value) { field=value xing=value.substring(0,1) ming=value.substring(l,value.length) ) 这样的话 fun main(args: Array var x=xm() x.xingming=”张强” print(x.xing+”一一”+x.ming) ) 的结果就是张一强,把xing和mmg分开了。 需要注意的是,xingming的Setter不能和xing或ming的Set-ter -同出现,因为在xingming的Setter中会修改xing/ming,从而调用xing/ming的Setter,而xing/ming的Setter中会修改xing-rmng,从而调用xmgming的Setter,这样就会陷入死循环。 所以这不是一个完美的方案。 7 用Getter实现姓名变量联动 对姓名问题而言,可以这样写xmgming的Getter: class xmf var xing:String=" var ming:String=“” var xingming:String=”” getO=xing+ming ) 这样 fun main(args: Array var x=xm0 x.xmg=”张” x.ming=”强” print(x.xingming) ) 的结果是张强,实现了变量联动。 xing和rmng的Getter可以这样写: class xmf var xing:String=”” getO=xingming.substring(0,1) var ming:String=”” getO=xingming.substring(l,xingming.length) var xingming:String=”” ) fun main(args: Array var x=xm() x.xlrWnmg=”张强” print(x.xing+”一一”+x.ming) ) 结果是张一强,把xing和rmng分开了。 但需要注意的是,和Setter -样,xingming的Getter不能和xmg或rmng的Getter -同出现,理由也类似:会造成死循环。 8 混用Getter和Setter实现姓名变量联动 单纯用Getter或Setter都无法完美实现姓名变量联动,混用却可以实现: class xmf var xing:String=… var ming:String=”” var xingming:String=" getO=xing+ming set(value){ field=value xing=value.substring(0,1) ming=value.substring(l,value.length) ) ) 通过只使用xmgrmng的Getter和Setter就可以完美实现姓名变量的联动。 fun main(args: Array var x=xmQ x.xmgrning=”张强” print(x.xing+”一一”+x.ming) x.xmg=”王” print(x.xingming) } 会输出张一一强一王强。 另一种方法是使用xmg和ming的Getter和Setter实现姓名变量的联动,原理类似,但更加复杂。 9 并联电阻的电压电流问题 电压、电流、电阻之间也有联动关系,具体地说是电压=电流×电阻。假设现在有两个电阻并联,需要解决的是两个电阻值和总电流、总电压的关系。这里假设电流不可主动赋值。 用Setter解决问题的代码如下: var U:Double=0.0 set(v){field=v;I=U/R1+U/R2) var Rl:Double=l.0 set(v){field=v;I=U/R1+U/R2) var R2:Double=l.0 set(v){field=v;I=U/R1+U/R2) var I:Double=0.0 可以看出无论改变R1、R2、U中的哪一个,都会重新计算电流的值。 fun main(args:Array U=4.0 R1=2.0 R2=1.0 print(I.toString0+”一一”) U=6.0 print(l) ) 的结果是6.0-9.0,解决了变量联动问题。 用Getter解决问题的代码如下: var U:Double=0.0 var Rl:Double=0.0 var R2:Double=0.0 val R:Double getO=U/I val Il:Double getO=U/R1 val I2:Double getO=U/R2 val I:Double get0=11+12 可以看出,Getter方式可以求出更多的东西:RI的电流II、R2的电流12以及总电阻R,如果用Setter方式求这些,则要多出很多代码。 10 结束语 用Kotlin的Getter和Setter可以优雅地解决变量联动问题,在实战的时候需要注意变量的Getter和Setter的死循环问题,另外在绝大多数场合,Getter比Setter更加方便。 参考文献: [1]水滴技术团队.Kotlin核心编程[M].北京:机械工业出版社,2019. [2]封亚飞.揭秘Kotlin编程原理[M].北京:电子工业出版社,2018. [3] Saumont P-Y.Kotlin编程之美.機械工业出版社[M].北京:机械工业出版社,2020. 【通联编辑:谢媛媛】 作者简介:刘华煜(1976-),男,讲师,硕士,研究方向为计算机应用。 |
随便看 |
|
科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。