驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
Kotlin:如何写出更优雅的代码之return的用法技巧
/  

Kotlin:如何写出更优雅的代码之return的用法技巧

开篇

最近用 kotlin写业务代码,福至心灵的又优化了一个写法,同时也再次加深了return的一个小技巧。

再感慨一句:kotlin真香...

return的范围

假如我有一个这样的代码,你觉得在 forEache里面的 return退出的是forEach还是这个方法?

    fun validateNum(strList: List<String>) {
        strList.forEach {
            if (it.length > 1)
                //注意这里
                return
        }
        doSomeOthers()
    }

如果你尝试执行下,那么久可以发现,当前的写法,return是退出整个方法,假如你要退出这个forEach你需要怎么写了?

    fun validateNum(strList: List<String>) {
        strList.forEach {
            if (it.length > 1)
                //注意这里
                return@forEach
        }
        doSomeOthers()
    }

核心的就是return@forEach,注明清楚返回的是@forEach这个循环

接收方法体的值

比如这个方法就是解析出json中的userId

 fun mtRegister(ctx: ChannelHandlerContext, body: TransferInfo) {
		val userId = parseToken(body).let {
      	if (it.first.isNotBlank()) {
            log.error("解析token失败...") 
            return //return 直接退出
       	} else {
            it.second.toLong()
       	}
    }
 }

接收方法体就是类似上面的写法,这样可以直接获取到 userId的值,我们简单分析下几个场景

为什么使用 let

  • 使用let的目的是为了减少一个局部变量的声明,假如我不用let代码需声明一个局部参数uIdTuple2,但是该变量只是一个为了uId过渡变量
  • 通过该变量后面可能根本不会使用,根据最少知道原则以及避免后续可能错误使用该变量的考虑着想,用let岂不更好。
 fun mtRegister(ctx: ChannelHandlerContext, body: TransferInfo) {
        val uIdTuple2 = parseToken(body)
      	val userId = if (uIdTuple2.first.isNotBlank()) {
            log.error("解析${uIdTuple2}失败...")
            return
       	} else {
            uIdTuple2.second.toLong()
       	}
    }
 }

return 退出

方便阅读,这里再贴下代码:

 fun mtRegister(ctx: ChannelHandlerContext, body: TransferInfo) {
		val userId = parseToken(body).let {
      	if (it.first.isNotBlank()) {
            log.error("解析token失败...") 
            return //return 直接退出
       	} else {
            it.second.toLong()
       	}
    }
 }

这里的return 退出也是kotlin支持的用法,在判定的过程中,就发现了终止条件,那么退出。

可能传统的Java程序员会纳闷不是外层还有一个userId在接收吗?其实在该情况下 userId根本不会有值,同时后续的代码也不会执行。

你注意最后一行 it.second.toLong(),这个可是没有return的,kotlin 会自动帮我们默认为该表达式最内层的方法的返回值。

假如你要强行写 return,那么就需要注意了,return 的范围了,因为此时可是又 2 层 方法的

  • 外层mtRegister
  • 里层let

所以,如果在当前情形下,你需要这么写:

 return@let it.second.toLong()

通过@method来表明你退出的是哪个方法...

结语

这个也是最近在使用kotlin的时候,发现的一些小技巧,这里简单记录下...

不积跬步,无以至千里。不积小流,无以成江海。