目录

Kotlin基础 密封类,扩展函数,运算符重载

延迟初始化

由于Kotlin中严格判空机制. 对于一些全局变量声明为 ? 可空类型, 先赋值null. 然后再合适的时机再进行创建赋值, 这个时候又需要判断非空. 由于这些零碎的步骤, lateinit关键字就为此而生.

延迟初始化lateinit , 它可以让编译器再晚些时候进行赋值, 而不需要在声明的时候就必需赋值为null

private lateinit var adapter: RecyclerAdapter

因为你明确使用了延迟加载, 在后续调用你必需能保证已经在所有调用前完成了赋值. 否则会出现UninitializedPropertyAccessException异常

为了避免重复的赋值, Kotlin提供了判断是否初始化的判断. ::Filed.isInitialized

密封类

当使用when处理分支情况时, 如果传入的是一个状态接口, 通常要处理成功, 失败, 还有一个其他情况. 而其他情况其实根本不会存在. 这个时候可以使用密封类.

Kotlin编译器会自动检查密封类有哪些子类, 并强制要求你的每一个子类所对应的条件全部处理.

密封类的关键字sealed class. 修饰类名

场景: RecyclerView#onBindViewHolder() 中处理多个类型的ViewHolder时, 使用密封类可以去除无必要的else语句, 让代码更规范.

扩展函数

扩展函数表示即使在不修改某个类的源码的情况下, 仍然可以打开这个类,向这个类添加新的函数.

在Java中, 项目中有许多的自建的Utils. 比如需要一个判断一个字符串是否是手机号时. 通常我们要创建一个StringUtils类然后添加判断方法. 其实这个判断手机号的方法应该属于String类中. 但是由于String类是Final类型, 不能复写继承. 而扩展函数却解决了这个问题.

fun String.isPhone(): boolean{
    // ...
}

代码表示向String类中添加一个isPhone() 的函数. 后续使用时 字符串.isPhone() 即可

"13888887777".isPhone()

运算符重载

Java中有许多的内置运算符关键字 +,-,/, % 等, 而Kotlin允许将所有的运算符甚至其他的关键字进行重载, 从而扩展这些运算符合关键字的用法.

比方每个图书对象都有书名价格的属性. 那么就可以使用运算法重载, 让两个图书对象+, 得出书的总价.

运算符重载使用的是operator关键字, 只要在指定的函数前面加上即可. 而指定的函数如下:

语法糖表达式 实际调用函数
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.rem(b)
a– a.dec()
a++ a.inc()
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a == b a.equals(b)
a > b (<, >=, <=) a.compareTo(b)
a..b a.rangeTo(b)
a[b] a.get(b)
a[b] = c a.set(b,c)
a in b b.contains(a)

class Book(val name: String, val price: Float){
    // 重载+运算
    operator fun plus(book: Book): Float{
        return price + book.price;
    }
}

fun main(args: Array<String>){
    val book1 = Book("西游记", 100.0f)
    val book2 = Book("水浒传", 90.0f)
    println(book1 + book2)  // println: 190.0
}

Kotlin中**String#contains()**就进行了重载,

if("Hi, Jack".contains("Jack")){}
// 使用语法糖
if("Jack" in "Hi, Jack"){}