Kotlin快速入门(3) -- 其他常用新特性

来源:互联网 发布:c语言 音乐函数 编辑:程序博客网 时间:2024/06/03 04:42

1.空值检查(空安全)

Kotlin 是空指针安全的,如果一个变量可能为空,必须在定义的时候显式地指定出来(在类型后面加上“?”)。

var a : String ? = "666"a = null //可以编译通过var b : String = "666"b = null //无法编译通过,因为这里没有显式指定b可以为空

Kotlin中还有一些涉及到空安全的操作符:
?. 如果不为空,则调用 例如:b?.length()如果b不为空,则返回b的长度,否则返回空
?: 如果为空,则…(Elvis 操作符) 例如:val l = b.length ?: -1 如果b.length为空,则返回-1,如果不为空则返回b.length
!! 这会返回一个非空的 b 或者抛出一个 b 为空的 NPE 例如: val l = b !!.length()
as? 空安全转型,普通的转换可能产生 ClassCastException 异常。另一个选择就是使用安全转换,如果不成功就返回空:val aInt: Int? = a as? Int

2.智能类型转换

在判断一个对象是否为一个类的实例的时候,可以使用is关键字,这与 Java 中的instanceof关键字类似。如果在前面某个变量已经使用is进行了判断,那么在后面的语句块中,该变量将会被自动转型,例如:

Kotlin:

fun getName(obj :Any) : String?{    if (obj is String){        //在这个语句块中,obj将会被自动转换成String类型,因此可以直接返回obj        return obj    }    return null}

而在Java中,则没有这么智能:

Java:

String getName(Object obj) {    if (obj instanceof String) {        return (String) obj;    }    return null;}

3.区间表达式(in..

区间表达式是通过 rangeTo 函数形成的。rangeTo 函数拥有形如 .. 的操作符,该操作符是用 in 和 !in 实现的。判断一个对象是否在在某一个区间内的时候可以使用in关键字,常常用于if或者for的条件,在for中使用前面已经讲了,下面就先来看if:

if:

fun rangesIf(a : Int){    //使用闭包进行数据的初始化    val ints : IntArray = IntArray(10,{i -> i})    //如果a在0到10之间,则打印"I am in"    if (a in 0..10){        println("I am in")    }    //如果a不在0到10之间,则打印"I am not in"    if (a !in 0..10){        println("I am not in")    }    //如果a在数组ints中,则打印"I am in"    if (a in ints){        println("I am in")    }}

此外,在for循环中,如果想从大的数字迭代到小的数字,也可以使用downTo函数。
for:

for (i in 4 downTo 1) {    println(i)}

结果是:

4321

这里还可以使用step指定一个步长,用于指定每个多少个单位迭代一次:

for (i in 1..4 step 2){    println(i)}

结果是:

13

4.单表达式函数

如果一个函数内部只包含一个ruturn语句,以后直接用单表式来表示,如:

fun getNum() : Int{    return 6}

等价于:

fun getNum() = 6

5.对象表达式

对象表达式的概念就类似于Java中的匿名内部类,主要用于我们想要创建一个对当前类有一点小修改的对象,但不想重新声明一个子类时。

通过object :创建:

window.addMouseListener(object: MouseAdapter () {    override fun mouseClicked(e: MouseEvent) {        //...    }})

有时候我们只是需要一个没有父类的对象,可以这样写:

val adHoc = object {    var x: Int = 0    var y: Int = 0}print(adHoc.x + adHoc.y)    

值得注意的是,Java中的匿名内部类只能访问被final修饰的外部变量(即不可变的变量),而Kotlin中却可以访问var修饰的变量(可变的变量)。
Java:

 int b = 6;window.addMouseListener(new MouseAdapter() {    @Override    public void mouseClicked(MouseEvent e) {        b++;//报错,匿名内部类中的变量是final的,不能自加    }});

Kotlin:

var b : Int = 6window.addMouseListener(object : MouseAdapter(){    override fun mouseClicked(e: MouseEvent?) {        b++    }})

6.对象声明

如果在 object后面添加了一个对象名,如 object Hello,这就表示一个对象声明
在声明的时候不能作为值赋给变量,不过声明完成后就可以赋值了:

//报错,不能在对象声明的时候同时赋值给变量var myObject = object HelloWorld {    fun sayHello(){        println("Hello world")    }}

下面这种写法则是正确的:

object HelloWorld {    fun sayHello(){        println("Hello world")    }}var myObject = HelloWorld

Kotlin中的单例模式就是用对象声明来构造的,不过这种单例其实是对应于Java中的最简单的单例–饿汉式
Java:

public class Singleton {    public static final Singleton INSTANCE = new Singleton();    private Singleton(){}    public static Singleton getINSTANCE() {        return INSTANCE;    }}

调用:Singleton.getINSTANCE().say();

Kotlin:

object Singleton {    fun say(){        println("Hello")    }}

调用:Singleton.say()

7.伴随对象

Kotlin中没有static关键字,因此如果想实现类似于Java中的静态方法类似的功能,就要借助伴随对象,伴随对象使用companion关键字标记对象声明,它里面的方法就类似于Java中的静态方法:

class MyClazz {    companion object Factory {        fun say(){            println("Hello")        }    }}

调用:MyClazz.say()

8.解构声明(Destructuring Declarations)

Kotlin可以通过解构声明将一个对象解构成多个变量。例如:

data class Person(val name : String ,val age : Int ,val sex : String)val (name, age, sex) = Person("Solinzon",21,"male")println("I am $name , a $age year-old and $sex man")

结果是:

I am Solinzon , a 21 year-old and male man

这样一来就可以省略我们单独去定义name , age , sex这三个变量的操作。

Kotlin中最经典的解构声明的例子就是遍历map的时候:

val map = mutableMapOf<Int,String>()for (i in 0..3) map.put(i,"I am element $i") //初始化一个mapfor ((key,value) in map){    println("$key -> $value")}

结果是:

0 -> I am element 01 -> I am element 12 -> I am element 23 -> I am element 3

9.相等

在Kotlin中的相等分为两种:参照相等(Referential equality)和 结构相等(Structural equality)
参照相等用===表示,它指的是两个等号两边的两个变量指向的是同一个对象。
结构相等用表示==,它指的是两个对象的内容一样。

val a = Person("Solinzon",21,"male")val b = Person("Solinzon",21,"male")println(a === b)//没有指向同一个对象,返回flaseprintln(a == b)//内容相等,返回true

结果是:

flasetrue
原创粉丝点击