继续创造,加速成长!这是我参加「日新计划 6 月更文应战」的第2天,点击查看活动概况

接下来会将笔者往常项目开发过程中,借助于Kotlin完成的比较好的代码实践共享给咱们。

更简便弹出toast

先看下原生弹出toast的代码:

Toast.makeText(this, "haha", Toast.LENGTH_SHORT).show()

写起来有点繁琐,接下来咱们就会扩展函数封装下:

fun String.toast() {
  Toast.makeText(MainApp.mApplication, "", Toast.LENGTH_SHORT).show()
}

这样调用就非常方便了:

"haha".toast()

当然由于Toast弹出的时刻有两种,这里只是封装了Toast.LENGTH_SHORT,对于Toast.LENGTH_LONG能够再封装一个扩展办法,

fun String.longToast() {
  Toast.makeText(MainApp.mApplication, "", Toast.LENGTH_LONG).show()
}

或许在上一个扩展办法toast()的基础上增加一个默许参数:

fun String.toast(isLong: Boolean = false) {
  Toast.makeText(MainApp.mApplication, "", if (isLong) Toast.LENGTH_LONG else
    Toast.LENGTH_SHORT).show()
}

多目标判空逻辑校验优化

日常编程中,应该会经常碰到下面这种情况,需求对多个目标判空才能履行某个逻辑:

fun test(other1: Other1?, other2: Other2?, other3: Other3?) {
  if (other1 != null && other2 != null && other3 != null) {
    //履行某种逻辑
   }
}

这样写起来就很麻烦,并且一旦判空的目标多了,更是恐惧,借助于扩展函数+vararg能够封装如下函数:

fun requireNotNull(vararg obj: Any?, block: () -> Unit) {
  if (obj.filterNotNull().isNotEmpty()) {
    block()
   }
}

根据上面封装就能够这样完成代码:

fun test(other1: Other1?, other2: Other2?, other3: Other3?) {
  requireNotNull(other1, other2, other3) {
    //履行非空的逻辑
   }
}

上下比照,是不是非常明显,下面的愈加优雅简略。

布尔判断逻辑校验优化

日常编码过程中,咱们必定会写出下面的代码:

fun test2(name: String, age: Int, other1: Other1?) {
  if (name.isNotEmpty() && age == 20 && other1 == null) {
    //履行某种逻辑
   }
}

上面这样写一点缺点也没有,可是咱们能够借助于invoke运算符重载标识去掉每次每次逻辑判断的if这两个字母的:

operator fun Boolean.invoke(block: () -> Unit) {
  if (this) {
    block()
   }
}

今后就能够骚气的这样写判断:

fun test2(name: String, age: Int, other1: Other1?) {
   (name.isNotEmpty() && age == 20 && other1 == null) {
    //履行某种逻辑
   }
}

默许参数+命名参数+require校验替代Build规划形式

结构者规划形式运用非常普遍,比方okhttpAlertDialog等等,在我看来构建者规划形式运用的意图有两个:

  • 有选择性的参数动态装备
  • 参数合法性校验

而Kotlin的默许参数+命名参数就能够轻松完成有选择性的参数动态装备,比方,界说下面这样一个数据类:

data class Other1(
  val name: String = "",
  val age: String = "",
  val content: String = "",
  val type: Int = -1,
  val card: String = "",
  val child: String = "",
) {
}

首先给每个参数默许值,这样假如没有外部装备该参数时,运用默许值不发生负面效果,然后外部需求赋值时,直接指定对应的参数名进行赋值即可:

fun test3() {
  val other = Other1(
    age = "15",
    type = 10
   )
}

接下来还有一个参数合法性校验的,咱们能够界说一个require办法完成:

fun require(condition: Boolean, block: () -> Unit) {
  if (!condition) {
    block()
   }
}
​
fun require(condition: Boolean, message: String = "") {
  if (!condition) {
    throw IllegalArgumentException(message)
   }
}
  • 第一个办法是用来检验参数不符合逻辑时,需求进行批改的代码逻辑;
  • 第二个办法是用来校验参数不符合逻辑时,直接抛出反常处理,适合比较严苛的校验场景

然后看下在Other1类中的运用:

  init {
    //批改
    require(content == "data") {
      content = ""
     }
        //抛出反常
    require(age > "10", "age must > "10"")
   }

其实kotlin中有协助咱们界说require校验办法,可是不符合条件就抛出反常感觉不太号,所以就自界说了者两种校验办法。

经过上面的处理,构建者规划形式能完成的事情,运用Kotlin某些特性就能替代,运用起来也是非常的方便简略。

请注意:界说数据类时给每个结构参数增加默许值是一个比较好的习惯,尤其是涉及到与Gson的序列化和反序列化,能够削减null值的安全隐患。