Kotlin:2.0.0 的新特性

科技颠覆者  金牌会员 | 2024-10-10 00:23:16 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 686|帖子 686|积分 2058

一、概述

kotlin 2.0.0版本英文官方文档
   The Kotlin 2.0.0 release is out and the new Kotlin K2 compiler is Stable! Additionally, here are some other highlights:
Kotlin 2.0.0发布了,新的Kotlin K2编译器已经稳定了。此外,以下是其他一些亮点:

  

  • New Compose compiler Gradle plugin
  • Generation of lambda functions using invokedynamic
  • The kotlinx-metadata-jvm library is now Stable
  • Monitoring GC performance in Kotlin/Native with signposts on Apple platforms
  • Resolving conflicts in Kotlin/Native with Objective-C methods
  • Support for named export in Kotlin/Wasm
  • Support for unsigned primitive types in functions with @JsExport in Kotlin/Wasm
  • Optimize production builds by default using Binaryen
  • New Gradle DSL for compiler options in multiplatform projects
  • Stable replacement of the enum class values generic function
  • Stable AutoCloseable interface
  二、局部变量和进一步的作用域

   从前,假如一个变量在if条件中被盘算为非空,则该变量将被智能逼迫转换。关于这个变量的信息将在if块的范围内进一步共享。

但是,假如在if条件之外声明变量,则在if条件中无法获得有关该变量的信息,因此无法对其进行智能逼迫转换。这种行为在when表达式和while循环中也可以看到。

从Kotlin 2.0.0开始,假如在if、when或while条件中使用一个变量之前声明它,那么编译器网络的关于该变量的任何信息都可以在相应的块中进行智能转换。

当您想要将布尔条件提取到变量中时,这大概很有用。然后,您可以为变量指定一个有意义的名称,这将提高代码的可读性,并使以后在代码中重用该变量成为大概。例如:
  三、使用逻辑或运算符进行范例查抄

   在Kotlin 2.0.0中,假如您将对象的范例查抄与or操作符(||)结合起来,则会对其最接近的公共超范例进行智能逼迫转换。在此更改之前,总是对Any范例进行智能逼迫转换。

在这种情况下,您仍旧必须手动查抄对象范例,然后才气访问其任何属性或调用其函数。例如:
  1. class Cat {
  2.     //咕噜声
  3.     fun purr() {
  4.         print("cat Purr purr")
  5.     }
  6. }
  7. fun petAnimal(animal: Any) {
  8.     val isCat = animal is Cat
  9.     if (isCat) {
  10.         //在Kotlin 2.0.0中,编译器可以访问关于isCat的信息,
  11.         // 所以它知道动物被智能铸造为Cat类型。因此,可以调用purr()函数。
  12.         
  13.         //在Kotlin 1.9.20中,编译器不知道
  14.         //调用purr()函数触发错误。
  15.         // animal.purr()
  16.         // 2.0之前的版本,
  17.         // (animal as Cat).purr()
  18.     }
  19. }
  20. fun main() {
  21.     val ketty = Cat()
  22.     petAnimal(ketty)
  23. }
复制代码
四、使用逻辑或运算符进行范例查抄

   在Kotlin 2.0.0中,假如您将对象的范例查抄与or操作符(||)结合起来,则会对其最接近的公共超范例进行智能逼迫转换。在此更改之前,总是对Any范例进行智能逼迫转换。

在这种情况下,您仍旧必须手动查抄对象范例,然后才气访问其任何属性或调用其函数。例如:
  1. interface Status {
  2.     fun signal() {}
  3. }
  4. interface Ok : Status
  5. interface Postponed : Status
  6. interface Declined : Status
  7. fun signalCheck(signalStatus: Any) {
  8.     if (signalStatus is Postponed || signalStatus is Declined) {
  9.         // signalStatus is smart-cast to a common supertype Status;  signalStatus被智能转换为一个普通的超类型Status
  10. //        signalStatus.signal()
  11.         // Prior to Kotlin 2.0.0, signalStatus is smart cast; 在Kotlin 2.0.0之前,signalStatus是智能强制转换
  12.         // to type Any, so calling the signal() function triggered an ; 输入Any,所以调用signal()函数会触发一个
  13.         // Unresolved reference error. The signal() function can only; 未解析的引用错误。signal()函数只能
  14.         // be called successfully after another type check: ; 在另一次类型检查后被成功调用:
  15.         // check(signalStatus is Status)
  16.         // signalStatus.signal()
  17.     }
  18. }
复制代码
五、内联函数

   在Kotlin 2.0.0中,K2编译器以差别的方式处理内联函数,允许它结合其他编译器分析来确定智能逼迫转换是否安全。

详细来说,内联函数现在被视为具有隐式的callsInPlace契约。这意味着任何传递给内联函数的lambda函数都会被就地调用。由于lambda函数是就地调用的,编译器知道lambda函数不会走漏对其函数体中包含的任何变量的引用。

编译器使用这些知识和其他编译器分析来决定智能转换捕捉的任何变量是否安全。例如:
  1. interface Processor {
  2.     fun process()
  3. }
  4. inline fun inlineAction(f: () -> Unit) = f()
  5. fun nextProcessor(): Processor? = null
  6. fun runProcessor(): Processor? {
  7.     var processor: Processor? = null
  8.     inlineAction {
  9.         // In Kotlin 2.0.0, the compiler knows that processor
  10.         // is a local variable, and inlineAction() is an inline function, so
  11.         // references to processor can't be leaked. Therefore, it's safe
  12.         // to smart-cast processor.
  13.         // If processor isn't null, processor is smart-cast
  14.         if (processor != null) {
  15.             // The compiler knows that processor isn't null, so no safe call
  16.             // is needed
  17.             processor.process()
  18.             // In Kotlin 1.9.20, you have to perform a safe call:
  19.             // processor?.process()
  20.         }
  21.         processor = nextProcessor()
  22.     }
  23.     return processor
  24. }
复制代码
六、函数范例的属性

   在Kotlin的早期版本中,有一个bug意味着带有函数范例的类属性不能智能逼迫转换。我们在Kotlin 2.0.0和K2编译器中修复了这个行为。例如:
  1. class Holder(val provider: (() -> Unit)?) {
  2.     fun process() {
  3.         // In Kotlin 2.0.0, if provider isn't null, then
  4.         // provider is smart-cast
  5.         if (provider != null) {
  6.             // The compiler knows that provider isn't null
  7.             provider()
  8.             // In 1.9.20, the compiler doesn't know that provider isn't
  9.             // null, so it triggers an error:
  10.             // Reference has a nullable type '(() -> Unit)?', use explicit '?.invoke()' to make a function-like call instead
  11.         }
  12.     }
  13. }
复制代码
  假如重载调用操作符,也适用此更改。例如:
  1. interface Provider {
  2.     operator fun invoke()
  3. }
  4. interface Processor : () -> String
  5. class Holder(val provider: Provider?, val processor: Processor?) {
  6.     fun process() {
  7.         if (provider != null) {
  8.             provider()
  9.             // In 1.9.20, the compiler triggers an error:
  10.             // Reference has a nullable type 'Provider?' use explicit '?.invoke()' to make a function-like call instead
  11.         }
  12.     }
  13. }
复制代码
七、非常处理

   在Kotlin 2.0.0中,我们对非常处理进行了改进,以便将智能逼迫转换信息传递给catch和finally块。此更改使代码更安全,由于编译器会跟踪对象是否具有可空范例。例如:
  1. fun testString() {
  2.     var stringInput: String? = null
  3.     // stringInput is smart-cast to String type
  4.     stringInput = ""
  5.     try {
  6.         // The compiler knows that stringInput isn't null
  7.         println(stringInput.length)
  8.         // 0
  9.         // The compiler rejects previous smart cast information for
  10.         // stringInput. Now stringInput has the String? type.
  11.         stringInput = null
  12.         // Trigger an exception
  13.         if (2 > 1) throw Exception()
  14.         stringInput = ""
  15.     } catch (exception: Exception) {
  16.         // In Kotlin 2.0.0, the compiler knows stringInput
  17.         // can be null, so stringInput stays nullable.
  18.         println(stringInput?.length)
  19.         // null
  20.         println("捕获到的异常信息:$exception")
  21.         // In Kotlin 1.9.20, the compiler says that a safe call isn't
  22.         // needed, but this is incorrect.
  23.     }finally {
  24.         println("执行了 finally 逻辑")
  25.     }
  26. }
复制代码
  运行结果

  八、kt_200.kt文件代码

  1. package com.example.test.ktversion// https://kotlinlang.org/docs/whatsnew20.htmlclass Cat {    //咕噜声    fun purr() {        print("cat Purr purr")    }}fun petAnimal(animal: Any) {    val isCat = animal is Cat    if (isCat) {        //在Kotlin 2.0.0中,编译器可以访问关于isCat的信息,        // 所以它知道动物被智能铸造为Cat范例。因此,可以调用purr()函数。        //在Kotlin 1.9.20中,编译器不知道        //调用purr()函数触发错误。        // animal.purr()        // 2.0之前的版本,        // (animal as Cat).purr()    }}// Type checks with logical or operator  将对象的范例查抄与or操作符(||)结合起来interface Status {
  2.     fun signal() {}
  3. }
  4. interface Ok : Status
  5. interface Postponed : Status
  6. interface Declined : Status
  7. fun signalCheck(signalStatus: Any) {
  8.     if (signalStatus is Postponed || signalStatus is Declined) {
  9.         // signalStatus is smart-cast to a common supertype Status;  signalStatus被智能转换为一个普通的超类型Status
  10. //        signalStatus.signal()
  11.         // Prior to Kotlin 2.0.0, signalStatus is smart cast; 在Kotlin 2.0.0之前,signalStatus是智能强制转换
  12.         // to type Any, so calling the signal() function triggered an ; 输入Any,所以调用signal()函数会触发一个
  13.         // Unresolved reference error. The signal() function can only; 未解析的引用错误。signal()函数只能
  14.         // be called successfully after another type check: ; 在另一次类型检查后被成功调用:
  15.         // check(signalStatus is Status)
  16.         // signalStatus.signal()
  17.     }
  18. }
  19. // Inline functionsinterface Processor {    fun process()}inline fun inlineAction(f: () -> Unit) = f()fun nextProcessor(): Processor? = nullfun runProcessor(): Processor? {    var processor: Processor? = null    inlineAction {        // In Kotlin 2.0.0, the compiler knows that processor ;  在Kotlin 2.0.0中,编译器知道这个处理器        // is a local variable, and inlineAction() is an inline function, so ; 是一个局部变量,而inlineAction()是一个内联函数,所以        // references to processor can't be leaked. Therefore, it's safe ; 对处理器的引用不能泄露。因此,它是安全的        // to smart-cast processor. ; 到智能转换处理器。        // If processor isn't null, processor is smart-cast; 假如processor不为空,则processor是smart-cast        if (processor != null) {            // The compiler knows that processor isn't null, so no safe call; 编译器知道处理器不是null,所以没有安全调用            // is needed ; 需要//            processor.process()            // In Kotlin 1.9.20, you have to perform a safe call:            // processor?.process()        }        processor = nextProcessor()    }    return processor}// Properties with function types  函数范例的属性class Holder(val provider: (() -> Unit)?) {    fun process() {        // In Kotlin 2.0.0, if provider isn't null, then        // provider is smart-cast        if (provider != null) {            // The compiler knows that provider isn't null//            provider()            // In 1.9.20, the compiler doesn't know that provider isn't            // null, so it triggers an error:            // Reference has a nullable type '(() -> Unit)?', use explicit '?.invoke()' to make a function-like call instead        }    }}//This change also applies if you overload your invoke operator. For example:interface Provider {    operator fun invoke()}interface Processor2 : () -> Stringclass Holder2(val provider: Provider?, val processor: Processor2?) {    fun process() {        if (provider != null) {//            provider()            // In 1.9.20, the compiler triggers an error:            // Reference has a nullable type 'Provider?' use explicit '?.invoke()' to make a function-like call instead        }    }}// 非常处理fun testString() {
  20.     var stringInput: String? = null
  21.     // stringInput is smart-cast to String type
  22.     stringInput = ""
  23.     try {
  24.         // The compiler knows that stringInput isn't null
  25.         println(stringInput.length)
  26.         // 0
  27.         // The compiler rejects previous smart cast information for
  28.         // stringInput. Now stringInput has the String? type.
  29.         stringInput = null
  30.         // Trigger an exception
  31.         if (2 > 1) throw Exception()
  32.         stringInput = ""
  33.     } catch (exception: Exception) {
  34.         // In Kotlin 2.0.0, the compiler knows stringInput
  35.         // can be null, so stringInput stays nullable.
  36.         println(stringInput?.length)
  37.         // null
  38.         println("捕获到的异常信息:$exception")
  39.         // In Kotlin 1.9.20, the compiler says that a safe call isn't
  40.         // needed, but this is incorrect.
  41.     }finally {
  42.         println("执行了 finally 逻辑")
  43.     }
  44. }
  45. fun main() {    val ketty = Cat()    petAnimal(ketty)    testString()}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

科技颠覆者

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表