分类目录归档:kotlin

kotlin类型检查和转换


is !is 表达式

我们可以在运行是通过上面俩个操作符检查一个对象是否是某个特定类:

if (obj is String) {
    print(obj.length)
}

if (obj !is String) { // same as !(obj is String)
    print("Not a String")
}
else {
    print(obj.length)
}

智能转换

在很多情形中,需要使用非明确的类型,因为编译器会跟踪 is 检查静态变量,并在需要的时候自动插入安全转换:

fun demo(x: Any) {
    if (x...

阅读全文...

kotlin This 表达式


为了记录下当前接受者,我们使用 this 表达式:

在类的成员中,this 表示当前类的对象

在扩展函数或扩展字面函数中,this 表示 . 左边接收者参数

如果 this 没有应用者,则指向的是最内层的闭合范围。为了在其它范围中返回 this ,需要使用标签

this使用范围

为了在范围外部(一个类,或者表达式函数,或者带标签的扩展字面函数)访问 this ,我们需要在使用 this@lable 作为 lable

class A { // implicit label @A
  inner class B { // implicit label @B
    fun Int.foo(...

阅读全文...

kotlin反射


反射是一系列语言和库的特性,允许在运行是获取你代码结构。 Kotlin 把函数和属性作为语言的头等类,而且反射它们和使用函数式编程或反应是编程风格很像。

类引用

最基本的反射特性就是得到运行时的类引用。要获取引用并使之成为静态类可以使用字面类语法:

val c = MyClass::class

引用是一种 KClass类型的值。你可以使用 KClass.propertiesKClass.extensionProperties 获取类和父类的所有属性引用的列表。

注意这与 java 类的引用是不一样的。

函数引用

当有一个像下面这样的函数声明时:

fun isOdd(x: Int)...

阅读全文...

kotlin Ranges


range 表达式是通过 rangeTo 函数形成的。rangeTo 函数拥有形如 .. 的操作符,该操作符是用 in 和 !in 实现的。 Range 可以对任何可比较的类型做操作,但对整数基本类型是优化过的。下面是些例子:

if (i in 1..10) {
    println(i)
}

if (x !in 1.0..3.0) println(x)

if (str in "island".."isle") println(str)

数字的范围有个附加的特性:它们可以迭代。编译器会把它转成类似于 java 的 for 循环的形式,且不用...

阅读全文...

Kotlin空安全


可空类型和非空类型

Kotlin 类型系统致力于消灭空引用。

在许多语言中都存在的一个大陷阱包括 java ,就是访问一个空引用的成员,结果会有空引用异常。在 java 中这就是 NullPointerException 或者叫 NPE

Kotlin 类型系统致力与消灭 NullPointerException 异常。唯一可能引起 NPE 异常的可能是:

明确调用 throw NullPointerException() 外部 java 代码引起 一些前后矛盾的初始化(在构造函数中没初始化的成员在其它地方使用)

在 Kotlin 类型系统中可以为空和不可为空的引用是不同的。比如,普通的...

阅读全文...

Kotlin运算符重载


Kotlin 允许我们实现一些我们自定义类型的运算符实现。这些运算符有固定的表示,和固定的优先级。为实现这样的运算符,我们提供了固定名字的数字函数和扩展函数,比如二元运算符的左值和一元运算符的参数类型。

转换

这里我们描述了一些常用运算符的重载

一元运算符

表达式 转换
+a a.plus()
-a a.minus()
!a a.not()

这张表解释了当编译器运行时,比如,表达式 +a ,是这样运行的:

决定 a 的类型,假设是 T 寻找接收者是 T 的无参函数 plus() ,比如数字函数或者扩展函数 如果这样的函数缺失或不明确,则返回错误。 如果函数是当前...

阅读全文...

kotlin多重声明


有时候可以通过给对象插入多个成员函数做区别是很方便的,比如:

val (name, age) = person

这种语法叫多重声明。多重声明一次创建了多个变量。我们声明了俩个新变量:name age 并且可以独立使用:

println(name)
println(age)

多重声明被编译成下面的代码:

val name = persion.component1()
val age = persion.component2()

component1() component2()是另一个转换原则的例子。任何类型都可以在多重分配的右边。当然了,也可以有 component3() comp...

阅读全文...

kotlin相等比较


在 kotlin 中有俩中相等:

参照相等(指向相同的对象) 结构相等

参照相等

参照相等是通过 === 操作符判断的(不等是!== ) a===b 只有 a b 指向同一个对象是判别才成立。

另外,你可以使用内联函数 identityEquals() 判断参照相等:

a.identityEquals(b)
a identityEquals b

结构相等

结构相等是通过 == 判断的。像 a == b 将会翻译成:

a?.equals(b) ?: b === null

如果 a 不是 null 则调用 equals(Any?) 函数,否则检查 b 是否参照等于 null

注意完全没...

阅读全文...

kotlin异常


异常类

所有的异常类都是 Exception 的子类。每个异常都有一个消息,栈踪迹和可选的原因。

使用 throw 表达式,抛出异常

throw MyException("Hi There!")

使用 try 捕获异常

try {
  // some code
}
catch (e: SomeException) {
  // handler
}
finally {
  // optional finally block
}

有可能有不止一个的 catch 块。finally 块可以省略。

try 是一个表达式

try 可以有返回值:

val a: Int? = ...

阅读全文...

kotlin动态类型


作为静态类型的语言,kotlin任然拥有与无类型或弱类型语言的调用,比如 javaScript。为了方便使用,dynamic应运而生:

val dyn: dynamic = ...

dynamic 类型关闭了 kotlin 的类型检查:

这样的类型可以分配任意变量或者在任意的地方作为参数传递 任何值都可以分配为dynamic 类型,或者作为参数传递给任何接受 dynamic 类型参数的函数 这样的类型不做 null 检查

dynamic 最奇特的特性就是可以在 dynamic 变量上调用任何属性或任何方法: (The most peculiar feature of dynamic ...

阅读全文...