阅读 102

Kotlin基础知识二——扩展功能

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")
}
复制代码
文章分类
Android
文章标签