爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      首页 知识中心 软件开发 文章详情页

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      2024-03-29 09:48:26 阅读次数:53

      kotlin,开发语言

      初识 Kotlin


      历史

      Kotlin由JetBrains公司开发设计,2011年公布第一版,2012年开源。

      2016年发布1.0正式版,并且JetBrains在IDEA加入对Kotlin的支持,安卓自此又有新的选择。

      2019年谷歌宣布Kotlin成为安卓第一开发语言,安卓程序员由java转Kotlin已经迫在眉睫。

      工作原理

      Java 虚拟机只认识 class 文件,并不关心是由什么文件编译来的, 因此当我们创造一个自己的语法规则时,再做一个对应的编译器,就可以让我们的语言跑在 Java 的虚拟机上。Kotlin 就是这个原理,运行前会先编译成 class,在给 Java 虚拟机运行。

      第一个Hello World!

      创建项目只需要注意以下几点即可(这里使用 Gradle 构建项目)

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      修改配置文件中的 JDK 版本(这里我使用的是 JDK8)

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      如下代码(Kotlin 以 main 方法作为程序的入口)

      fun main() {
          println("hello world!")
      }
      

      运行结果如下

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      接下来,进入语法的学习

      Kotlin 语法


      变量

      var 表示可变变量

      val 表示不可变变量

      a)由于 Kotlin 存在类型推导机制,因此不用声明具体的数据类型。当然也可以手动指定数据类型,如下代码

          var a = 1  //可变
          val b = 2  //不可变
          var c: Int = 1 //指定数据类型(Kotlin有类型推导机制,这里可以不用指明)
      

      他们的本质区别就类似 Java 中如下代码

          private static int a = 1;
          private static final int b = 2;
          private static int c = 3;

       Kotlin 这样设计是为了防止非 final 类型的滥用,也就是说,如果一个变量永远不会被修改,就有必要给他加上 final,让其他人看到代码更好理解。

      Ps:建议写代码时,可以先使用 val,如果真的需要修改,再改为 var

      b)如何查看 Kotlin 对应的 Java 代码?如下

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      基本数据类型

      Kotlin 不存在基本类型,全部都是对象类型

      Java基本类型 Kotlin对象类型 对象类型说明
      int Int 整型
      long Long 长整型
      short Short 短整型
      float Float 单精度浮点型
      double Double 双精度浮点型
      boolean Boolean 布尔型
      char Char 字符型
      byte Byte 字节型

      函数

      无参无返回值

      fun add1() {
      
      }
      

      有参有返回值,语法如下:

      fun 方法名(参数名: 类型): 返回值类型 { 函数体 }

      fun add2(a: Int, b: Int): Int {
          return a + b
      }
      

      当函数体只有一行代码时可以直接使用以下方式声明

      fun add3(a: Int, b: Int): Int = a + b

      Kotlin 存在类型推导,返回值类型也可省略

      fun add4(a: Int, b: Int) = a + b
      

      调用的的时候,直接写函数名即可

      fun add4(a: Int, b: Int) = a + b
      
      
      fun main() {
          println(add4(3, 5))
      }
      

      == 和 ===

      Kotlin 中的 == 等价于 Java 的 equals,比较的是对象里的内容(Kotlin 中只有对象类型,不存在值比较),而 ===  等价于 Java 中 == ,比较的是对象的引用.

      选择控制(if、when)

      if

      Kotlin 中的 if 和 Java 基本上没有区别

      例如,实现一个返回最大值的函数,有以下多种写法

      fun max1(a: Int, b: Int): Int {
          if(a > b) {
              return a
          }
          return b
      }
      
      fun max2(a: Int, b: Int): Int {
          return if(a > b) a else b  //if 也可以直接返回值
      }
      
      fun max3(a: Int, b: Int) = if(a > b) a else b
      

      when

      a)类似 Java 中的 switch 语句,可以进行选择控制

      如下代码

      fun whenTest(num: Int) {
          when(num) {
              1 -> println("1")
              2 -> println("2")
              3 -> println("3")
              4 -> println("4")
              else -> println("非法!") //else 可有可无
          }
      }
      

      解释:例如当 num 为 2 时,when 就会匹配 num 为 2,执行 println("2"),程序结束.  与 switch 不同的是,这里执行完 num 为 2 逻辑后,不需要 break,自动跳出 when 语句;如果 num 非 1、2、3、4,就会执行 else 逻辑.

      c)when 也支持执行代码块

      fun whenTest2(name: String) {
          when(name) {
              "1" ->  {
                  println("你好1")
                  println("你好2")
                  println("你好3")
              }
              "2" -> println("我好像作用不大")
              else -> println("非法")
          }
      }
      

      b)when 支持参数检查

      fun checkNumber(num: Number) {
          when (num) {
              is Int -> println("Int")
              is Double -> println("Double")
              else -> println("others")
          }
      }

      c)when 也可以不传递参数

      fun whenTest3(name: String) {
          when {
              name == "cyk" -> println("男")
              name == "lyj" -> println("女")
              else -> println("emm...")
          }
      }
      

      循环语句

      Kotlin 有两种循环方式:while 和 for-in

      while 和 Java 中的 while 没有区别(因此这里就不再赘述 while 了),而 for-in 则是对 for-each 的加强,舍弃了 for-i 的写法.

      对于 for-in 的写法,首先要明确一个 区间 的概念

          val range = 0..10 //代表区间 [0, 10],前闭后闭
      

      a)for-in 需要使用区间

      fun test1() {
          val range = 0..10 //前闭后闭
          for(i in range) { //也可以使用 for(i in 0..10)
              print("${i} ")
          }
      }
      

      b)0..10 表示双闭区间,如果想使用左闭右开,需要借助 until 关键字

      fun test2() {
          for(i in 0 until 10) { //前闭后开 [0, 10)
              print("${i} ")
          }
      }
      

      c)上面的代码类似于 i++,Kotlin 也支持跳步

      fun test3() {
          for(i in 0 until 10 step 2) {
              print("${i} ")
          }
      }
      

      d)以上实现都是升序,Kotlin也可以实现降序循环.

      fun test4() {
          for(i in 10 downTo 0) { //前闭后闭
              print("${i} ")
          }
      }
      

      for-in 还可以进行集合的遍历,后续再演示.

      通过 main 函数依次执行以上函数,如下:

      fun main() {
          test1()
          println("----------------------")
          test2()
          println("----------------------")
          test3()
          println("----------------------")
          test4()
          println("----------------------")
      }
      

      执行结果如下:

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      类和对象

      创建和使用

      创建一个 Person 类,具有 name 和 age 属性,showInfo 方法(打印信息),代码如下

      class Person {
          var name = ""
          var age = 0
          fun showInfo() {
              println("name: ${name}, age: ${age}")
          }
      }
      

      对象的创建和使用如下

          val person = Person()
           = "cyk"
          person.age = 20
          person.showInfo()
      

      继承

      声明 Person 类,声明 Student 类并继承 Person 类

      open class Person {
          var name = ""
          var age = 0
          fun showInfo() {
              println("name: ${name}, age: ${age}")
          }
      }
      
      class Student : Person() { //被继承的类需要使用 open 修饰(需要在 Person 类前添加 open)
          var num = 1
          var grade = 0
          fun study() {
              println("student: ${name} do homework")
          }
      }
      

      注意:Person 类默认情况下不能被继承的,因为默认情况下类似于 Java 中的 final 修饰的,因此。这里需要使用 open 关键字才可以解除 final。(否则 IDEA 自动语法检测报错)

      构造

      主构造

      在 Kotlin 中,分为主构造和次构造。

      a)主构造直接写在类后面即可,如下代码

      //主构造(直接写在类后面)
      class Student(val num: Int, val grade: String) {
      }
      

      创建方式如下

          var student = Student(1, "三年二班")
      

      b)当 Person 和 Student 都有主构造,并且 Student 继承了 Person 类时,就需要修改 Student 的主构造,附带上父类的参数(此时不需要指定 var 或 val),如下代码

      open class Person(val name: String, val age: Int) {
      }
      
      class Student(val num: Int, val grade: String, name: String, age: Int):
      Person(name, age) {
      }
      
      fun main() {
          //创建 Student 对象
          var student = Student(1, "三年二班", "cyk", 20)
      }

      c)如果在构造时需要进行一些特殊处理怎么办?Kotlin 中提供了 init 结构体,主构造的逻辑可以在 init 中进行处理,如下代码

      class Student(val num: Int, val grade: String, name: String, age: Int):
      Person(name, age) {
          init {
              println("对主构造中的参数进行了一些特殊处理")
              println("...")
          }
      }
      

      如果一个类想要有多种构造方法,该怎么做?这就需要用到次构造

      次构造

      a)constructor 中只需要指定创建该对象时需要的参数(也就是说,无参构造无需指定任何参数),this 中就表明了需要什么样的参数,代码如下

      class Student(val num: Int, val grade: String, name: String, age: Int):
      Person(name, age) {
          //两个参数的构造
          constructor(name: String, age: Int) : this(0, "", name, age){
      
          }
          //无参构造
          constructor(): this(0, "", "", 0) {
      
          }
      }
      

      通过以上构造,就有三种创建 Student 对象的方式,如下

          //创建 Student 对象
          var student1 = Student(1, "三年二班", "cyk", 20)
          var student2 = Student("cyk", 20)
          var student3 = Student()
      

       b)如果类不要主构造,那么继承类也无需通过 () 的方式初始化参数,子类次构造可以通过 super 来初始化父类的构造器

      class Student: Person {
          constructor(name: String, age: Int, grade: String) : super(name, age){
      
          }
      }
      

      创建对象如下

          //创建 Student 对象
          Student("cyk", 20, "三年二班")
      

      接口

      定义

      和 Java 基本没什么区别

      interface Study {
      
          fun study()
          fun sleep()
          fun doHomework()
      
      }

      Kotlin 支持接口的方法有默认实现(JDK1.8以后支持此功能),如果有默认实现,则继承类可以重写该方法,也可以不重写,若重写,以重写为主,否则执行默认实现.

      interface Study {
          fun study() {
              println("学习ing ~")
          }
          fun doHomework()
      }
      
      class Student(val name: String, val age: Int): Study, Other { //多个接口只需要使用逗号隔开
      
      //    override fun study() { //可以不重写~ 若重写,则执行此方法
      //        println("学习!")
      //    }
      
          override fun doHomework() {
              TODO("Not yet implemented")
          }
      
          override fun sleep() {
              TODO("Not yet implemented")
          }
      
      }
      

      实现

      Kotlin 和 Java 一样,支持一个类实现多个接口,需要实现所有方法(若接口的方法有默认实现,则可以不重写该方法)

      class Student(val name: String, val age: Int): Study, Other { //多个接口只需要使用逗号隔开
      
          override fun study() {
              TODO("Not yet implemented") //TODO 表明该方法未被实现,因此实现该方法时,需要将这一行删除
          }
      
          override fun doHomework() {
              TODO("Not yet implemented")
          }
      
          override fun sleep() {
              TODO("Not yet implemented")
          }
      
      }
      

      权限修饰符

      Java 和 Kotlin 的异同点.

      需要注意的是,Kotlin 中移除了 default,引入了 internal 修饰.

      修饰符 Java Kotlin
      public 所有类可见 所有类可见(默认)
      private 当前类可见 当前类可见
      protected 当前类,子类,同包下类可见 当前类,子类可见
      default 同包下类可见(默认) 无
      internal 无 同模块下的类可见

      使用方式和 Java 没什么区别

      //类上
      public open class Solution(val name: String, val number: Int) {
      
          //变量上
          private val key = 1
      
          //方法上
          private fun test() {
      
          }
      
      }
      

      数据类(实体类)和单例类

      数据类

      数据类则只处理数据相关(实体类),与Java Bean类似,通常需要实现其get,set,hashCode,equals,toString等方法

      例如一个用户实体类,Java 代码如下:

      public class UserJava {
      
          private Integer id;
          private String username;
          private String password;
      
          public UserJava() {
          }
      
          public UserJava(Integer id, String username, String password) {
              this.id = id;
              this.username = username;
              this.password = password;
          }
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public String getUsername() {
              return username;
          }
      
          public void setUsername(String username) {
              this.username = username;
          }
      
          public String getPassword() {
              return password;
          }
      
          public void setPassword(String password) {
              this.password = password;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              UserJava userJava = (UserJava) o;
              return Objects.equals(id, userJava.id) && Objects.equals(username, userJava.username) && Objects.equals(password, userJava.password);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(id, username, password);
          }
      
          @Override
          public String toString() {
              return "UserJava{" +
                      "id=" + id +
                      ", username='" + username + '\'' +
                      ", password='" + password + '\'' +
                      '}';
          }
      
      }
      

      而 Kotlin 实现以上实体类,只需要一个新建一个 kt 文件,选择创建 Data Class 类型,一行代码即可搞定(虽然一行可以搞定,但是建议还是分行写,可读性高),如下

      data class UserKotlin(
          val id: Int,
          val username: String,
          val password: String
      )
      

      若无data关键字,上述方法(hashCode,equals,toString)无法正常运行.

      单例类

      Java 最广泛使用的单例如下

      public class Singleton {
      
          private static final Singleton singleton = new Singleton();
      
          public static Singleton getSingleton() {
              return singleton;
          }
      
          private Singleton() {
      
          }
      
          /**
           * 测试方法
           */
          public void test() {
      
          }
      
      }
      

      而 Kotlin 中实现单例模式只需要 object 修饰即可,如下代码

      object Singleton {
          fun test() {
              println("hello")
          }
      }
      

       使用如下

      fun main() {
          Singleton.test() //等同于 Java 中 Singleton.getSingleton.test
      }
      

      集合

      List

      fun listTest() {
          //常规创建
          //list1 类型:ArrayList<Int>
          var list1 = ArrayList<Int>()
          list1.add(1)
          list1.add(2)
          list1.add(3)
      
          //创建不可变类型,创建后不可进行增加和删除操作,只能进行查询
          //list2 类型: List<Int>
          val list2 = listOf<Int>(1, 2, 3)
      
          //创建可变类型,创建后可以继续增删改查
          //list3 类型: MutableList<Int>
          var mutableListOf = mutableListOf<Int>()
          mutableListOf.add(1)
          mutableListOf.add(2)
      
          for(value in list1) {
              print("$value ")
          }
      }
      

      Set

      fun setTest() {
          //常规创建
          //set1 类型: HashSet<Int>
          var set1 = HashSet<Int>()
          set1.add(1)
          set1.add(2)
          set1.add(3)
      
          //创建不可变类型,创建后不可进行增加和删除操作,只能进行查询
          //set2 类型: Set<Int>
          var set2 = setOf<Int>(1,2,3)
      
          //创建可变类型,创建后可以继续增删改查
          //set3 类型: MutableList<Int>
          var set3 = mutableSetOf<Int>()
          set3.add(1)
      
          for(value in set1) {
              print("$value ")
          }
      }
      

      Map

      fun mapTest() {
          //常规创建
          //map1 类型: HashMap<String, String>
          var map1 = HashMap<String, String>()
          map1.put("name", "cyk")
          map1.put("age", "20")
          //Kotlin 中 map 支持下表的赋值和访问
          map1["id"] = "1"
          map1["gender"] = "男"
      
          //创建不可变类型,创建后不可进行增加和删除操作,只能进行查询
          //map2 类型: mapOf<String, String>
          var map2 = mapOf<String, String>("name" to "cyk", "age" to "20")
      
          //创建可变类型,创建后可以继续增删改查
          //set3 类型: MutableList<Int>
          var map3 = mutableMapOf<String, String>()
          map3.put("name", "cyk")
          map3.put("age", "20")
          map3["id"] = "1"
          map3["gender"] = "男"
      
          for((key, value) in map3) {
              println("$key   $value");
          }
      
      }
      

      Lambda 的使用

      基本认识

      方法在传递参数时都是普通变量,而Lambda可以传递一段代码

      Lambda表达式的语法结构

      {参数名1: 参数类型, 参数名2:参数类型 -> 函数体}

      list.maxByOrNull

      Kotlin 的 list 提供了 maxByOrNull 函数,参数就是一个 lambda 表达式,用来返回当前 list 中 xx 最大的元素,xx 是我们定义的条件,可能为长度,可能是别的.

      这里拿长度来举例,例如我有一个 list,现在要找出 list 中长度最大的元素,如下代码

      fun test1() {
          //找出 list 中长度最大的元素
          val list = listOf<String>("a", "abc", "abcd", "ab")
      
          //写法1
          val lambda = {str: String -> str.length}
          var maxStr = list.maxByOrNull(lambda)
      
          //写法2
          maxStr = list.maxByOrNull {str: String -> str.length}
      
          //写法3
          maxStr = list.maxByOrNull() {str: String -> str.length}
      
          //写法4: 基于 Kotlin 的类型推导机制,Lambda 可以省略参数类型
          maxStr = list.maxByOrNull {str -> str.length}
      
          //写法5: 若 Lambda 只有一个参数,可以使用 it 代替参数名
          maxStr = list.maxByOrNull {it.length}
      
          println(maxStr)
      }
      

      list.map、list.filter、list.any、list.all

          //创建一个 list,后续操作都以此展开
          var list = listOf("a", "ab", "abc", "abcd")
      
          //map 用于返回一个新的集合,例如将集合中的元素都换成大写
          val mapList = list.map { it.toUpperCase() }
      
          //filter 过滤,返回一个新集合,例如对集合中的元素进行筛选(筛选出长度大于 3 的元素)
          val filterList = list.filter { it.length > 3 }
      
          //any 返回 Boolean,用来判断集合中是否有元素满足 Lambda 条件,只要有任意一个满足返回 true,否则返回 false
          val anyList = list.any {it.length > 3} //存在一个字符串长度大于 3,因此返回 true
      
          //all 返回 Boolean,集合中元素是否全部都满足 Lambda 的条件,全都满足才返回true,有任意一个不满足就返回 false
          val allList = list.all { it.length <= 4 } //所有元素长度都满足字符串长度小于等于 4, 因此返回 true
      

      空指针检查机制

      国外统计程序出现最多的异常为空指针异常,Kotlin存在编译时检查系统帮助我们发现空指针异常。

      Kotlin把空指针异常的检查提前到了编译期,若空指针则编译期就会崩溃,避免在运行期出现问题,因此在 Kotlin 中,任何变量和参数都不允许为空.

      a)参数为空,报错

      fun study(study: Study) {
          study.doHomework() //正确
          study.readBook()   //正确
      }
      
      fun main() {
          study(null) //报错
          study(Study()) //正确
      }

      b)如果有需求就是要传入 null,那么可以通过 "?" 来对传入可能为 null 的参数在类型后进行声明

      fun study(study: Study?) {
          study.doHomework() //报错
          study.readBook()   //报错
      }
      
      fun main() {
          study(null) //正确
          study(Study()) //正确
      }

      c)?的意思则是当前参数可为空,如果可为空的话,则此对象调用的方法必须要保证对象不为空,上面代码没有保证,则报错,修改如下

      fun study(study: Study?) {
          if(study != null) {
              study.doHomework() //正确
              study.readBook()   //正确
          }
      }
      
      fun main() {
          study(null) //正确
          study(Study()) //正确
      }

      辅助判空工具

      ?.

      表示 ?前面对象不为空才执行.后面的方法

      fun study(study: Study?) {
          study?.doHomework() 
          study?.readBook()   
      }
      

      ?:

      表示 ?前不为空则返回问号前的值,为空则返回:后的值

      fun test1(a: Int, b: Int) {
          val c = a ?: b //a 不为空返回 a,为空返回 b
      }
      

      !!

      如果想要强行通过编译,就需要依靠!!,这时就是程序员来保证安全

      fun study(study: Study?) {
          study!!.doHomework()
          study!!.readBook()
      }
      

      let 函数

      let 是一个函数,提供了函数式 API 接口,会将调用者作为参数传递到 Lambda 表达式,调用之后会立马执行 Lambda 表达式的逻辑.

      aaa.let { it ->  // it 就是 aaa(调用者)
          //执行业务逻辑
      }

      例如,原本函数的逻辑是这样的

      fun study(study: Study?) {
          if(study != null) {
              study.doHomework()
              study.readBook()
          }
      }
      

      通过 let 则可以改为

      fun testLet(study: Study?) {
          //此时通过 ?.就保证了 study 不为空的时候才会执行 let 函数
          study?.let { it ->
              it.doHomework()
              it.readBook()
          }
      }
      

      a)好处1:最常用的就是使用 let 函数处理一个可 null 的对象做统一判空处理(例如上述代码).

      b)好处2:在有限的范围内引入局部变量提高代码的可读性.

      内嵌表达式

      以前我们拼接字符串可能是这样的,如下

      fun printTest() {
          val name = "cyk"
          val age = 20
          println("name: " + name + ",age: " + age)
      }
      

      a)通过 Kotlin 提供的内嵌表达式就不需要拼接了,只需要如下代码

      fun printTest() {
          val name = "cyk"
          val age = 20
          println("name: $name, age: $age")
      }
      

      b)内敛表达式还支持复杂的操作,语法为 ${表达式}

      fun printTest() {
          val name = "cyk"
          val age = 20
          println("name: ${if (2 > 1) "cyk" else "lyj"}, age: $age")
      }
      

      函数参数默认值

      a)Kotlin 支持函数默认值,如下

      fun study(name: String, age: String = "男") {
          println("name: $name, age: $age")
      }
      
      fun main() {
          study("cyk")
          study("lyj", "女")
      }
      

      运行结果

      【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

      b)如果方法的第一个参数设置成默认值,那么传入的第一个实参就会匹配第一个形参,因此就可能出现以下问题.

      fun study(age: String = "男", name: String) {
          println("name: $name, age: $age")
      }
      
      fun main() {
          study("cyk") //报错
      }
      

      你可能会这样想:因为第一个设置了默认值,而我又想让我传入的实参就不匹配设置了默认值的形参了...

      如果一定要这么做,Kotlin 也提供了键值对的形式来匹配形参,解决上述问题,如下

      fun study(age: String = "男", name: String) {
          println("name: $name, age: $age")
      }
      
      fun main() {
          study(name = "cyk") //报错
      }
      
      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/CYK_byte/article/details/135119913,作者:陈亦康,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:python turtle库 绘制 红旗 代码及效果图

      下一篇:深入学习 Redis - 虽然是单线程,为啥效率这么高,速度这么快呢?

      相关文章

      2025-04-07 10:28:48

      Python高维统计建模变量选择:SCAD平滑剪切绝对偏差惩罚、Lasso惩罚函数比较

      变量选择是高维统计建模的重要组成部分。许多流行的变量选择方法,例如 LASSO,都存在偏差。

      2025-04-07 10:28:48
      python , r语言 , 后端 , 开发语言
      2025-04-07 10:20:39

      ​Python是如何表示时间的?2个模块、3种方式,1文看懂~

      ​Python是如何表示时间的?2个模块、3种方式,1文看懂~

      2025-04-07 10:20:39
      python , 开发语言 , 时间戳 , 结构化
      2025-04-01 10:28:37

      找到非负数组中拥有“最大或的结果“的最短子数组,返回最短长度。

      找到非负数组中拥有"最大或的结果"的最短子数组,返回最短长度。

      2025-04-01 10:28:37
      java代码 , rust , 后端 , 开发语言 , 数组
      2025-04-01 09:21:49

      【C语言】探索数据的存储(上篇)

      【C语言】探索数据的存储(上篇)

      2025-04-01 09:21:49
      c语言 , 后端 , 开发语言
      2025-03-31 08:49:25

      MFC编程 -- 判断是否按下ctrl和shift键

      MFC编程 -- 判断是否按下ctrl和shift键

      2025-03-31 08:49:25
      c++ , mfc , 开发语言
      2025-03-24 08:53:06

      【编译原理实验】 -- 词法分析程序设计原理与实现(C语言实现)

      【编译原理实验】 -- 词法分析程序设计原理与实现(C语言实现)

      2025-03-24 08:53:06
      c语言 , 开发语言
      2025-03-24 08:45:46

      Android 判断是否有可用摄像头(前置,后置,USB外接)

      Android 判断是否有可用摄像头(前置,后置,USB外接)

      2025-03-24 08:45:46
      Android , Java , kotlin , USB
      2025-03-12 09:32:31

      Android Compose的基本使用

      Android Compose的基本使用

      2025-03-12 09:32:31
      kotlin , View , 事件 , 创建
      2025-01-17 09:15:58

      小团生日收到妈妈送的两个一模一样的数列作为礼物! 他很开心的把玩,不过不小心没拿稳将数列摔坏了! 现在他手上的两个数列分别为A和B,长度分别为n和m。

      小团生日收到妈妈送的两个一模一样的数列作为礼物! 他很开心的把玩,不过不小心没拿稳将数列摔坏了! 现在他手上的两个数列分别为A和B,长度分别为n和m。

      2025-01-17 09:15:58
      rust , 后端 , 开发语言 , 递归
      2025-01-17 09:15:58

      一场电影开始和结束时间可以用一个小数组来表示[“07:30“,“12:00“],已知有2000场电影开始和结束都在同一天,这一天从00:00开始到23:59结束,一定要选3场完全不冲突的电影来观看,返回最大的观影时间。

      一场电影开始和结束时间可以用一个小数组来表示[“07:30”,“12:00”],已知有2000场电影开始和结束都在同一天,这一天从00:00开始到23:59结束,一定要选3场完全不冲突的电影来观看,返回最大的观影时间。

      2025-01-17 09:15:58
      golang , 开发语言 , 数组 , 空间复杂度 , 算法
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5232819

      查看更多

      最新文章

      Python高维统计建模变量选择:SCAD平滑剪切绝对偏差惩罚、Lasso惩罚函数比较

      2025-04-07 10:28:48

      ​Python是如何表示时间的?2个模块、3种方式,1文看懂~

      2025-04-07 10:20:39

      找到非负数组中拥有“最大或的结果“的最短子数组,返回最短长度。

      2025-04-01 10:28:37

      【C语言】探索数据的存储(上篇)

      2025-04-01 09:21:49

      MFC编程 -- 判断是否按下ctrl和shift键

      2025-03-31 08:49:25

      【编译原理实验】 -- 词法分析程序设计原理与实现(C语言实现)

      2025-03-24 08:53:06

      查看更多

      热门文章

      kotlin创建简单多线程的3种方式

      2023-04-17 09:39:23

      java学习第三天笔记-运算符10-短路逻辑运算符56

      2023-04-07 06:41:50

      kotlin匿名内部类与接口实现

      2023-04-18 14:15:13

      Filter&Listener笔记

      2023-02-22 08:37:42

      ESLint:可组装的JavaScript和JSX检查工具

      2023-02-23 07:57:25

      java学习第二天笔记-java基础概念08-数据类型-30

      2023-04-10 08:53:07

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      【QT】QT调色板类

      前端项目实战245-ant design radio设置默认值

      第一季:7Spring Bean的作用域之间有什么区别【Java面试题】

      【QT】QT不规则窗体效果——遮罩

      java8-巩固练习

      前端项目实战225-ant design 5确认框

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号