1.关键字as用法
使用关键字as来修饰导入的类或者函数名称,避免类或函数名重复,其是解决命名冲突问题的唯一方式。
- 使用
as关键字
import strings.lastChar as last
val c = "Kotlin".last()
- 不使用
as关键字
import strings.lastChar
val c = "Kotlin".lastChar()
2.扩展函数
扩展函数是静态函数,它把调用对象作为它的第一个参数。调用扩展函数,不会创建适配的对象或者任何运行时的额外消耗。
扩展函数的静态性质也决定了扩展函数不能被子类重写。
- 重写成员函数
//定义
open class View {
open fun click() = println("View clicked")
}
class Button: View() {
override fun click() = println("Button clicked")
}
//执行
>>> val view: View = Button()
>>> view.click() //具体调用哪个方法,由实际的view的值决定
Button clicked
- 不可重写扩展函数
//定义
fun View.showOff() = println("I'm a view!")
fun Button.showOff() = println("I'm a button!")
//执行
>>> val view: View = Button()
>>> view.showOff()
I'm a view!
如果一个类的成员函数和扩展函数有相同的签名,成员函数往往会被优先使用。
牢记:当在扩展API类的时候:如果添加一个和扩展函数同名的成员函数,那么对应类定义的消费者将会重新编译代码,这将会改变它的意义并开始指向新的成员函数
3.扩展属性
扩展属性提供了一种方法,用来扩展类的API,可以用来访问属性,用的是属性语法而不是函数的语法。
尽管它们被称为属性,但它们可以没有任何状态,因为没有合适的地方来存储它,不可能给现有的Java对象的实例添加额外的字段。
- 示例1
val String.lastChar: Char
get() = get(length - 1)
- 示例2
var StringBuilder.lastChar: Char
get() = get(length - 1)
set(val: Char) {
this.setCharAt(length - 1, val)
}
注意: 在Java中访问扩展属性的时候,应该显示地调用它的getter函数和setter函数:
/* 使用getLastChar时会出现两个方法
* getLastChar(String s) 与 getLastChar(StringBuilder sb)
* /
getLastChar("Kotlin!")
/* 使用setLastChar方法,具体方法参数如下
* setLastChar(StringBuilder sb, char val)
* /
setLastChar("Kotlin?", '!')
4.可变参数
当你在调用一个函数来创建列表的时候,可以传递任何个数的参数给它:
//定义
val list = listOf(2, 3 ,5, 7, 11)
//对应底层源码
fun listOf<T>(vararg values: T): List<T> =
if (elements.size > 0) elements.asList()
else emptyList()
关键字vararg:把任何个数的参数值打包到数组中传给函数。
Kotlin与Java之间的另一个区别是,当需要传递的参数已经包装在数组中时,调用该函数的语法:在Java中,可以按原样传递数组,而Kotlin则要求显式地解包数组,以便每个数组元素在函数中能作为单独的参数来调用。
从技术的角度来讲,这个功能被称为展开运算符,而使用的时候,不过是在对应的参数前面放一个 *
// 定义
val list: Array<String> = arrayOf("two","three","four")
val newList = listOf("one",*list);
//对应数据
list: ["two","three","four"]
newList: ["one", "two","three","four"]
5.键值对处理:中缀调用与解析声明
可以使用mapOf函数来创建map
val map = mapOf(1 to "one", 7 to "senven", 53 to "fifty-three")
上述代码中的单词to不是内置的结构,而是一种特殊的函数调用,被称为中缀调用。
中缀调用可以与只有一个参数的函数一起使用,无论是普通的函数还是扩展函数。要允许使用中缀符号调用函数,需要使用infix修饰符来标记它。
- 简单的
to函数的声明:
infix fun Any.to(other: Any) = Pair(this, other)
to函数会返回一个Pair类型的对象,Pair是Kotlin标准款中的类,用来表示一对元素。Pair和to的声明都使用泛型。
直接用Pair的内容来初始化两个变量,这个功能称为解析声明。
val (number, name) = 1 to "one"
解析声明特征用法:
- pair
- 使用map的key和value内容来初始化两个变量
- 适用于循环
for((index, element) in collection.withIndex()) {
println("$index: $element")
}