java集合转labelpoint_Kotlin中label标签的使用

你可能会好奇,对Kotlin中的一些用法感到困惑,比如:

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

btn_login.setOnClickListener({

val phone = et_phone.text.toString().trim()

val password = et_password.text.toString().trim()

if (TextUtils.isEmpty(phone)) {

ToastUtils.showShortToast(this, "手机号不能为空")

return@setOnClickListener

}

if (!ValidateUtils.isMobile(phone)) {

ToastUtils.showShortToast(this, "请输入正确手机号")

return@setOnClickListener

}

if (TextUtils.isEmpty(password)) {

ToastUtils.showShortToast(this, "密码不能为空")

return@setOnClickListener

}

if (password.length < 6 || password.length > 16) {

ToastUtils.showShortToast(this, "请输入6-16位密码")

return@setOnClickListener

}

getCampus(phone, password)

})

btn_forget_password.setOnClickListener({

val phone = et_phone.text.toString().trim()

startActivity(

Intent(this@LoginActivity, ForgetPasswordActivity::class.java).putExtra("phone",

phone))

})

上面是我从登录功能中截取的一段代码,我们来着重看下面这句:

if (password.length < 6 || password.length > 16) {

ToastUtils.showShortToast(this, "请输入6-16位密码")

return@setOnClickListener

}

这个@setOnClickListener是个什么鬼呢?

其实我们被编译器的颜色误导了,这个@标记的是return,也就是 return@

Kotlin的返回与跳转

Kotlin 中存在 3 种跳出程序流程的表达式:

return. 默认行为是, 从最内层的函数或 匿名函数 中返回.

break. 结束最内层的循环.

continue. 在最内层的循环中, 跳转到下一次循环.

所有这些表达式都可以用作更大的表达式的一部分:

val s = person.name ?: return

这些表达式的类型都是 Nothing 类型.

Break 和 Continue 的位置标签

Kotlin 中的任何表达式都可以用 label 标签来标记. 标签由标识符后面加一个 @ 符号构成, 比如: abc@, fooBar@ 都是合法的标签(参见 语法). 要给一个表达式标记标签, 我们只需要将标签放在它之前:

loop@ for (i in 1..100) {

// ...

}

然后, 我们就可以使用标签来限定 break 或 continue 的跳转对象:

loop@ for (i in 1..100) {

for (j in 1..100) {

if (...) break@loop

}

}

通过标签限定后, break 语句, 将会跳转到这个标签标记的循环语句之后. continue 语句则会跳转到循环语句的下一次循环.

使用标签控制 return 的目标

在 Kotlin 中, 通过使用字面值函数(function literal), 局部函数(local function), 以及对象表达式(object expression), 允许实现函数的嵌套. 通过标签限定的 return 语句, 可以从一个外层函数中返回. 最重要的使用场景是从 Lambda 表达式中返回. 回忆一下我们曾经写过以下代码:

//sampleStart

fun foo() {

listOf(1, 2, 3, 4, 5).forEach {

if (it == 3) return // 非局部的返回(non-local return), 直接返回到 foo() 函数的调用者

print(it)

}

println("this point is unreachable")

}

//sampleEnd

fun main(args: Array) {

foo()

}

这里的 return 会从最内层的函数中返回, 也就是, 从 foo 函数返回. (注意, 这种非局部的返回(non-local return), 仅对传递给 内联函数(inline function) 的 Lambda 表达式有效.) 如果需要从 Lambda 表达式返回, 我们必须对它标记一个标签, 然后使用这个标签来指明 return 的目标:

//sampleStart

fun foo() {

listOf(1, 2, 3, 4, 5).forEach lit@{

if (it == 3) return@lit // 局部的返回(local return), 返回到 Lambda 表达式的调用者, 也就是, 返回到 forEach 循环

print(it)

}

print(" done with explicit label")

}

//sampleEnd

fun main(args: Array) {

foo()

}

这样, return 语句就只从 Lambda 表达式中返回. 通常, 使用隐含标签会更方便一些, 隐含标签的名称与 Lambda 表达式被传递去的函数名称相同.

//sampleStart

fun foo() {

listOf(1, 2, 3, 4, 5).forEach {

if (it == 3) return@forEach // 局部的返回(local return), 返回到 Lambda 表达式的调用者, 也就是, 返回到 forEach 循环

print(it)

}

print(" done with implicit label")

}

//sampleEnd

fun main(args: Array) {

foo()

}

或者, 我们也可以使用 匿名函数 来替代 Lambda 表达式. 匿名函数内的 return 语句会从匿名函数内返回.

//sampleStart

fun foo() {

listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {

if (value == 3) return // 局部的返回(local return), 返回到匿名函数的调用者, 也就是, 返回到 forEach 循环

print(value)

})

print(" done with anonymous function")

}

//sampleEnd

fun main(args: Array) {

foo()

}

注意, 上面三个例子中局部返回的使用, 都与通常的循环中的 continue 关键字的使用很类似. 不存在与 break 直接等价的语法, 但可以模拟出来, 方法是增加一个嵌套的 Lambda 表达式, 然后在它内部使用非局部的返回:

//sampleStart

fun foo() {

run loop@{

listOf(1, 2, 3, 4, 5).forEach {

if (it == 3) return@loop // 非局部的返回(non-local return), 从传递给 run 函数的 Lambda 表达式中返回

print(it)

}

}

print(" done with nested loop")

}

//sampleEnd

fun main(args: Array) {

foo()

}

当 return 语句指定了返回值时, 源代码解析器会将这样的语句优先识别为使用标签限定的 return 语句, 也就是说:

return@a 1

含义是 “返回到标签 @a 处, 返回值为 1”, 而不是 “返回一个带标签的表达式 (@a 1)”.

最后

这下应该明白为什么要用return@setOnClickListener这种写法了吧,是为了指定返回的目标位置,如果直接写return,则会直接退出onCreate方法,导致下面的代码无法执行。

b214b5e58017?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

うずまき ナルト.jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值