Kotlin学习笔记之习惯用法

本文继Kotlin学习笔记之基本语法的续篇,
主要讲解之前未讲解过的一些习惯用法。
例如:

  • 创建全局静态变量
  • 创建内联函数
  • with 等语法

创建 DTOs(POJOs/POCOs)

1
data class User(val name:String,val age:Int = 25)
  • 会为 Customer 类提供以下功能:

    • 所有属性的 getters (对于 var 定义的还有 setters)
    • equals()
    • hashCode()
    • toString()
      输出格式: “User(name=John, age=42)”
    • copy()
      1
      2
      3
      4
      fun copy(name: String = this.name, age: Int = this.age) = User(name, age)   

      val jack = User(name = "Jack", age = 1)
      val olderJack = jack.copy(age = 2)
  • 数据类和解构声明

    1
    2
    3
    val jane = User("Jane", 35)
    val (name, age) = jane
    println("$name, $age years of age") // 输出 "Jane, 35 years of age"

注意:

  • 在 JVM 中,如果生成的类需要含有一个无参的构造函数,则所有的属性必须指定默认值。

函数给默认参数

1
fun foo(a: Int = 0, b: String = "") { …… }

过滤 list

  • 内部提供filter方法
    1
    2
    3
    val positives = list.filter { x -> x > 0 }
    //或
    val positives = list.filter { it > 0 }

String 内插

  • 使用关键符号$
    1
    println("Name $name")

扩展函数

  • 创建扩展函数语法:需要扩展的类名.自定义扩展的方法。 (即:该类名就多了一个扩展方法)
    1
    2
    3
    4
    5
    6
    7
    8
    fun String.toTop10String() :String{
    if (this.length > 10)
    return this.substring(0, 10)
    else
    return this
    }

    "Convert this to toTop10String".toTop10String()

创建单例

  • object 关键字
    1
    2
    3
    object className {
    val name = "Name"
    }

    null相关缩写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// If not null 缩写
val files = File("Test").listFiles()
println(files?.size)

// If not null and else 缩写
val files = File("Test").listFiles()
println(files?.size ?: "empty")

// if null 执行一个语句
val data = ……
val email = data["email"] ?: throw IllegalStateException("Email is missing!")

//映射可空值(如果非空的话
val data = ……
val mapped = data?.let { transformData(it) } ?: defaultValueIfDataIsNull
~

try/catch表达式

1
2
3
4
5
6
7
8
fun test() {
val result = try {
count()
} catch (e: ArithmeticException) {
throw IllegalStateException(e)
}
// 使用 result
}

with

  • with括号里面传入any对象,就可以直接调用any的方法。不用 对象.方法()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Turtle {
fun penDown()
fun penUp()
fun turn(degrees: Double)
fun forward(pixels: Double)
}

val myTurtle = Turtle()
with(myTurtle) { //draw a 100 pix square
penDown()
for(i in 1..4) {
forward(100.0)
turn(90.0)
}
penUp()
}

inline 创建通用函数

  • 在整个应用程序中都可以调用的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//放到kotlin文件最外层程序全局可使用 
//1.传参数
inline fun <reified T> getClassName(any:Any):String{
return T::class.java.name + any.toString()
}
//使用
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
txt.text = getClassName<OneActivity>(this)
}

//2.传函数
object MyExecutor{
val instance: ExecutorService = Executors.newCachedThreadPool()
}
inline fun doSync(crossinline block: () -> Unit) {
MyExecutor.instance.execute { block() }
}

//调用如下。 传入的block代码块可以直接放在函数后面的{}里。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
doSync{
//Code: Request network
}
}

companion object 静态变量

与java有所区别,kotlin创建静态变量需要companion object 关键字。
注意事项

  • 使用const关键字后创建的静态属性不属于内部类中的成员,可减少不需要的Constants对象
  • const关键字不支持Any等实体对象,可用@JvmField 关键字
    1
    2
    3
    4
    companion object {
    const val TIMER_DELAY:Long = 3000 // 定义long类型的全局静态变量
    @JvmField val mUser:User = User("小张",25) //定义any对象的全局静态变量
    }

使用可空布尔

1
2
3
4
5
6
val b: Boolean? = ……
if (b == true) {
……
} else {
// `b` 是 false 或者 null
}