Kotlin:2.0.0 的新特性
一、概述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 Cat
if (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 : Status
fun 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? = null
fun runProcessor(): Processor? {
var processor: Processor? = null
inlineAction {
// 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-cast
if (processor != null) {
// The compiler knows that processor isn't null, so no safe call
// is needed
processor.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-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
}
}
}
假如重载调用操作符,也适用此更改。例如:
interface Provider {
operator fun invoke()
}
interface Processor : () -> String
class 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 type
stringInput = ""
try {
// The compiler knows that stringInput isn't null
println(stringInput.length)
// 0
// The compiler rejects previous smart cast information for
// stringInput. Now stringInput has the String? type.
stringInput = null
// Trigger an exception
if (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)
// null
println("捕获到的异常信息:$exception")
// In Kotlin 1.9.20, the compiler says that a safe call isn't
// needed, but this is incorrect.
}finally {
println("执行了 finally 逻辑")
}
}
运行结果
https://i-blog.csdnimg.cn/direct/4329019d5e4d4ad0903662f918abd5b7.png
八、kt_200.kt文件代码
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 {
fun signal() {}
}
interface Ok : Status
interface Postponed : Status
interface Declined : Status
fun 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 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() {
var stringInput: String? = null
// stringInput is smart-cast to String type
stringInput = ""
try {
// The compiler knows that stringInput isn't null
println(stringInput.length)
// 0
// The compiler rejects previous smart cast information for
// stringInput. Now stringInput has the String? type.
stringInput = null
// Trigger an exception
if (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)
// null
println("捕获到的异常信息:$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()}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]