版权声明:本文为 newtrekWang 原创文章,可以随意转载,但必须在明确位置注明出处!!!

Day1 可见性

参考

31 天,从浅到深轻松学习 Kotlin
Kotlin实战

在 Kotlin 中一切都是默认 public 的。在Kotlin中,存在private、protected、internal和 public四种修饰符,它们可用于修饰类、对象、接口、构造器、函数、属性、以及属性的设值方法等。

修饰符 类成员 顶层声明
public(默认) 所有地方可见 所有地方可见
internal 模块中可见 模块中可见
protected 子类中可见 -
private 类中可见 文件中可见

内部类和嵌套类:默认是嵌套类

类A在另一个类B中声明 在Java中 在Kotlin中
嵌套类(不存储外部类的引用) static class A class A
内部类(存贮外部类的引用) class A inner Class A

Day2 可空性

参考

Kotlin Reference: Null Safety
Kotlin教程(四)可空性

可空类型与非空类型

如果一个变量可能为空,然后对这个变量直接进行调用是不安全的,很容易造成NullPointerException,通常我们的办法是加个if判断,但是用java写个if在Kotliln看来语句也是听多的。所以Kotlin给变量增加了可空类型和非空类型特性。

通常声明一个变量,如果变量类型后面没有加?,那么它是非空类型,也就是它不能为null

例子:
没有加?是非空类型

非空类型变量a赋值为null,直接爆红

但是我加了?就正常了,证明加了?表示这个变量为可空类型,可以赋值为null

加?是可空类型

非空判断与安全调用

加? 和不加可以看做是两种类型,不能直接调用可空类型的方法,只有与null进行比较后,编译器才会智能转换这个类型。
例如:

这样s才能转为非空类型,才能调用其length属性

为了简化是否为null的if语句,Kotlin提供了?.这个安全调用运算符,它把一次null检查和一次方法调用合并成一个操作,例如例如表达式s?.toUpperCase() 等同于if (s != null) s.toUpperCase() else null,换句话说,如果你试图调用一个非空值的方法,这次方法调用会被正常地执行。但如果值是null,这次调用不会发生,而整个表达式的值为null。因此表达式s?.toUpperCase() 的返回类型是String?

安全调用支持链式调用,很实用,例:

Elvis 操作符

对于一个可为空的引用 r,我们可以说“如果 r 不为空,则使用它,否则使用另外的非空值 x”
原来写法:

使用Elvis写法:

如果 ?: 左边的表达式不为空,则 Elvis 操作符返回该表达式;否则返回右边的表达式。注意只有在左边的表达式不为空时,才会计算右边的表达式。

因为在 Kotlin 中 throw 和 return 也属于表达式,所以它们也可以放在 Elvis 操作符的右边。这一点非常方便,如在检查函数参数时:

!!操作符

如果你想要看到NPE,就是让他像用Java一样可能抛NPE,那么你要显示的在变量后面加!!,不过这样的情况一般是在你100%确定该变量不会为空。
例如:

安全转换

常规的转换会在对象不属于目标类型时导致 ClassCastException。此外还可以使用安全转换,安全转换会在转换失败时返回 null:

Day3 String模板

格式化字符串?将\$放在变量名的前面去表达字符串中的变量和表达式。使用 \${expression} 求表达式的值。
例子:

Day4 when表达式

参考文章

31 天,从浅到深轻松学习 Kotlin
kotlin中的when:强大的switch

when相当于switch,但是Kotlin的when是个强大的switch,几乎可以匹配任何东西,字面值,枚举,数组范围

像用Java的switch一样使用

自动转换类型

无自变量when,类似if else的含义,可做表达式

Day5 循环,范围表达式与解构

Day6 属性

再Kotlin中,类可以具有可变和只读属性,默认情况下生成getter和setter,也可以自定义。

Day7 解构

Android KTX 使用解构来分配颜色的组件值。您可以在您的类中使用解构,或者扩展现有的类来添加解构。

解构声明可以一次声明多个变量,任何表达式都可以出现在解构声明的右侧,只要我们可以对它调用所需数量的component函数(注意:componentN()函数需要用operator关键字修饰,以允许其在解构声明声明中使用它们)。数据类自动声明component函数。

也可以在for循环中使用解构声明,只要集合中的每个元素提供有componentN()方法

也可以对映射使用解构赋值。因为map结构提供函数 component1() 和 component2() 来将每个元素呈现为一对。

Day 8 简单的bundle

通过简洁的方式创建bundle,不调用putString,putInt,或它们的20个方法中的任何一个。一个调用生成一个新的bundle,甚至可以处理Arrays,bundle很像map

Day 9 Parcelize

习惯Parcelable的速度,但不喜欢写所有的代码?和@Parcelize打个招呼.

Day10 Data类和equality

可以创建一数据类,它可以默认实现生成equals()方法相当于hashCode(),toString()和copy(),并检查结构是否相等。

Day11 简化postDelay

Android KTX已经为Handler做了个小包装,类似于传闭包的形式传入参数。

Day12 默认参数

如果方法中的参数太多,Kotlin可以在函数中指定默认参数值,使用命名参数使代码更具有可读性。

Day13 java调用Kotlin

java和,Kotlin混用,默认情况下,编译器可以生成顶级类,名称为YourFileKt,可以通过使用@file:JvmName注释文件来更改它。

ShapesGenerator.kt

java调用

使用file注解

java调用

Day14 在没有迭代器的情况下迭代类型

迭代器用在了有趣的地方!Android KTX 将迭代器添加到 viewGroup 和 sparseArray。要定义迭代器扩展请使用 operator 关键字。 Foreach 循环将使用扩展名!
可惜androidKTX要最新版开发版AS才能用。

第二周小结:
这周我们更深入的学习了 Kotlin 的特性:简洁 bundle,迭代,Data,postDelay,默认参数,序列化。

Day 15 Sealed Class

Kotlin的sealed类可以让你轻松的处理错误数据

密封类的好处在于:使用when表达式,如果能覆盖所有情况,就无需再添加else子句

如果将sealed类用在RecyclerView的Adapter中,非常适合于ViewHolders,用一组干净的类型明确地分派给每个持有者。用作表达式时,如果有类型不匹配,编译器将会出错。

使用RecyclerView,如果我们有很多来自RecyclerView中的item的回调,比如一个点击,分享和删除item的项目,我们可以用sealed类,一个回调处理所有的事情!

Day 16 懒加载

通过使用懒加载,可以省去昂贵的属性初始化的成本直到它们真正需要时。计算值然后保存并为了未来的任何时候的调用。

lazy 应用于单例模式(if-null-then-init-else-return),而且当且仅当变量被第一次调用的时候,委托方法才会执行。

Day 17 lateinit

在kotlin中不为空的对象必须初始化,var 变量加这个关键字表示这个变量迟早会初始化,不过lateinit只能用于var

例如,Activity里的成员初始化

Day18 要求(require)和检查(check)

判断方法参数的有效,可以用require在使用前检查它们,如果它们是无效的,将会抛出IllegalArgumentException

封闭类的状态是否正确,可以使用check来验证,如果检查的值为false,它将抛出IllegalStateException

本质就是Kotlin标准库定义了个require和check含闭包的方法

Day19 内联 InLine

参考:Kotlin语法(十九)-内联函数(Inline Functions)

调用一个方法是一个压栈和出栈的过程,调用方法时将栈针压入方法栈,然后执行方法体,方法结束时将栈针出栈,这个压栈和出栈的过程会耗费资源,这个过程中传递形参也会耗费资源。
例如:

通过内联Lambda表达式方式,可以减少这种开销。等同于:

定义方法:

inline关键字实际上增加了代码量,但是提升了性能,而且增加的代码量是在编译期执行的,对程序可读性不会造成影响。

Day20 运算符重载

参考:Kotlin - 运算符重载

用操作符重载快更快速写 Kotlin。像 Path,Range或 SpannableStrings 这样的对象允许像加法或减法这样的操作。通过 Kotlin,您可以实现自己的操作符。

Day21 顶级方法和参数

顶级方法,将它们添加到源文件的顶层,在Java中,它们被编译为该类的静态方法

也可以定义顶级属性,它们将编译为字段和静态访问器

Day22 简单的内容值

将ContentValues的强大功能与kotlin的简洁性相结合,使得Android KTX只传递一个Pair<StringKey, Value>创建ContentValues.

Day23 DSLs

特定于域的语言可以通过使用类型安全的构建器来完成。它们为简化API做出贡献。你可以借助扩展lambdas和类型安全构建器等功能构建它们.

Anko例子:

Day 24 具体化

Android KTX中的Context.systemService()使用泛化来通过泛型传递“真实”类型,没有通过getSystemService.

Day25 代理

类委托

属性委托
语法是: val/var <属性名>: <类型> by <表达式>。在 by 后面的表达式是该 委托, 因为属性对应的 get()(和 set())会被委托给它的 getValue() 和 setValue() 方法。 属性的委托不必实现任何的接口,但是需要提供一个 getValue() 函数(和 setValue()——对于 var 属性)。

Day26 扩展方法

没有更多的Util类,可以通过使用扩展方法扩展类的功能。只要把你要扩展的类的名字放在你添加的方法的名字后面。

扩展功能的一些特性:

  • 不是成员函数
  • 不要以任何方式修改原始类
  • 通过静态类型信息解决编译时间
  • 会被编译为静态函数
  • 不要多态性

例如String的扩展:

Day27 Drawable.toBitmap()轻松转换

AndroidKTX对Drawable进行了扩展,能将Drawable轻松转换为bitmap

Day28 Sequences,lazy和generators

参考

Kotlin系列之序列(Sequences)源码完全解析

序列操作又被称之为惰性集合操作,Sequences序列接口强大在于其操作的实现方式。序列中的元素求值都是惰性的,所以可以更加高效使用序列来对数据集中的元素进行链式操作(映射、过滤、变换等),而不需要像普通集合那样,每进行一次数据操作,都必须要开辟新的内存来存储中间结果,而实际上绝大多数的数据集合操作的需求关注点在于最后的结果而不是中间的过程,

序列是在Kotlin中操作数据集的另一种选择,它和Java8中新增的Stream很像,在Java8中我们可以把一个数据集合转换成Stream,然后再对Stream进行数据操作(映射、过滤、变换等),序列(Sequences)可以说是用于优化集合在一些特殊场景下的工具。但是它不是用来替代集合,准确来说它起到是一个互补的作用。

Day 29 更简单的Sqans

Spans 功能强大,但是API很难用,Android KTX为常见的Span添加了扩展功能。

Day30 updatePadding 扩展

Android KTX的视图扩展

#Day 31 范围外run,let,with,apply

kotlin的标准函数,简短强大,run,let,with和apply都有一个接收器(this),可能由一个参数(it)并可能有一个返回值,差异如下:

run

执行后,result为1,run就是一个传闭包的函数,闭包里可以调用对象的方法和this

let

with

apply

Hits: 11

分类: Kotlin

发表评论

电子邮件地址不会被公开。 必填项已用*标注