前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用好 Require,check,assert,写好 Kotlin 代码

用好 Require,check,assert,写好 Kotlin 代码

作者头像
技术小黑屋
发布2020-05-12 10:04:43
7710
发布2020-05-12 10:04:43
举报
文章被收录于专栏:技术小黑屋技术小黑屋

在编码的时候,我们需要做很多的检测判断,比如某个变量是否为null,某个成员属性是否为true,执行某个操作结果是否成功。比如像下面的这段代码

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

var isDiskMounted = true fun createNewFile(file: File?): Boolean { return if (isDiskMounted) { if (file != null) { file.createNewFile() if (file.exists()) { true } else { println("Create file($file) failed") false } } else { println("File($file) is null") false } } else { println("Disk is not mounted") false } }

上面的代码实现了

  • 检测磁盘是否挂载
  • 检测file参数是否为null
  • 检测执行操作结果是否成功(file.exists())

但是上面的代码也有一些问题

  • 太多的if else 检测,层级产生,不够平
  • 多个方法出口
  • 更不容易发现异常和错误(有点类似fail safe模式)

使用今天的知识点改造

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

fun createNewFileV2(file: File?): Boolean { check(isDiskMounted) { "Disk is not mounted" } requireNotNull(file) { "file is null" } file.createNewFile() assert(file.exists()) { "createNewFileV2 file($file) does not exist" } return true }

  • 方法体没有多余层级,比较平
  • 单个方法出口
  • 更快更早发现问题(有点类似fail fast)
  • file.createNewFile()执行时可以不需要再使用file?.createNewFile() 这一点是因为使用了Contract

require

  • require(boolean) 用来检测方法的参数,当参数boolean为false时,抛出IllegalArgumentException

示例代码

1 2 3 4 5 6 7 8 9 10 11 12

fun readFileContent(file: File?): String { //判断file不能为null requireNotNull(file) //判断文件必须可读,并提供错误的信息 require(file.canRead()) { "readFileContent file($file) is not readable" } //read file content return "Your file content" }

变种方法

  • fun require(value: Boolean)
  • fun require(value: Boolean, lazyMessage: () -> Any)
  • fun <T : Any> requireNotNull(value: T?)
  • fun <T : Any> requireNotNull(value: T?, lazyMessage: () -> Any)

check

  • check(boolean)用来检测对象的状态(属性),如果boolean为false,抛出异常IllegalStateException

示例代码

1 2 3 4 5 6 7 8 9 10 11 12 13

class Engine { var isStarted = false fun speedUp() { check(isStarted) { "Engine is not started, cannot be speed up now" } //speed up the engine } }

变种方法

  • fun check(value: Boolean, lazyMessage: () -> Any)
  • fun <T : Any> checkNotNull(value: T?)
  • fun <T : Any> checkNotNull(value: T?, lazyMessage: () -> Any)

assert

  • assert(boolean) 用来检测执行结果,当boolean为false时,抛出AssertionError。但是需要在开启对应的JVM选项时才生效。

示例代码

1 2 3 4 5 6 7 8

fun makeFile(path: String) { val file = File(path) file.createNewFile() assert(file.exists()) { "make File($file) failed" } }

使用顺序

  • 先使用check检测对象的状态
  • 再使用require检测方法的参数合法性
  • 执行操作后,使用assert校验结果

关于lazyMessage

崩溃更多了,怎么办

  • 是的,上面无论是require,check,assert都会在发现错误的时候抛出异常
  • 这是为了让问题更早发现,这就是它们的哲学
  • 如果想要考虑稳定的话,可以在业务侧 debug下崩溃,非debug下捕获吞掉异常

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

fun main() { createNewFile(null) safeRun { createNewFileV2(null) } } private val isDebug = true fun safeRun(block: () -> Unit) { try { block() } catch (t: Throwable) { t.printStackTrace() if (isDebug) { throw t } } }

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用今天的知识点改造
  • require
    • 示例代码
      • 变种方法
      • check
        • 示例代码
          • 变种方法
          • assert
            • 示例代码
            • 使用顺序
            • 关于lazyMessage
            • 崩溃更多了,怎么办
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档