Kotlin 基础语法快速入门教程

amdecz51271 7年前
   <h2>为什么使用Kotlin</h2>    <p>项目一期在收尾了终于有时间折腾了,一个多月以来Kotlin从入门到现在,坚持用来开发的切身感受。因为语法与Java的区别挺大的一开始很想放弃,如果不是因为项目在使用,想必很少人会尝试这样一门小众语言,但是习惯后会发现这些年究竟浪费多少时间在写无用的Java代码了,Kotlin在兼容Java的基础上还能大大提升开发效率。Kotlin有许多特性但对于开发来说,快速适应和学习更为重要,很多时候我们都是在不明白其原因就开始使用的,正如我们不可能把Retrofit原理研究透才使用它。只要它足够稳定成熟,并能有效的提升开发效率都是值得尝试的。鄙人不才,目前使用Kotlin的原因主要是因为它语法简洁,支持lambda表达式,强大的when语法,不用写分号结尾,光是这些就足以让我喜欢Kotlin。至于空安全之类的特性,毕竟服务端数据类型太多null了并没多大感触,这些特性在实际应用中潜移默化的就吸收了,以至于现在遇到几个Java编写的代码,都有些不适应了。</p>    <h3>修改声明</h3>    <p>突然火了一脸懵逼,Google IO的影响真是不容小觑。避免误人子弟还是修改下比较好,也就把上一篇文章的基础知识也搬迁过来,移除过期链接。</p>    <h3>Kotlin 基本语法</h3>    <p>先说个学习Kotlin语法的小窍门,将代码用Java写好,然后 Code/Conver Java File to Kotlin File 转换成Kotlin代码,或者将Java代码复制到Kotlin文件会提示转换也是挺方便的,比较差异很容易就能理解了,一开始难免不适应习惯后相信你一定会喜欢上Kotlin</p>    <p>1). 定义</p>    <p>忘掉Java的那一套写法不然会很不适应的,Kotlin有自己的特性不该被Java的思维所束缚。在Kotlin中常量用 val 声明,变了用 var 声明,关键字在前面,类型以冒号 : 隔开在后面,也可以省略直接赋值,类型后带问号 ? 表示可为空类型(默认空安全)。</p>    <p>常量 val 延迟加载 by lazy{} ,默认线程安全关闭线程安全 lazy(LazyThreadSafetyMode.NONE){} ,变量 var 延迟加载 lateinit 。</p>    <pre>  <code class="language-kotlin">//常量数组int[][][] arrs = new int[3][2][1];  val arrs = Array(3) { Array(2) { IntArray(1) } }  //空安全变量  var str: String = "hello"  //可为空字符串变量  var str1: String? = null</code></pre>    <p>2). 条件</p>    <p>if...else 正常使用,不过移除了 switch 用更强大的 when 替代,when子式可以是各种返回Boolean的表达式</p>    <pre>  <code class="language-kotlin">val x = 7  when (x) {    in 1..10 -> print("x is in the range")    in validNumbers -> print("x is valid")    !in 10..20 -> print("x is outside the range")    else -> print("none of the above")  }</code></pre>    <p>3). 循环</p>    <p>while 和 do...while 同Java并无区别, for 则有很大改变并多出了几个变种</p>    <pre>  <code class="language-kotlin">val list = ArrayList<String>()  //递增for (int i = 0; i < list.size(); i++)  for (i in list.indices) {     print(list[i])  }  //递增for (int i = 2; i < list.size(); i++)  for (i in 2..list.size-1) {     print(list[i])  }  //递减for (int i = list.size(); i >= 0; i--)  for (i in list.size downTo 0) {      print(list[i])  }  //操作列表内的对象  for (item in list) {      print(item)  }  //加强版  for((i, item) in list.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{      override fun invoke(i: Int, s: String) {          print(list[i])          print(s)      }  })</code></pre>    <h3>万能的冒号</h3>    <p>在Kotlin中冒号 : 用万能来称呼绝不为过。常量变量的类型声明,函数的返回值,类的继承都需要它</p>    <pre>  <code class="language-kotlin">//val表示常量var表示变量声明  val name: String = "tutu"   //省略类型说明  var age = "23"  //fun表示函数  fun getName(): String{     return "tutu"  }  //类继承  class UserList<E>(): ArrayList<E>() {      //...  }</code></pre>    <p>除此之外还有一个特别的地方也需要它,使用Java类的时候。Kotlin最终会还是编译成Java字节码,使用到Java类是必然的,在Kotlin语法如下</p>    <pre>  <code class="language-kotlin">val intent = Intent(this, MainActivity::class.java)</code></pre>    <p>类名 ::class.java 没有为什么就这么写记着就是</p>    <h3>我是谁的@</h3>    <p>除了冒号另一个重要符号 @ ,想必用到内部类和匿名内部类的地方一定很多,再加上支持lambda语法,没有它谁告诉你 this 和 return 指的是哪一个</p>    <pre>  <code class="language-kotlin">class User {      inner class State{          fun getUser(): User{              //返回User              return this@User          }          fun getState(): State{              //返回State              return this@State          }      }  }</code></pre>    <h3>偷懒的方法</h3>    <p>1). Kotlin特色</p>    <p>Java的 getter/setter 方法自动转换成属性,对应到Kotlin属性的调用</p>    <pre>  <code class="language-kotlin">public class User {      private String name;      private String age;        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }        public String getAge() {          return age;      }        public void setAge(String age) {          this.age = age;      }  }</code></pre>    <p>这样一个Java类在Kotlin中只需这样调用</p>    <pre>  <code class="language-kotlin">val user = User()  //赋值  user.name = "tutu"  user.age = "23"  //取值  val name = user.name  val age = user.age</code></pre>    <p>反之Kotlin的属性自动生成Java的 getter/setter 方法,方便在Java中调用,同样的定义在Kotlin中</p>    <pre>  <code class="language-kotlin">class User {      var name: String? = null      var age: String? = null  }</code></pre>    <p>我们的 getter/setter 方法有时不会这么简单,这就需要自定义 getter/setter 了,另起一行设置get()/set(value)方法,实现一个Java中常用的单例,这里只为了展示,单例在Kotlin有更简单的方法实现,只要在 package 级别创建一个 object 即可</p>    <pre>  <code class="language-kotlin">class User {      companion object {          @Volatile var instance: User? = null              get() {                  if (field == null) {                      synchronized(User::class.java) {                          if (field == null)                              field = User()                      }                  }                  return field              }      }        var name: String? = null      var age: String? = null  }</code></pre>    <p>自定义 getter/setter 重点在 field ,跟我们熟悉所Java的 this 指代当前类一样, field 指代当前参数,直接使用参数名 instance 代替不会报错但单例就没效果了</p>    <p>2). 字符串模板</p>    <p>在Java中拼接字符串的代码可读性都很差,在Kotlin字符串拼接变得非常简洁,只需用 $ 后面加上参数名,复杂的参数要加上 {}</p>    <pre>  <code class="language-kotlin">val user = User()  //赋值  user.name = "tutu"  user.age = "23"  //取值  val name = user.name  val age = user.age  var userInfo = "name:${user.name},  age:$age"  //输出结果:name:tutu, age:23</code></pre>    <p>3). lambda</p>    <p>一开始觉得lambda很高级完全看不懂,其实很简单的就是把接口名、方法名和参数类型省掉不写再加个 -> 罢了,明白这点了就不介绍。</p>    <h3>新面孔</h3>    <p>1). 延迟加载</p>    <p>2). 流程控制</p>    <p>内容参考 <a href="/misc/goto?guid=4959748892051518425" rel="nofollow,noindex">Android Kotlin 学习笔记</a> ,不重复介绍</p>    <h3>空判断</h3>    <p>Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式一种像Java一样抛出空异常,字段后加 !! ,另一种不做处理直接跳过,字段后加 ?</p>    <pre>  <code class="language-kotlin">//类型后面加?表示可为空  var age: String? = "23"   //抛出空指针异常  val ageInt = age!!.toInt()  //不做处理跳过  val ages = age?.toInt()</code></pre>    <h3>注意事项</h3>    <p>内部类和参数默认为public,而在Java中为private</p>    <p>类默认为不可继承(final),想要可被继承要声明为 open 或 abstract</p>    <p>取消了static关键字,静态方法和参数统一写在 companion object 块</p>    <p>internal模块内可见,inner内部类</p>    <p>以上仅是对使用频率较高的语法总结,学会基本可以阅读Kotlin代码,遇到点问题Google速查一下,至于智能转换、类型推导之类的不用说使用后喜欢自然就会了。当然这只是kotlin的基本语法,方便Java快速熟悉kotlin,深入学习还请阅读相关资料。</p>    <p> </p>    <p>来自:http://www.linuxidc.com/Linux/2017-05/143960.htm</p>    <p> </p>