Kotlin官方参考整理——05.其他
2017-06-29 22:15
369 查看
5.1 解构声明
见《03类和对象2.md》->“解构声明”5.2 集合
与大多数语言不同,Kotlin区分只读集合和可读写集合,这有助于消除bug和设计良好的API。只读 | 可读写 |
---|---|
List<out T> | MutableList<T> |
Set<out T> | MutableSet<T> |
Map<K, out V> | MutableMap<K, V> |
//只读集合 val list = listOf(1, 2, 3) //list的类型是List<out T>,即只支持读,不支持写。泛型被out修饰,因此List<out T>是一个可协变的类型 //list.add(4) //编译报错,不允许写操作 //可读写集合 val mutableList = mutableListOf(1, 2, 3) //mutableList的类型是MutableList<T>,支持读写。MutableList<T>不可协变也不可逆变 mutableList.add(4)
可读写集合是对应的只读集合的子类,因此可以将一个可读写集合的对象赋值给一个只读集合的引用:
val numbers: MutableList<Int> = mutableListOf(1, 2, 3) val readOnlyView: List<Int> = numbers//MutableList是List的子类,因此可以这样做 println(numbers) // 输出 "[1, 2, 3]" numbers.add(4) println(readOnlyView) // 输出 "[1, 2, 3, 4]" //readOnlyView.add(5) // 编译报错,不允许写操作
可以为可读写集合创建一个只读的副本:
val mutableList = mutableListOf<String>() val list = mutableList.toList()
集合的一些习惯用法
val items = listOf(1, 2, 3, 4) print(items.first()) print(items.last()) //filter接受一个函数为参数,函数类型为“(T) -> Boolean” //filter会将集合中的每一个元素分别传入该函数,如果函数返回true,则保留该元素 items.filter { it % 2 == 0 } // 返回 [2, 4] val rwList = mutableListOf(1, 2, 3) //返回集合中非null的元素,这里会返回[1, 2, 3] rwList.requireNoNulls() //rwList.none { it > 6 }:集合中是否没有大于6的元素 if (rwList.none { it > 6 }) println("No items above 6") //输出“No items above 6” //返回集合中的第一个元素,如果集合为空则返回null val item = rwList.firstOrNull() val readWriteMap = hashMapOf("foo" to 1, "bar" to 2) println(readWriteMap["foo"]) //输出“1”
5.3 区间
见《01开始.md》->“使用区间”5.4 类型的检查与转换
见《01开始.md》->“类型检测与转换”5.5 this表达式
在类的成员中,this指的是该类的当前对象在扩展函数或者带接收者的函数字面值中,this表示调用时位于“.”左侧的接收者对象
带标签的this表达式参考《03类和对象2.md》->“嵌套类、内部类、匿名内部类”
5.6 相等性
Kotlin中有两种类型的相等性:引用相等(两个引用指向同一对象则引用相等)
结构相等(也可称为值相等。调用equals(),如果返回true则结构相等)
引用相等由===(否定形式为!==)来判断。a===b当且仅当a和b指向同一个对象时为true。
结构相等由==(否定形式为!=)来判断。如果a不是null则调用equals函数,如果a是null则查看b是否为null。
当然了,==和===两端的操作数必须是同一类型,否则无法通过编译,提示类型不兼容。
5.7 操作符重载
类似于C++,Kotlin也支持操作符重载。重载操作符可以通过类的成员函数或扩展函数来进行。重载操作符的函数前面需要加上“operator”修饰符。操作符重载一般用得不多,详见官方参考。
5.8 空安全
见《01开始.md》->“空安全”5.9 异常
Kotlin中异常的使用方式与Java中基本一样,要注意的主要是以下几点:Kotlin中的所有异常都是非受检异常,没有受检异常
Java中的异常分为受检异常(Checked Exception)和非受检异常(Unchecked Exception)。
受检异常:必须被显式地捕获或者传递的异常。Java中大部分的异常都是受检异常。
非受检异常:无须被显式地捕获或者传递的异常。Java中的非受检异常只有一种,即RuntimeException及其子类。
Kotlin中的try…语句可以当做表达式使用
val a: Int? = try { parseInt(input) } catch (e: NumberFormatException) { null }
try…表达式的值是try块中的最后一个表达式的值或者是(所有)catch块中的最后一个表达式的值。finally块中的内容不会影响try…表达式的值。
在Kotlin中throw也可以当做表达式使用
val s = person.name ?: throw IllegalArgumentException("Name required")
throw表达式的类型是特殊类型Nothing。该类型没有值,而是用于标记永远不能达到的代码位置(即程序运行时永远到达不了需要用到该值地方)。你也可以使用Nothing来标记一个永远不会返回的函数:
fun fail(message: String): Nothing { throw IllegalArgumentException(message) } //注意:此处s的类型是非空类型,因为fail函数的类型是Nothing //如果person.name为空的话,那么会执行fail函数,而fail函数是永远不可能返回的,也就是说只要执行了fail函数,那么永远执行不到将等号右边表达式的值赋给s这一步 //因此,只要执行了将等号右边表达式的值赋给s这一步,说明person.name必然是非空的,那么s也就必然是非空的 val s = person.name ?: fail("Name required") println(s)
5.10 注解
定义注解的方式与Java中不同,详见官方参考。5.11 反射
官方参考讲的很简略,了解即可反射允许在运行时自省你的程序的结构。所谓自省即在运行时获悉一个名称、或属性、或函数的类型。
在使用反射之前,请确保已将kotlin-reflect.jar添加到了项目的classpath中。
5.11.1 类引用
类引用是KClass的实例。通过
类名或对象名::class可以获得Kotlin的类类型(即KClass)的实例
通过
类名或对象名::class.java可以获得Java的类类型(即Class)的实例
class SampleClass fun test() { //获得KClass的实例 val kotlinClass: KClass<SampleClass> = SampleClass::class kotlinClass.constructors//获取构造方法 KClass没有提供获取方法和属性的途径 ... //获得Class的实例 val javaClass: Class<SampleClass> = SampleClass::class.java javaClass.getConstructor()//获取构造方法 javaClass.getField()//获取属性 javaClass.getMethod()//获取成员方法 ... val sampleClass = SampleClass() sampleClass::class//获得KClass的实例 sampleClass::class.java//获得Class的实例 }
5.11.2 函数引用
函数引用是KFunction的实例。当我们有一个命名函数声明如下:
fun isOdd(x: Int) = x % 2 != 0
我们可以很容易地直接调用它,如isOdd(5);但是我们也可以通过“::”操作符来获取函数的引用,并将函数引用传递给另一个函数:
val numbers = listOf(1, 2, 3) //filter接受一个“(Int)->Boolean”类型的函数为参数 println(numbers.filter(::isOdd))
如果一个函数是类的成员函数或扩展函数,则“::”前必须加上类名或对象名作为限定:
class Haha { fun test() {} } fun test() { val method1 = Haha::test //通过类来获取方法引用 method1(Haha()) //调用时需要传入方法所属的类的对象 val method2 = Haha()::test //通过对象来获取方法引用 method2() //调用时无需传入方法所属的类的对象 }
5.11.3 属性引用
属性引用是KProperty(对于val)或KMutableProperty(对于var)的实例。KMutableProperty是KProperty的子类。通过“::”运算符来获取属性引用,获得属性引用之后,可以调用其getter和setter等方法。如果属性是类的成员,则::前要加上类名或对象名作为限定:
var m = 3 class AA { var x = 1 val y = 2 fun test() { /** * 通过类名获取成员变量的引用 */ //可读写成员变量 AA::x.get(this)//需要传入AA的对象,这里使用了this AA::x.set(this, 2) //只读成员变量 AA::y.get(this) //AA::y.set()//y是只读的,无此方法 /** * 通过对象名获取成员变量的引用 */ val aa = AA() aa::x.get() aa::x.set(2) aa::y.get() //aa::y.set() /** * 获取顶层变量的引用 */ ::m.get() ::m.set(1) } }
5.11.4 构造函数引用
构造函数可以像方法和属性那样引用。格式:::类名:
class Foo //接受一个无参并返回Foo类型对象的函数为参数 fun function(factory: () -> Foo) { val x: Foo = factory() } fun test(){ function(::Foo)//将Foo的构造函数传递给function函数 }
5.12 类型安全的构建器
了解,详见官方参考构建器可以让我们以非常简单明晰的格式来创建一段复杂的html代码字符串、xml代码字符串等。
fun result(args: Array<String>) = html { head { title { +"XML encoding with Kotlin" } } body { h1 { +"XML encoding with Kotlin" } p { +"this format can be used as an alternative markup to XML" } a(href = "http://kotlinlang.org") { +"Kotlin" } p { +"This is some" b { +"mixed" } +"text. For more see the" a(href = "http://kotlinlang.org") { +"Kotlin" } +"project" } p { +"some text" } p { for (arg in args) +arg } } }
这是完全合法的Kotlin代码。下面我们看看它的实现原理。
首先想想为什么我们可以在代码中这样写:
html { ... }
html实际上是一个函数调用,它接受一个lambda表达式作为参数。该函数定义如下:
//init需要通过一个HTML对象来调用,因此在init函数内部,可以直接调用HTML类中的函数,不需要任何前缀 fun html(init: HTML.() -> Unit): HTML { val html = HTML() html.init() return html }
这个函数接受一个名为init的函数为参数,该函数参数的类型是HTML.() -> Unit,它是一个带接收者的函数类型,这意味着我们需要通过一个HTML对象(即接收者)来调用init函数,并且我们可以在init函数内部直接调用接收者的成员:
html { //head和body是HTML的成员函数 head { ... } body { ... } }
5.13 类型别名
Kotlin通过typealias关键字来为一个已有类型起一个别名。//给集合类型起别名 typealias NodeSet = Set<Network.Node> typealias FileTable<K> = MutableMap<K, MutableList<File>> //给函数类型起别名 typealias MyHandler = (Int, String, Any) -> Unit typealias Predicate<T> = (T) -> Boolean //给嵌套类、内部类起别名 class A { class Nested inner class Inner } typealias ANested = A.Nested typealias AInner = A.Inner
相关文章推荐
- Kotlin官方参考整理——01.开始
- Kotlin官方参考整理——02.基础
- Kotlin官方参考整理——03.类和对象1
- Kotlin官方参考整理——03.类和对象2
- Kotlin官方参考整理——04.函数和lambda表达式
- Kotlin官方参考整理——06.Java互操作
- Spring Data JPA 指南——整理自官方参考文档
- 为Windows 7 Professional SP1添加任何官方语言包(其他语言可参考使用本教程)
- Linux 搭建简单的应用服务器(参考其他博客整理和自己实践)
- 多语言字符集和数据库(mysql)排序整理,其他数据库和网站等多语言环境也可参考
- Kotlin 官方参考文档 中文版_kotlin-reference-chinese.pdf
- 添加支持状态栏一键锁屏教程,可替代电源键(以泛泰A820L官方4.0rom为例,其他可参考)
- Python学习笔记整理(七)Python中的元组和文件及其他
- KOTLIN开发语言文档(官方文档) -- 入门
- Cloudera Manager 5升级(官方翻译整理,企业级实战验证)
- 参考TinyOS官方网站学习Mote-PC serial communication
- Spring 4.x官方参考文档中文版——第21章 Web MVC框架(10)
- EBS系统管理常用SQL语句整理汇总(参考网上资料&其他人博客)
- 【C#】【转】SharpSVN的官方使用方法参考
- C++知识要点整理05:常对象 常引用