Kotlin 编程三分钟入门
为什么使用Kotlin
项目一期在收尾了终于有时间折腾了,一个多月以来Kotlin从入门到现在,坚持用来开发的切身感受。因为语法与Java的区别挺大的一开始很想放弃,如果不是因为项目在使用,想必很少人会尝试这样一门小众语言,但是习惯后会发现这些年究竟浪费多少时间在写无用的Java代码了,Kotlin在兼容Java的基础上还能大大提升开发效率。Kotlin有许多特性但对于开发来说,快速适应和学习更为重要,很多时候我们都是在不明白其原因就开始使用的,正如我们不可能把Retrofit原理研究透才使用它。只要它足够稳定成熟,并能有效的提升开发效率都是值得尝试的。鄙人不才,目前使用Kotlin的原因主要是因为它语法简洁,支持lambda表达式,强大的when语法,不用写分号结尾,光是这些就足以让我喜欢Kotlin。至于空安全之类的特性,毕竟服务端数据类型太多null了并没多大感触,这些特性在实际应用中潜移默化的就吸收了,以至于现在遇到几个Java编写的代码,都有些不适应了。
修改说明
突然火了一脸懵逼,GoogleIO的影响真是不容小觑。避免误人子弟还是修改下比较好,也就把上一篇文章的基础知识也搬迁过来,移除过期链接。
Kotlin基本语法
先说个学习Kotlin语法的小窍门,将代码用Java写好,然后Code/ConverJavaFiletoKotlinFile转换成Kotlin代码,或者将Java代码复制到Kotlin文件会提示转换也是挺方便的,比较差异很容易就能理解了,一开始难免不适应习惯后相信你一定会喜欢上Kotlin
1).定义
忘掉Java的那一套写法不然会很不适应的,Kotlin有自己的特性不该被Java的思维所束缚。在Kotlin中常量用val声明,变了用var声明,关键字在前面,类型以冒号:隔开在后面,也可以省略直接赋值,类型后带问号?表示可为空类型(默认空安全)。
常量val延迟加载bylazy{},默认线程安全关闭线程安全lazy(LazyThreadSafetyMode.NONE){},变量var延迟加载lateinit。
//常量数组int[][][]arrs=newint[3][2][1]; valarrs=Array(3){Array(2){IntArray(1)}} //空安全变量 varstr:String="hello" //可为空字符串变量 varstr1:String?=null
2).条件
if...else正常使用,不过移除了switch用更强大的when替代,when子式可以是各种返回Boolean的表达式
valx=7 when(x){ in1..10->print("xisintherange") invalidNumbers->print("xisvalid") !in10..20->print("xisoutsidetherange") else->print("noneoftheabove") }
3).循环
while和do...while同Java并无区别,for则有很大改变并多出了几个变种
vallist=ArrayList() //递增for(inti=0;i =0;i--) for(iinlist.sizedownTo0){ print(list[i]) } //操作列表内的对象 for(iteminlist){ print(item) } //加强版 for((i,item)inlist.witnIndex()){ print(list[i]) print(item) } //变种版 list.forEach{ print(it) } list.forEach{ print(it) } list.forEachIndexed{i,s-> print(list[i]) print(s) } list.forEachIndexed(object:(Int,String)->Unit{ overridefuninvoke(i:Int,s:String){ print(list[i]) print(s) } })
万能的冒号
在Kotlin中冒号:用万能来称呼绝不为过。常量变量的类型声明,函数的返回值,类的继承都需要它
//val表示常量var表示变量声明 valname:String="tutu" //省略类型说明 varage="23" //fun表示函数 fungetName():String{ return"tutu" } //类继承 classUserList():ArrayList (){ //... }
除此之外还有一个特别的地方也需要它,使用Java类的时候。Kotlin最终会还是编译成Java字节码,使用到Java类是必然的,在Kotlin语法如下
valintent=Intent(this,MainActivity::class.java)
类名::class.java没有为什么就这么写记着就是
我是谁的@
除了冒号另一个重要符号@,想必用到内部类和匿名内部类的地方一定很多,再加上支持lambda语法,没有它谁告诉你this和return指的是哪一个
classUser{ innerclassState{ fungetUser():User{ //返回User returnthis@User } fungetState():State{ //返回State returnthis@State } } }
偷懒的方法
1).Kotlin特色
Java的getter/setter方法自动转换成属性,对应到Kotlin属性的调用
publicclassUser{ privateStringname; privateStringage; publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicStringgetAge(){ returnage; } publicvoidsetAge(Stringage){ this.age=age; } }
这样一个Java类在Kotlin中只需这样调用
valuser=User() //赋值 user.name="tutu" user.age="23" //取值 valname=user.name valage=user.age
反之Kotlin的属性自动生成Java的getter/setter方法,方便在Java中调用,同样的定义在Kotlin中
classUser{ varname:String?=null varage:String?=null }
我们的getter/setter方法有时不会这么简单,这就需要自定义getter/setter了,另起一行设置get()/set(value)方法,实现一个Java中常用的单例,这里只为了展示,单例在Kotlin有更简单的方法实现,只要在package级别创建一个object即可
classUser{ companionobject{ @Volatilevarinstance:User?=null get(){ if(field==null){ synchronized(User::class.java){ if(field==null) field=User() } } returnfield } } varname:String?=null varage:String?=null }
自定义getter/setter重点在field,跟我们熟悉所Java的this指代当前类一样,field指代当前参数,直接使用参数名instance代替不会报错但单例就没效果了
2).字符串模板
在Java中拼接字符串的代码可读性都很差,在Kotlin字符串拼接变得非常简洁,只需用$后面加上参数名,复杂的参数要加上{}
valuser=User() //赋值 user.name="tutu" user.age="23" //取值 valname=user.name valage=user.age varuserInfo="name:${user.name},age:$age" //输出结果:name:tutu,age:23
3).lambda
一开始觉得lambda很高级完全看不懂,其实很简单的就是把接口名、方法名和参数类型省掉不写再加个->罢了,明白这点了就不介绍。
新面孔
1).延迟加载
2).流程控制
空判断
Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式一种像Java一样抛出空异常,字段后加!!,另一种不做处理直接跳过,字段后加?
//类型后面加?表示可为空 varage:String?="23" //抛出空指针异常 valageInt=age!!.toInt() //不做处理跳过 valages=age?.toInt()
注意事项
内部类和参数默认为public,而在Java中为private
类默认为不可继承(final),想要可被继承要声明为open或abstract
取消了static关键字,静态方法和参数统一写在companionobject块
internal模块内可见,inner内部类
以上仅是对使用频率较高的语法总结,学会基本可以阅读Kotlin代码,遇到点问题Google速查一下,至于智能转换、类型推导之类的不用说使用后喜欢自然就会了。当然这只是kotlin的基本语法,方便Java快速熟悉kotlin,深入学习还请阅读相关资料。