kotlin入门笔记

来源:互联网 发布:淘宝运营 策划能力 编辑:程序博客网 时间:2024/06/18 02:53

为什么使用Kotlin

        网上关于kotlin的讨论已经热了一个多月了,究竟怎么看待这门语言在Android开发中的应用前景,我觉得还是要留给时间去验证。“我思故我在”,自己的思考在学习的过程中非常重要,尤其是面对新事物。下面说说我的看法,以它主要的优势入手:
        Kotlin是门类型安全语言,但同时保持了类型推测,会自动根据常量或变量的具体数字来推测相关的类型,从而大大避免了Java、C等语言繁琐的类型声明,让代码变得异常简洁明了,看起来很像JavaScript。就好比原来大家用过的“万能充”的充电器,不管你的手机电池是什么尺寸或者品牌,只要你的额定电压与电流在安全范围内,都能实现充满电的需求。这很显然大大提高了编程的效率。

Kotlin基本语法

       Kotlin有哪些新式的使用方法和语法呢?英语好的同学可以下载Kotlin英文文档,英语一般的同学直接看中文版的也可以,kotlin-中文免费文档下载地址。
       下面开始简单介绍:

1、函数的使用

定义函数使用fun关键字,如下代码所示:
fun add(a: Int, b: Int): Int {      return a + b  }  
函数add有两个Int型的参数,冒号后跟的是函数的返回值,一条代码语句的末尾不用加分号,当然加上分号也没有问题。
上面的add函数还可以简写成如下形式:
fun add(a: Int, b: Int) = a + b;  
没有显式指定函数的返回值,会自动推断函数的返回值。
如果一个函数没有返回值,可以写成如下两种形式:
//没有返回值的函数,显式指定Unit为返回值  fun showAddResult(a: Int, b: Int): Unit {      println(a + b)  }    //没有返回值的函数,省略Unit的写法  fun showAddResult2(a: Int, b: Int) {      println(a + b)  }  

2、常量和变量

使用val关键字声明一个常量(只读,不可修改),使用var关键字声明一个变量,下面是具体用法:
fun test() {      //使用val关键字声明一个常量(只读),声明常量时必须初始化      val a: Int = 1 //显式指定常量的类型      val b = 2  //自动推断类型      val c: Int //声明一个不初始化的常量,必须显式指定类型  //    b = 3  //常量值不可修改,这句代码会报错        //a = 3  //不可以修改常量的值,此句代码会报错        //使用var关键字声明一个变量,变量的值可以修改      var year: Int = 2016 //显式指定变量的类型      var month = 5 //自动推断变量类型      var day: Int //声明一个不初始化的变量,必须显式指定类型      month = 6 //变量值可以被修改  }  


3、注释

Kotlin中的注释和Java中类似,但是唯一不同之处是Kotlin中的注释可以嵌套。如下所示:
fun comments() {  //    注释一行代码  //    var s = "hello world"      /*注释一段代码      var a = 8      a++      a--*/  }  


4、字符串模板

“${}”是一个变量的占位符,“${xxx}”相当于一个文本的模板,在Kotlin中叫字符串模板,它会直接把xxx插入到文本中。
//main方法是整个程序的入口  fun main(args: Array<String>){      var run = 5    run = 6    print("每天跑${run}公里")}  
上面的代码执行后,在控制台打印如下内容:每天跑6公里

5、条件表达式

常规的条件表达式可以是这么写的:
//常规写法的条件表达式,这里的函数返回值不能省略  fun max(a: Int, b: Int): Int {      if(a > b)          return a      else          return b  }  
Kotlin可以简写条件表达式,如下所示:
//简写的条件表达式  fun max2(a: Int, b: Int) = if(a > b) a else b  

6、可空类型(nullable)

就是指所有“实体的”类型与空的组合,写法是在源类型后面紧跟一个问号;Int?、String?、Boolean?等,这里的“?”指空值null,表示什么都没有。比如一些会员账号的注册会有必填项和选填项,可空类型就是指这种可选填字段的情况。
var addr : String? = "北京大学"var sex : Boolean?
函数返回值为可空的例子如下代码:
/*  函数返回值为Int?,表示返回值可为空  当参数为空或者为""时,则返回null,否则使用Java中的字符串转整型的方法  这里也体现了kotlin代码和Java代码无缝集成   */  fun parseInt(s: String): Int? {      if(s == null || s == "")          return null;      return Integer.parseInt(s);  }  

7、类型检查和自动类型转换

Kotlin中使用is运算符来检查数据类型和做类型转换,如下代码所示:
/*  当函数参数为字符串类型时,就返回字符串的长度,否则返回空   */  fun getStringLength(n: Any): Int? {      if(n is String)          return n.length //这里会自动将n转化为字符串类型      return null  }  

上面的代码还可以写成:
/*  当函数参数为字符串类型时,就返回字符串的长度,否则返回空   */  fun getStringLength(n: Any): Int? {      if(n !is String)          return null      return n.length //这里会自动将n转化为字符串类型  }  

8、for循环和while循环

whiledo...while 同Java并无区别,但是要注意for的使用。
//for循环的测试代码  fun testFor() {      var arr = arrayOf(1, 3, 4, 5, 6)      for(i in arr.indices) { //通过索引循环          println(arr[i])      }      for(num in arr) { //直接使用数组中的对象循环          println(num)      }  }    //while循环的测试代码  fun testWhile() {      var i = 0;      while(i < 10) {          print(" " + i)          i++      }  }


9、条件表达式

if...else 正常使用,不过移除了switch用更强大的when替代,when子式可以是常量、变量、返回数值的表达式、返回Boolean值的表达式,强大到用来替换if...else if。如下代码所示:
fun main(args: Array<String>) {      testCase("hello world")  }    fun testCase(obj: Any) {      when(obj) {          is String -> {              print("this is string")          }          is Int -> {              print("this is integer")          }          //代替if...else if...        else -> {              print("unkown value")          }      }  }  


10、ranges的使用


(1)使用in操作符检查一个数是否在某个范围内
/*  判断分数是否大于等于90,小于等于100   */  fun isGood(score: Int) {      if(score in 90..100) //ranges是闭区间          println("very good")      else          println("not so good")  }  

(2)检查索引是否越界
/*  检查index是否在数组arr的索引范围内   */  fun checkIndex(index: Int, arr: Array<Int>) {      if(index in 0..arr.lastIndex) //arr.lastIndex返回的是数组的最后一位的下标          println("index in bounds")      else          println("index out of bounds")  } 

(3)遍历一个范围
for(i in 1..5) {      println(i)  }  
也可以通过in运算符遍历一个集合,如下代码:
//in运算符遍历一个字符串数组  fun testStr(arr: Array<String>) {      for(str in arr)          println(str)  } 


11、万能的冒号


在Kotlin中冒号:用万能来称呼绝不为过。常量变量的类型声明,函数的返回值,类的继承都需要它。
//val表示常量var表示变量声明val name: String = "tutu" //省略类型说明var age = "23"//fun表示函数fun getName(): String{   return "tutu"}//类继承class UserList<E>(): ArrayList<E>() {    //...}
除此之外还有一个特别的地方也需要它,使用Java类的时候。Kotlin最终会还是编译成Java字节码,使用到Java类是必然的,在Kotlin语法如下:
val intent = Intent(this, MainActivity::class.java)
类名::class.java没有为什么就这么写,记着就是。

12、我是谁的@


除了冒号另一个重要符号@,想必用到内部类和匿名内部类的地方一定很多,再加上支持lambda语法,没有它谁告诉你thisreturn指的是哪一个。
class User {    inner class State{        fun getUser(): User{            //返回User            return this@User        }        fun getState(): State{            //返回State            return this@State        }    }}

13、Java的getter/setter方法


Java的getter/setter方法自动转换成属性,对应到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;    }}
反之Kotlin的属性自动生成Java的getter/setter方法,方便在Java中调用,同样的定义在Kotlin中可以偷懒写成如下格式:
class User {    var name: String? = null    var age: String? = null}
这样一个Java类在Kotlin中只需这样调用
val user = User()//赋值user.name = "tutu"user.age = "23"//取值val name = user.nameval age = user.age
我们的getter/setter方法有时不会这么简单,这就需要自定义getter/setter了,另起一行设置get()/set(value)方法,实现一个Java中常用的单例,这里只为了展示,单例在Kotlin有更简单的方法实现,只要在 package 级别创建一个 object即可
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}

自定义getter/setter重点在field,跟我们熟悉所Java的this指代当前类一样,field指代当前参数,直接使用参数名instance代替不会报错但单例就没效果了。

14、. lambda


一开始觉得lambda很高级完全看不懂,其实很简单的就是把接口名、方法名和参数类型省掉不写再加个->罢了,明白这点了很好理解。

// 无参数无返回值Thread(Runnable {    sleep(1000)}).start()// 单参数不带返回值view.setOnClickListener { v ->    Log.e("tag", "${v.tag}")}// 多参数带返回值view.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->    Log.e("tag", "keyCode$keyCode, ${event.keyCode}")    if (event.keyCode == KeyEvent.KEYCODE_BACK)        return@OnKeyListener true    false})


原创粉丝点击