Kotlin-简约之美-进阶篇(二):when的使用详解_kotlin duplicate label in when-程序员宅基地

提到 when,大家都会联想到 Java 中的 switch,然而在 kotlin 中,when 显然比 Java 中的 switch 要强大得多。首先,我们先来看看 when 的特点:

  • 它可以作为表达式使用
  • 使用更加安全
  • 强大灵活的分支结构
  • 可以不带参数
    接下来,我来带大家逐步领略这些特点。以下面这段 Java 功能代码为例:
switch(animal) {
    case EAGLE:
        System.out.println("鸟类");
        break;
    case DOLPHIN:
        System.out.println("兽类");
        break;
    case LOCUST:
        System.out.println("昆虫类");
        break;
    case CARP:
        System.out.println("鱼类");
        break;
    case TIGER:
        System.out.println("兽类");
        break;
    case DUCK:
        System.out.println("鸟类");
        break;
    default:
        System.out.println("未知动物");
        break;
}

从以上代码可以看出,我们这里实现的功能是:通过用户输入一个动物名称来得到其对应的种类信息。乍一看,你可能会觉得上面的代码再正常不过,但是倘若我们的输入情形很多的话,就会增加密密麻麻的限制条件,这肯定是我们不想看到的。那么,让我们来看看通过 Kotlin 的 when 表达式如何实现相同功能:

when(animal) {
    EAGLE, DUCK -> println("鸟类")
    DOLPHIN, TIGER -> println("兽类")
    CARP -> println("鱼类")
    LOCUST -> println("昆虫类")
    else -> println("未知动物")
}

OK,以上就是该功能代码的 kotlin 实现方式,代码不仅简化了很多,也省去了大量的 break 语句,避免了 Java 中因遗漏 break 而导致的 bug,增强了安全性。如果匹配成功,对应的分支便会执行,同时也可以把多个情况合并到同一个分支,只需要通过逗号隔开,并没有额外的代码。

PS:每个条件分支的处理通过在 -> 之后来进行。

作为表达式使用

首先,我们需要重温一下表达式与语句的区别。表达式有值,并能作为另一个表达式的一部分来使用;而语句没有返回值。Java 中的控制结构皆为语句。而在 Kotlin 中,除了循环体结构外,大多数控制结构都是表达式。举个栗子��,还是上面的例子,我们可以将其优化为以下代码:

var result = when(animal) {
    EAGLE, DUCK -> "鸟类"
    DOLPHIN, TIGER -> "兽类"
    CARP -> "鱼类"
    LOCUST -> "昆虫类"
    else -> "未知动物"
}
// 输入:DUCK,返回:当前动物的种类为:鸟类
println("当前动物的种类为: $result")

此外,我们也可以直接通过表达式函数来直接得到最终的结果:

fun displayAnimalType(animal: Animal) =
            when(animal) {
                Animal.EAGLE, Animal.DUCK -> "鸟类"
                Animal.DOLPHIN, Animal.TIGER -> "兽类"
                Animal.CARP -> "鱼类"
                Animal.LOCUST -> "昆虫类"
                else -> "未知动物"
  }

强大灵活的分支

Kotlin 中的 when 远比 Java 当中的 switch 要强大得多。switch 只能以常量作为分支条件,而 when 允许使用任意对象。emmm~举个简单的例子吧:

fun handleResult(score: Int) =
            when(score) {
                in 0..39 -> "fail to go up to the next grade."
                in 40 until 60 -> "not pass, should test again."
                97,98,99,100 -> "learning outstanding results."
                else -> "pass the test."
            }

Java 当中,当我们的分支情况比较多或者每种分支可能会重复多次时,势必会通过 if-else 来各种判断,而在 Kotlin 当中,一个 when 就能帮我们完成这些操作。
此外,如果你想判断一个未知变量的类型,而其可能类型有很多种可能性,那么也可以通过 when 来实现,例如:

fun judgeAnimalKind(animal: Any) =
            when(animal) {
                is Bird -> "这是鸟类"
                is Fish -> "这是鱼类"
                judgeIfInsect(animal) -> "这是昆虫"
                else -> "我不知道这是什么动物"
}

当然,我们也可以将代码块作为我们的分支体,这时候,代码块中最后一个表达式或者变量就是该分支体的返回结果,如:

fun judgeAnimalKind(animal: Any) =
            when(animal) {
                is Bird -> "这是鸟类"
                is Fish -> "这是鱼类"
                judgeIfInsect(animal) -> "这是昆虫"
                else -> {
                    val kind = if (judgeDolphin(animal) || judgeTiger(animal)) {
                        "这是兽类"
                    }else {
                        "我不知道这是什么动物"
                    }
                    kind
                }
            }

上述代码中,kind 即为我们的 else 分支块中的最终返回结果。

无参的情况

特别地,when 中的参数可能并非满足我们的需求,我们可以选择省略该参数,例如这样:

when {
    phoneNumber?.length != 11 -> toast("illegal phone number.")
    password.isNullOrEmpty() -> toast("please input password")
}

总结

通过以上的介绍,我们不难发现:when 的使用场景要比 Java 的 switch 灵活、强大的多,同时,我们也可以借助 when 来重构和优化复杂的 if-else 结构,以简化我们的代码,提高代码的可读性。

学习交流

欢迎入群交流学习,Android、Java开发技术交流群

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/geduo_83/article/details/104260291

智能推荐

vue后台水印实现_v-watermark-程序员宅基地

文章浏览阅读2.4w次,点赞3次,收藏2次。vue后台水印实现Vue项目在页面添加水印功能创建watermark.js文件<template> <router-view v-waterMark="waterCode" ></router-view></template><script>import waterMark from 'common/utils/watermark';export default { directives: {_v-watermark

CSS 鼠标悬浮在图片上添加遮罩层效果的实现_css 悬浮遮罩进行操作怎么操作-程序员宅基地

文章浏览阅读2.3k次,点赞3次,收藏6次。实现的关键是 CSS 的opacity和hover,本文也主要介绍遮罩层的实现父级元素 sub-module-type 要display: block;position: relative;子级元素 mask 遮罩层 position: absolute;opacity: 0;pointer-events:none;鼠标悬浮时 opacity: 1; <div class="sub-module"> <div class="sub-modul..._css 悬浮遮罩进行操作怎么操作

ora-64203:Destination buffer too small to hold CLOB data after character set conversion.-程序员宅基地

文章浏览阅读2.8k次。ora-64203:Destination buffer too small to hold CLOB data after character set conversion.拼接字符串时过长引起,报缓冲区太小错误SELECT WM_CONCAT(field_A|| field_b) FROM table_A WHERE fie..._destination buffer too small to hold clob data after character set conversio

ThinkPHP 数据库操作(三) : 查询方法、查询语法、链式操作_thinkphp db where-程序员宅基地

文章浏览阅读3.5k次。查询方法条件查询方法where 方法可以使用 where 方法进行 AND 条件查询:Db::table('think_user') ->where('name','like','%thinkphp') ->where('status',1) ->find();多字段相同条件的 AND 查询可以简化为如下方式:Db::table('think_user') ->where('name&title','like','%_thinkphp db where

在Java中,使用HttpUtils实现发送HTTP请求_java httputils-程序员宅基地

文章浏览阅读1.4k次。HTTP请求,在日常开发中,还是比较常见的,今天给大家分享HttpUtils如何使用。阅读本文,你将收获:简单总结HTTP请求常用配置;JavaLib中HttpUtils如何使用;如何封装HTTP请求工具类。_java httputils

解决loadrunner 12 录制时打不开Chrome谷歌浏览器,显示正在加载中的问题_loadrunner12录制脚本打不开谷歌浏览器-程序员宅基地

文章浏览阅读8.6k次,点赞12次,收藏18次。loadrunner 12 录制时打不开谷歌浏览器,一直显示正在加载的问题刚开始学习loadrunner,安装了loadrunner 12,录制时浏览器一直显示正在加载…看到网上有人说录制的时候打开Fiddler就可以了,试了下确实可以。但如果录制的时候打开Fiddler,那么回放时也需要借助Fiddler才能正常回放。后来折腾了很久发现可以这么设置1. 在开始录制时的录制选项(Recor..._loadrunner12录制脚本打不开谷歌浏览器

随便推点

物联网应用开发实践案例-智慧农业_物联网农业项目案例-程序员宅基地

文章浏览阅读1.1k次。1. 设计需求、硬件环境介绍1.1 项目背景近几年,物联网、智能家居、AI人工智能技术发送非常迅速。在物联网技术的支撑下,如今农业逐渐走向现代化,自动化、现在智能化的农业生产成为了主流。告别“刀耕火种”的传统农业后,现代农业也正在向智慧型转变,当前智慧农业模式已经深入到农业生产的各个环节,灌溉、施肥、植保等细分领域都将与物联网、信息技术等先进科技相结合,效率、效果也将得到大大提高。要知道,所谓的“智慧农业”就是充分应用现代信息技术成果,集成应用计算机技术与网络技术、物联网技术、无线通信技术以及专家智慧_物联网农业项目案例

【nifi数据采集】nifi给kafka打数据遇到的坑 - kafka2.1 的listeners配置_nifi consumerkafkarecord-程序员宅基地

文章浏览阅读4.3k次。如下图,在测试使用nifi往kafka打数据的时候,发现通过ambari安装的kafka收不到数据,而通过docker安装的kafka则可以收到数据。nifi后台log日志报错信息2020-04-19 11:09:02,916 INFO [Timer-Driven Process Thread-10] o.a.kafka.common.utils.AppInfoParser Kafka ..._nifi consumerkafkarecord

ide小技巧_zhile.io-程序员宅基地

文章浏览阅读730次。目录前言一.安装toolbox二.安装ide三.添加插件说明:前言 ide的工具都是要花钱购买的,那么有一种无限薅羊毛的方法,是不是就特别爽呢?话不多说,直接进入正题。一.安装toolbox首先去下载iea全家桶下载的工具,这个工具里面有最近几个版本的ide。特别说明一下,ide2021的版本都是要先登录才能试用,那么2020的就没有这个要求了,它们支持直接进入试用!咱们可以去官网直接下载toolbox,JetBrains Too..._zhile.io

Docker 快速安装Jenkins完美教程(解决无法安装插件问题)_docker 安装jenkins 无法安装git插件-程序员宅基地

文章浏览阅读3.7k次,点赞2次,收藏12次。一、前言有人问,为什么要用Jenkins?我说下我以前开发的痛点,在一些中小型企业,每次开发一个项目完成后,需要打包部署,可能没有专门的运维人员,只能开发人员去把项目打成一个war包,可能这个项目已经上线了,需要把服务关,在部署到服务器上,将项目启动起来,这个时候可能某个用户正在操作某些功能上的东西,如果你隔三差五的部署一下,这样的话对用户的体验也不好,自己也是烦的很,总是打包拖到服务器上。希望小型企业工作人员学习一下,配置可能复杂,但是你配置好了之后,你只需要把代码提交到Git或者Svn上,自动构建部署_docker 安装jenkins 无法安装git插件

【python初级】 ModuleNotFoundError: No module named paho_modulenotfounderror: no module named 'paho-程序员宅基地

文章浏览阅读8.2k次,点赞3次,收藏3次。【python初级】 ModuleNotFoundError: No module named paho1、背景2、解决1、背景python3在导入mqtt时报错,具体如下:Traceback (most recent call last): File "E:/E05_Project/mqtt_server.py", line 17, in <module> import paho.mqtt.client as mqttModuleNotFoundError: No modu_modulenotfounderror: no module named 'paho

fatal error: opencv2/freetype.hpp: 没有那个文件或目录 - opencv_contrib_没有 opencv2/freetype.hpp-程序员宅基地

文章浏览阅读5.1k次。fatal error: opencv2/freetype.hpp: 没有那个文件或目录 - opencv_contrib1. freetype.hpp fileopencv2https://docs.opencv.org/4.2.0/dc/d8f/freetype_8hpp.htmlopencv_contrib -> modules -> freetype -> include -> opencv2https://docs.opencv.org/3.2.0/dc/d8f/_没有 opencv2/freetype.hpp