我正在使用帶有 kotlin 的專案反應器。正如預期的那樣,由于我正在撰寫呼叫 java 代碼的 kotlin 代碼,因此來自專案反應器操作員的所有型別簽名都顯示為平臺型別。例如
//here i is inferred as Int!
Mono.just(1).map { i -> i 1 }
閱讀專案反應堆的檔案,似乎有一種方法可以斷言所有型別都不可為空,并將型別推斷為不可為空的型別。https://projectreactor.io/docs/core/release/reference/#kotlin-null-safety
Kotlin support for JSR 305 annotations and Reactor nullability annotations provide null-safety for the whole Reactor API to Kotlin developers, with the advantage of dealing with null-related issues at compile time.
我嘗試使用建議的編譯器選項,但沒有成功。使用以下 kotlin 配置,型別i仍然顯示,Int!而我現在期望它是Int.
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.6.10"
application
}
group = "me.stef"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
testImplementation(kotlin("test"))
implementation("io.projectreactor:reactor-core:3.4.14")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = listOf("-Xjsr305=strict")
}
}
application {
mainClass.set("MainKt")
}
我正在使用2021.3.2帶有 kotlin 插件版本的 intelliJ IDEA Ultimate 版本213-1.6.10-release-961-IJ6777.52
我知道我可以使用顯式型別注釋將平臺型別轉換為可空或非空型別,但如果可能的話,我想避免這種情況。
所以我的問題是:
- 我是否正確地解釋了檔案以理解在將專案反應器與 kotlin 一起使用時確實有一種方法可以強制執行不可為空的型別?
- 如果我理解正確,并且
jsr305編譯器選項是實作我的目標的方法,我會做錯什么? - 如果那不是實作目標的方法,我該怎么做?
- 會不會是intellij的問題?
uj5u.com熱心網友回復:
實際上,這種行為是設計使然,因為@NonNullApi它應用于呼叫方法 ( ) 的包map,沒有型別使用默認限定符,而只有METHODand PARAMETER。特別是,這意味著 Kotlin 編譯器不會增強型別引數位置中的型別,而只會增強回傳型別和值引數位置中的整個型別。
可以用下面的代碼證明:
fun main() {
// useless unsafe call before `get()` is reported because
// the Kotlin compiler already enhanced the return type of `blockOptional` to not-null
Mono.just(1).blockOptional()?.get()
}
在您的特定情況下,lambda 的 value 引數i映射到宣告中的T型別引數,Function該引數map對應于型別使用位置。這就是 Kotlin 編譯器不增強這種型別的原因。
請注意,Kotlin 編譯器默認支持在型別使用位置中增強 Java 型別的可空性注釋(包括在包上的注釋)。請參閱以下編譯器測驗。
NonNullApi因此,為反應器創建功能請求以擴展其注釋范圍以鍵入使用位置可能是有意義的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/427780.html
標籤:科特林 智能理念 spring-webflux 项目反应堆
