Kotlin官方参考整理——05.其他
来源:互联网 发布:企业协同办公软件 编辑:程序博客网 时间:2024/06/05 11:38
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>
以List集合为例:
//只读集合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”//返回集合中的第一个元素,如果集合为空则返回nullval 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 SampleClassfun 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 = 3class 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) -> Unittypealias Predicate<T> = (T) -> Boolean//给嵌套类、内部类起别名class A { class Nested inner class Inner}typealias ANested = A.Nestedtypealias AInner = A.Inner
- Kotlin官方参考整理——05.其他
- Kotlin官方参考整理——01.开始
- Kotlin官方参考整理——02.基础
- Kotlin官方参考整理——06.Java互操作
- Kotlin官方参考整理——03.类和对象1
- Kotlin官方参考整理——03.类和对象2
- Kotlin官方参考整理——04.函数和lambda表达式
- kotlin习惯用法——kotlin官方文档学习
- Kotlin官方文档翻译—概述
- Spring Data JPA 指南——整理自官方参考文档
- Kotlin 官方参考文档 中文版_kotlin-reference-chinese.pdf
- Kotlin-其他
- Kotlin官方文档翻译—《Functions and Lambdas-Functions》
- IOS基础控件学习—参考其他博客
- django官方文档——模型字段关系参考
- prestodb安装配置 —参考prestodb官方文档配置
- Kotlin语法(其他)
- Android官方语言:Kotlin
- [编程题] 下厨房
- 线程清理函数
- 全面解析Linux 内核 3.10.x
- Jetty8——实现Servlet 3 注解
- 在jsp中如何引入css的三种方法
- Kotlin官方参考整理——05.其他
- (六)MySQL 基础(练习二)
- 鼠标经过图片 图片自动变大
- Java高级特性之反射学习总结
- ASCII码排序(南阳理工OJ)
- js 分页列表组件
- Kotlin官方参考整理——06.Java互操作
- 【maven】创建简单的maven项目
- Unity3d 触屏手机滑动事件(上下左右方向精确判断)