kotlin基础知识七: kotlin类型系统(type system)

一、为空性(Nullability)

Kotlin类型系统的为空性(Nullability)可能帮助你避免NullPointerException错误,比如"An error has occurred: java.lang.NullPointerException"或者"Unfortunately, the application X has stopped",现代语言(包括kotlin在内)的解决方法是把这些问题由运行时错误(runtime errors )转变为编译时错误(compile-time errors)。

1.1 可空类型(Nullable types)

Kotlin显式支持nullable types, 这是Kotlin与Java类型系统的第一个、可能也是最重要的不同点。Kotlin中的nullable类型和non-null类型是不同的。
举例:

fun strLen(s: String) = s.length

如果调用strLen(null)就会报错。

>>> strLen(null)
ERROR: Null can not be a value of a non-null type String
image.png

注意:nullable类型和non-null类型的对象在运行期是一样的,一个nullable类型并不是对non-null类型的wrapper,所有的checks都是在编译期执行的,因此在kotlin中使用nullable类型是没有运行期开销(runtime overhead)的。

1.2 Safe call 操作符: “?.”

表达式s?.toUpperCase()等价于if (s != null) s.toUpperCase() else null.


image.png

多个Safe call操作符的链式调用:

class Address(
    val streetAddress: String, val zipCode: Int,
    val city: String, val country: String
)

class Company(val name: String, val address: Address?)
class Person(val name: String, val company: Company?)

fun Person.countryName(): String {
    return company?.address?.country ?: "Unknown"
}

fun main(args: Array<String>) {
    val person = Person("Dmitry", null)
    println(person.countryName()) //null
}

1.3 Elvis操作符: “?:”

含义:为null提供一个默认值,它是Java中三元运算符的一个缩写。
举个例子:

fun strLenSafe(s: String?): Int = s?.length ?: 0

等价于Java的

int strLenSafe(String s) {
    return s != null ? s.length : 0;
}

也可以在Evlis操作符也可以与抛出异常结合使用。

class Address(val streetAddress: String, val zipCode: Int,
              val city: String, val country: String)
class Company(val name: String, val address: Address?)
class Person(val name: String, val company: Company?)
fun printShippingLabel(person: Person) {
    val address = person.company?.address
        ?: throw IllegalArgumentException("No address")
    with (address) {
        println(streetAddress)
        println("$zipCode $city, $country")
    }
}

fun main(args: Array<String>) {
    val jetbrains = Company("JetBrains", null)
    val person = Person("Dmitry", jetbrains)
    printShippingLabel(person)
}

输出:
Exception in thread "main" java.lang.IllegalArgumentException: No address

1.4 Safe casts操作符:“as?”

image.png

举例:
使用safe cast实现equals方法

class Person(val firstName:String, val lastName:String) {
    override fun equals(other: Any?): Boolean {
        val otherPerson = other as? Person ?: return false

        return otherPerson.firstName == firstName &&
                otherPerson.lastName == lastName
    }
}

1.5 Not-null assertions:“!!”

image.png

使用非空断言其实是告诉编译器:
“I know the value isn’t null, and I’m ready for an exception if it turns out I’m wrong.”

二、类型参数的为空性

2.1 处理可为空类型的参数

class MyService {
    fun performAction(): String = "foo"
}

fun <T> printHashCode(t: T) {
    println("type: " + t + ", hashCode: " + t.hashCode())
}

fun main(args: Array<String>) {
    val myService: MyService? = null
    printHashCode(myService) //"T" is inferred as "Any?".
}

输出结果:
type: null, hashCode: 0

2.2 处理非空类型的参数

class MyService {
    fun performAction(): String = "foo"
}

//“T” can’t be nullable.
fun <T : Any> printHashCode(t: T) {
    println(t.hashCode())
}

fun main(args: Array<String>) {
    val myService: MyService? = null
    printHashCode(myService) //compile-error: Type mismatch: inferred type is MyService? but TypeVariable(T) was expected
}

Any和Any?: the root types

Any是所有类型的父类型,包括原始类型(primitive type)在内。
注意Any是一个非空类型(non-nullable type),也就意味着它不能持有null,如果需要的话,需使用Any?。
举例:

val answer: Any = 42 //42会被自动装箱(automatically boxed), 因为Any是一个引用类型.

Unit: kotlin中的void

Nothing

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342