Kotlin:2.0.0 的新特性

news/2024/12/21 20:31:29/

一、概述

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类型进行智能强制转换。

在这种情况下,您仍然必须手动检查对象类型,然后才能访问其任何属性或调用其函数。例如:

class Cat {//咕噜声fun purr() {print("cat Purr purr")}
}fun petAnimal(animal: Any) {val isCat = animal is Catif (isCat) {//在Kotlin 2.0.0中,编译器可以访问关于isCat的信息,// 所以它知道动物被智能铸造为Cat类型。因此,可以调用purr()函数。//在Kotlin 1.9.20中,编译器不知道//调用purr()函数触发错误。// animal.purr()// 2.0之前的版本,// (animal as Cat).purr()}
}fun main() {val ketty = Cat()petAnimal(ketty)
}

四、使用逻辑或运算符进行类型检查

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

在这种情况下,您仍然必须手动检查对象类型,然后才能访问其任何属性或调用其函数。例如:

interface Status {fun signal() {}
}
interface Ok : Status
interface Postponed : Status
interface Declined : Statusfun signalCheck(signalStatus: Any) {if (signalStatus is Postponed || signalStatus is Declined) {// signalStatus is smart-cast to a common supertype Status;  signalStatus被智能转换为一个普通的超类型Status
//        signalStatus.signal()// Prior to Kotlin 2.0.0, signalStatus is smart cast; 在Kotlin 2.0.0之前,signalStatus是智能强制转换// to type Any, so calling the signal() function triggered an ; 输入Any,所以调用signal()函数会触发一个// Unresolved reference error. The signal() function can only; 未解析的引用错误。signal()函数只能// be called successfully after another type check: ; 在另一次类型检查后被成功调用:// check(signalStatus is Status)// signalStatus.signal()}
}

五、内联函数

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

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

编译器使用这些知识和其他编译器分析来决定智能转换捕获的任何变量是否安全。例如:

interface Processor {fun process()
}inline fun inlineAction(f: () -> Unit) = f()fun nextProcessor(): Processor? = nullfun runProcessor(): Processor? {var processor: Processor? = nullinlineAction {// In Kotlin 2.0.0, the compiler knows that processor// is a local variable, and inlineAction() is an inline function, so// references to processor can't be leaked. Therefore, it's safe// to smart-cast processor.// If processor isn't null, processor is smart-castif (processor != null) {// The compiler knows that processor isn't null, so no safe call// is neededprocessor.process()// In Kotlin 1.9.20, you have to perform a safe call:// processor?.process()}processor = nextProcessor()}return processor
}

六、函数类型的属性

在Kotlin的早期版本中,有一个bug意味着带有函数类型的类属性不能智能强制转换。我们在Kotlin 2.0.0和K2编译器中修复了这个行为。例如:

class Holder(val provider: (() -> Unit)?) {fun process() {// In Kotlin 2.0.0, if provider isn't null, then// provider is smart-castif (provider != null) {// The compiler knows that provider isn't nullprovider()// 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}}
}

如果重载调用操作符,也适用此更改。例如:

interface Provider {operator fun invoke()
}interface Processor : () -> Stringclass Holder(val provider: Provider?, val processor: Processor?) {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}}
}

七、异常处理

在Kotlin 2.0.0中,我们对异常处理进行了改进,以便将智能强制转换信息传递给catch和finally块。此更改使代码更安全,因为编译器会跟踪对象是否具有可空类型。例如:

fun testString() {var stringInput: String? = null// stringInput is smart-cast to String typestringInput = ""try {// The compiler knows that stringInput isn't nullprintln(stringInput.length)// 0// The compiler rejects previous smart cast information for// stringInput. Now stringInput has the String? type.stringInput = null// Trigger an exceptionif (2 > 1) throw Exception()stringInput = ""} catch (exception: Exception) {// In Kotlin 2.0.0, the compiler knows stringInput// can be null, so stringInput stays nullable.println(stringInput?.length)// nullprintln("捕获到的异常信息:$exception")// In Kotlin 1.9.20, the compiler says that a safe call isn't// needed, but this is incorrect.}finally {println("执行了 finally 逻辑")}
}

运行结果
在这里插入图片描述

八、kt_200.kt文件代码

package com.example.test.ktversion// https://kotlinlang.org/docs/whatsnew20.html
class Cat {//咕噜声fun purr() {print("cat Purr purr")}
}fun petAnimal(animal: Any) {val isCat = animal is Catif (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 {fun signal() {}
}
interface Ok : Status
interface Postponed : Status
interface Declined : Statusfun signalCheck(signalStatus: Any) {if (signalStatus is Postponed || signalStatus is Declined) {// signalStatus is smart-cast to a common supertype Status;  signalStatus被智能转换为一个普通的超类型Status
//        signalStatus.signal()// Prior to Kotlin 2.0.0, signalStatus is smart cast; 在Kotlin 2.0.0之前,signalStatus是智能强制转换// to type Any, so calling the signal() function triggered an ; 输入Any,所以调用signal()函数会触发一个// Unresolved reference error. The signal() function can only; 未解析的引用错误。signal()函数只能// be called successfully after another type check: ; 在另一次类型检查后被成功调用:// check(signalStatus is Status)// signalStatus.signal()}
}// Inline functions
interface Processor {fun process()
}inline fun inlineAction(f: () -> Unit) = f()fun nextProcessor(): Processor? = nullfun runProcessor(): Processor? {var processor: Processor? = nullinlineAction {// 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-castif (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-castif (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() {var stringInput: String? = null// stringInput is smart-cast to String typestringInput = ""try {// The compiler knows that stringInput isn't nullprintln(stringInput.length)// 0// The compiler rejects previous smart cast information for// stringInput. Now stringInput has the String? type.stringInput = null// Trigger an exceptionif (2 > 1) throw Exception()stringInput = ""} catch (exception: Exception) {// In Kotlin 2.0.0, the compiler knows stringInput// can be null, so stringInput stays nullable.println(stringInput?.length)// nullprintln("捕获到的异常信息:$exception")// In Kotlin 1.9.20, the compiler says that a safe call isn't// needed, but this is incorrect.}finally {println("执行了 finally 逻辑")}
}
fun main() {val ketty = Cat()petAnimal(ketty)testString()
}

http://www.ppmy.cn/news/1536789.html

相关文章

STM32中断——外部中断

目录 一、概述 二、外部中断(Extern Interrupt简称EXTI) 三、实例-对射式红外传感器 1、配置中断: 2 、完整代码 一、概述 中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当…

uni-app之旅-day03-搜索

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 5. 搜索5.0 创建 search 分支5.1 自定义搜索组件5.1.2 my-search.vue组件通过自定义属性增强组件的通用性5.1.3 为自定义组件封装 click 事件 5.2 搜索建议5.2.1 渲…

Hugging face简要介绍

1.注册使用huggingface 2.在Datasets下可以查看数据集 3.在Models下可以查看模型,左侧是对模型的分类 4.官方文档查看https://huggingface.co/docs 5.主要模型: 自回归:GPT、Transformer-XL、XLNet 自编码:BERT、ALBERT、RoBERT…

Python Kivy 事件与交互教程

文章目录 Kivy 事件与交互教程3. 事件与交互3.1 事件处理3.1.1 事件与回调函数示例:按钮点击改变标签文本 3.1.2 处理多种事件示例:处理按钮的 on_release 事件 3.2 触摸和手势3.2.1 处理触摸事件示例:绘制简单的手势轨迹 3.2.2 多点触控示例…

如何将数据从 AWS S3 导入到 Elastic Cloud - 第 1 部分:Elastic Serverless Forwarder

作者:来自 Elastic Hemendra Singh Lodhi 这是多部分博客系列的第一部分,探讨了将数据从 AWS S3 导入 Elastic Cloud 的不同选项。 Elasticsearch 提供了多种从 AWS S3 存储桶导入数据的选项,允许客户根据其特定需求和架构策略选择最合适的方…

RK3568笔记六十四:SG90驱动测试

若该文为原创文章,转载请注明原文出处。 前面有测试过PWM驱动,现在使用两种方式来产生PWM驱动SG90,实现舵机旋转任意角度 方法一:使用硬件PWM 方法二:使用高精度定时器,GPIO模拟PWM. 一、PWM子系统框架 二、SG90控制方法 舵机的控制需要MCU产生一个周期为20ms的脉冲信号…

(笔记)第三期书生·浦语大模型实战营(十一卷王场)--书生入门岛通关第2关Python 基础知识

学员闯关手册:https://aicarrier.feishu.cn/wiki/ZcgkwqteZi9s4ZkYr0Gcayg1n1g?open_in_browsertrue 课程视频:https://www.bilibili.com/video/BV1mS421X7h4/ 课程文档:https://github.com/InternLM/Tutorial/tree/camp3/docs/L0/Python 关…

FFMpeg源码分析,关键结构体分析(一)

http://lazybing.github.io/blog/categories/ffmpegyuan-ma-fen-xi/ 一、下载FFmpeg的编译源码 进入网站:http://ffmpeg.org/download.html二、编译源码 执行下述命令: ./configure --prefix/usr/local/ffmpeg --enable-debug3 --enable-ffplay sudo …