序文
優れたAndroid開発には完全なナレッジシステムが必要 です。ここで、考えながら成長していきましょう。
最後に、Kotlin 1.4の最初のプレビューバージョンがリリースされました。新しいバージョン1.4-M1では、Kotlinがいくつかの新機能を追加すると同時に、いくつかの主要な改善点があります。この記事では、Kotlinの新バージョンで追加および改善される予定の機能について説明します。
1.新しいバージョンの使い方は?
オンラインプログラミングを使用している場合は、ブラウザーでhttps://play.kotlinlang.org/を開き、Kotlinバージョン1.4-M1を選択できます。
Android StudioまたはIntelliJ IDEを使用している場合、プラグインを最新バージョン1.4-M1に直接アップグレードできます。手順は次のとおりです。
- 1.选择[ツール]-> [Kotlin]-> [Kotlinプラグインの更新の構成]。
- 2.更新リスト
Early Access Preview X
から選択し、対応するバージョンを選択します
- 3. [インストール]をクリックして再起動すると、構成が完了します。
2.より強力な型推奨アルゴリズム
Kotlin1.4では、新しい、より強力な型推奨アルゴリズムが使用されています。おそらく、このアルゴリズムはKotlin1.3ですでに試した可能性があります。Kotlin1.3では、コンパイラオプションを指定することで実現できます。ただし、現在はデフォルトで使用されます。新しいアルゴリズムの詳細については、https://youtrack.jetbrains.com/issues/KT?q = Tag:%20fixed-in-new-inference%20&_ga = 2.58428450.988595807.1586745008-1408654980.1539842787をご覧ください。
以下では、いくつかの重要な改善点のみを紹介します。
2.1。KotlinメソッドとインターフェースのSAM変換
最後にあなたを待って、Kotlin1.4はKotlinインターフェイスのSAM変換をサポートできます。これは非常に重要です。
なにSAM转换
?まだあまり知らない学生もいるかもしれません。
SAM変換、つまり単一抽象メソッド変換は、単一の非デフォルト抽象メソッドインターフェースのみの変換です。この条件を満たすインターフェース(SAMタイプと呼ばれます)の場合、LatdaでKotlinで直接表現できます。もちろん、前提はLambdaによって表される関数のタイプは、インターフェースのメソッドと一致できます。
Kotlin 1.4より前では、KotlinはKotlinのSAM変換をサポートしておらず、Java SAM変換をサポートできます。公式の説明は次のとおりです。** Kotlin自体にはすでに関数タイプと高次関数があり、SAMに移動する必要はありません変革。** Java LambdaとFunction Interfaceを使用している場合、この説明は開発者向けではありません。Kotlinに切り替えると、非常に退屈になります。Kotlinはこれに気づいたか、開発者からのフィードバックを見て、最終的にそれをサポートしたようです。
KotlinのSAM変換はどのように見えますか?一緒に比較を見てください
1.4
以前:
1.4
後:
// 注意需用fun 关键字声明
fun interface Action {
fun run()
}
fun runAction(a: Action) = a.run()
fun main() {
// 传递一个对象,OK
runAction(object : Action{
override fun run() {
println("run action")
}
})
// 1.4-M1支持SAM,OK
runAction {
println("Hello, Kotlin 1.4!")
}
}
1.4より前では1つのオブジェクトしか渡せず、Kotlin SAMはサポートされていません。1.4以降ではKotlin SAMをサポートできますが、使用方法にいくつかの変更があります。インターフェイスはfun
キーワードで宣言する必要があります。インターフェースがfunキーワードでマークされた後、インターフェースがパラメーターとして使用されている限り、ラムダをパラメーターとして渡すことができます。
2.2。より多くのシーンのための自動型推論
新しい推論アルゴリズムでは多くの場合推断类型
、これらの場合、古い推論ではタイプを明示的に指定する必要があります。たとえば、次の例でlambda
は、パラメーターのタイプは次のように正しく推論されString?
ます。
val rulesMap: Map<String, (String?) -> Boolean> = mapOf(
"weak" to { it != null },
"medium" to { !it.isNullOrBlank() },
"strong" to { it != null && "^[a-zA-Z0-9]+$".toRegex().matches(it) }
)
fun main() {
println(rulesMap.getValue("weak")("abc!"))
println(rulesMap.getValue("strong")("abc"))
println(rulesMap.getValue("strong")("abc!"))
}
バージョン1.3では、上記のコードでIDE是会报错的
明示的なラムダパラメーターを導入するかto
、それを機能させるために、明示的なジェネリックパラメーターを持つPairコンストラクターで置き換える必要があります。代わりに、このように:
//需要显示的lambda 参数
val rulesMap: Map<String, (String?) -> Boolean> = mapOf(
"weak" to { it -> it != null },
"medium" to { it -> !it.isNullOrBlank() },
"strong" to { it -> it != null && "^[a-zA-Z0-9]+$".toRegex().matches(it) }
)
fun main() {
println(rulesMap.getValue("weak")("abc!"))
println(rulesMap.getValue("strong")("abc"))
println(rulesMap.getValue("strong")("abc!"))
}
印刷結果は次のとおりです。
true
true
false
Process finished with exit code 0
2.3。Lambdaの最後の式のスマート型変換
Kotlin 1.3では、型が指定されていない限り、ラムダの最後の式をインテリジェントにキャストできません。したがって、次の例では、Kotlin 1.3はString?
型を結果変数として推測します。
val result = run {
var str = currentValue()
if (str == null) {
str = "test"
}
str // Kotlin编译器知道str在这里不为null
}
// result的类型在kotlin1.3中推断为String?,在Kotlin1.4中为String
しかし、Kotlin 1.4では、新しい推論アルゴリズムを使用するためlambda
、最後の内部式が取得され智能转换
、この新しいより正確な型を使用して、結果のラムダ型が推論されます。したがって、結果変数の型はStringになります。Kotlin 1.3では、通常、この状況を機能させるために明示的な強制(!!
またはStringなどのタイプ强制转换
)を追加する必要がありますが、これらの強制は不要になりました。
2.4。呼び出し可能タイプ(呼び出し可能)参照のスマート変換
以下のサンプルコードをご覧ください。
sealed class Animal
class Cat : Animal() {
fun meow() {
println("meow")
}
}
class Dog : Animal() {
fun woof() {
println("woof")
}
}
fun perform(animal: Animal) {
val kFunction: KFunction<*> = when (animal) {
is Cat -> animal::meow
is Dog -> animal::woof
}
kFunction.call()
}
fun main() {
perform(Cat())
}
kotlin 1.3では、スマート変換タイプによって参照されるメンバーにアクセスできませんが、現在はそうです。で Animal
インテリジェントに特定の型にキャスト変数Cat
とDog
した後、あなたは参照の異なるメンバーを使用することができるanimal :: meow
とanimal :: woof
。タイプを確認した後、サブタイプに対応するメンバー参照にアクセスできます。
2.5。呼び出し可能な参照の最適化
たとえば、次の例:
fun foo(i: Int = 0): String = "$i!"
fun apply1(func: () -> String): String = func()
fun apply2(func: (Int) -> String): String = func(42)
fun main() {
println(apply1(::foo))
println(apply2(::foo))
}
Kotlin 1.3では、foo
関数はIntパラメーターを持つ関数として解釈されるためapply1
、型エラーを報告します。
現在、デフォルトのパラメーター値を持つ関数を使用した呼び出し可能な参照が最適化され、foo
関数への呼び出し可能な参照は采用一个Int参数
OR として解釈できます不采用任何参数
。したがって、上記のタイプのエラーは報告されません。
2.6。手数料属性の最適化
最初にコードを見てください。
fun main() {
var prop: String? by Delegates.observable(null) { p, old, new ->
println("$old → $new")
}
prop = "abc"
prop = "xyz"
}
上記のコードはKotlin 1.3でコンパイルされています。これは、by
次のデリゲート式を分析するときにデリゲートプロパティのタイプが考慮されないため、タイプエラーが報告されるためです。ただし、kotlin 1.4-M1では、コンパイラーはパラメーターの型を正しく推論old
およびnew
パラメーター化しますString?
。
3.標準ライブラリの変更
3.1。放棄された実験コルーチンAPI
バージョン1.3.0では、kotlin.coroutines.experimental
API は推奨されませんが、推奨されkotlin.coroutines
ます。1.4-M1では、kotlin.coroutines.experimental
非推奨にするために標準ライブラリから削除します。JVMでまだ使用している人のために、互換性ライブラリを提供 kotlin-coroutines-experimental-compat.jar
しています。Kotlin 1.4-M1とともにBintrayにリリースしました。
3.2。廃止されたmod
演算子を削除する
別の廃止された関数は、mod
除算後の剰余を計算する数値演算子です。Kotlin 1.1では、rem()
関数に置き換えられました。次に、標準ライブラリから完全に削除します。
3.3。浮動小数点型からバイトおよびショートへの変換の放棄
標準ライブラリは、以下のような方法の浮動小数点変換を整数型の種類の数が含まれていますtoInt()
、 toShort()
、 toByte()
。ただし、値の範囲が狭く、変数サイズが小さいため、浮動小数点数をShortおよびByteに変換すると、予期しない結果が生じる可能性があります。この問題を解決するために、1.4-M1は、我々は廃車Double
とし、方法。それでも浮動小数点型をShortまたはByteに変換したい場合はどうなりますか?2ステップ変換の場合、最初に浮動小数点型をIntに変換してから、Intをターゲットの型に変換します。Float
toShort()
toByte()
3.4。一般的な起動API
一般的なリフレクションAPIを変更しました。現在、3つのターゲットプラットフォーム(JVM、JS、ネイティブ)すべてで使用可能なメンバーが含まれているため、これらのプラットフォームのいずれでも同じコードが確実に機能するようになりました。
3.5。KotlinリフレクションのProguard構成
1.4-M1以降、kotlin-reflect.jar
Kotlin Reflection Proguard / R8
構成が組み込まれています。この変更により、R8またはProguardを使用するほとんどのAndroidプロジェクトは、他の構成なしでkotlin-reflectを使用します。KotlinリフレクションのProguardルールをコピーして貼り付ける必要はありません。ただし、リフレクションの対象となるすべてのAPIを明示的にリストする必要があることに注意してください。
4. Kotlin / JVM
バージョン1.3.70以降、KotlinはタイプアノテーションをJVMバイトコード(ターゲットバージョン1.8+)で生成できるため、実行時に使用できます。この機能は、既存のJavaライブラリの使用を容易にし、新しいライブラリの作成者により多くの拡張機能を提供するため、コミュニティはこの機能を要求してきました。
次の例では、文字列型@Foo
注釈をバイトコードで発行し、ライブラリコードで使用できます。
@Target(AnnotationTarget.TYPE)
annotation class Foo
class A {
fun foo(): @Foo String = "OK"
}
具体的な使用方法については、次のブログをご覧ください。https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/#kotlin-jvm
5.その他の変更
上記の変更に加えて、Kotlin / JsおよびKotlin / iOSプラットフォームのいくつかの最適化と改善もあります。
5.1 Kotlin / JS
5.1.1。Gradle DSLの変更
ではkotlin.js
とmultiplatform
、のGradleプラグインは、重要な新しい設定を導入しました。build.gradle.kts
ファイルのターゲットブロック内で、ビルドプロセス中に.js
アーティファクトを生成する場合は、アーティファクトを構成して使用できますproduceExecutable()
。
kotlin {
target {
useCommonJs()
produceExecutable()
browser {}
}
}
-
Kotlin / JSライブラリを作成している場合は、
ProduceExecutable()
設定を省略できます。 -
新しいIRコンパイラバックエンドを使用する場合(詳細については、以下を参照)、この設定を省略すると、実行可能なJSファイルが生成されなくなります(したがって、ビルドプロセスがより高速に実行されます)。klibファイルは、他のKotlin / JSプロジェクトから、または同じプロジェクトの依存関係として使用できるbuild / libsフォルダーに生成されます。明示的
produceExecutable()
に指定しない場合、これはデフォルトで行われます。
produceExecutable()を使用すると、JavaScriptエコシステムから実行できるコードが生成されます。独自のエントリポイントがある場合でも、JavaScriptライブラリーである場合でも、実際のJavaScriptファイルが生成され、ノードインタープリターで実行してHTMLページに埋め込むことができます。ブラウザで実行するか、JavaScriptプロジェクトの依存関係として使用します。
5.1.2。新しいバックエンド
Kotlin 1.4-M1は、Kotlin / JSターゲット用の新しいIRコンパイラバックエンドを含む最初のバージョンです。このバックエンドは、大幅な改善の基盤であり、Kotlin / JSがJavaScriptおよびTypeScriptと対話する方法のいくつかの変更の決定的な要素です。以下で強調表示されているいくつかの機能は、新しいIRコンパイラバックエンド用です。デフォルトでは有効になっていませんが、プロジェクトで以下を試すことをお勧めします。
(1)如何使用新的后端?
gradle.properties
構成ファイルに次の構成を追加します。
kotlin.js.compiler=ir // or both
IRコンパイラバックエンドとデフォルトのバックエンドのライブラリを生成する必要がある場合は、このフラグをに設定することを選択できますboth
。
both
役割以下のセクションでは、説明を検討してください。
(2)バイナリ互換性なし
元のデフォルトのバックエンドと比較して、新しいIRコンパイラバックエンドの主な変換は、バイナリ互換性がないことです。Kotlin/ JSの2つのバックエンド間に互換性がないため、新しいIRコンパイラバックエンドが使用されます。作成されたライブラリはデフォルトのバックエンドからは使用できず、その逆も同様です。
(3)DCE最適化
デフォルトのバックエンドと比較して、新しいIRコンパイラバックエンドは大幅に最適化されています。生成されたコードは、静的アナライザーでより適切に機能します。生成されたコードを新しいIRコンパイラバックエンドからGoogleのClosure Compilerを介して実行し、高度な最適化モードを使用することもできます。
(4)JavaScriptへのステートメントのエクスポートをサポート
現在、パブリックとしてマークされた宣言は自動的にエクスポートされなくなりました。トップレベルの宣言をJavaScriptまたはTypeScriptで使用できるようにするには、@JsExport
アノテーションを使用します。
package blogpost
@JsExport
class KotlinGreeter(private val who: String) {
fun greet() = "Hello, $who!"
}
@JsExport
fun farewell(who: String) = "Bye, $who!"
fun secretGreeting(who: String) = "Sup, $who!" // only from Kotlin!
(5)TypeScript定義をサポート
新しいコンパイラは、KotlinコードからのTypeScript定義の生成をサポートしています。構成produceExecutable()
アイテムの場合、上記のトップ@JsExport
レベル宣言を使用すると、TypeScript定義を含む.d.ts
ファイルが生成されます。上記のコードのように、生成されたファイルは次のとおりです。
// [...]
namespace blogpost {
class KotlinGreeter {
constructor(who: string)
greet(): string
}
function farewell(who: string): string
}
// [...]
6. Kotlin / Nativeのいくつかの変更
6.1。Objective-Cはデフォルトでジェネリックをサポートします
Kotlinの初期のバージョンでは、Objective-Cの相互運用性におけるジェネリックの実験的なサポートが提供されていました。Kotlinコードからジェネリックでフレームヘッダーを生成するには、-Xobjc-generics
オプションを使用する必要があります。1.4-M1では、パラダイムがデフォルトでサポートされています。ただし、場合によっては、Kotlinフレームワークを呼び出す既存のObjective-CまたはSwiftコードが破損することがあります。パラダイムを使いたくない場合は、-Xno-objc-generics
オプションを追加します
binaries.framework { freeCompilerArgs += "-Xno-objc-generics"}
6.2。Objective-C / Swiftの相互運用における例外処理の変更
1.4では、Swift API例外処理がKotlinから生成される方法をわずかに変更しました。KotlinとSwiftのエラー処理は根本的に異なり、Swiftはエラーのみをチェックするのに対し、すべてのKotlin例外はチェックされていません。したがって、Swiftコードに例外を認識させるためには、@Throws
Kotlin関数に、潜在的な例外クラスのリストを指定する注釈を付ける必要があります。
SwiftまたはObjective-Cフレームワークにコンパイルされると、@Throws
アノテーションを持っているまたは継承している関数は、Objective-C NSError *
では処理メソッドとして、Swiftではメソッドとして表されますthrows
。
6.3。パフォーマンスの改善
Kotlin / Nativeのコンパイルと実行の全体的なパフォーマンスを改善するために努力してきました。1.4-M1では、新しいオブジェクトアロケーターが提供され、一部のベンチマークテストでは、2倍の速度で実行されました。現在、新しいディスペンサーは実験的なものであり、デフォルトでは使用されません。を使用して-Xallocator = mimalloc
、このオプションに切り替えることができます。
7.まとめ
上記はKotlin1.4-M1の変更点の一部です。最も驚くべき機能の1つは、最終的にKotlinインターフェースのSAM変換をサポートすることです。他の機能もいくつか試してみることができますが、詳しくは公式サイトで公開予定を確認し、リリース版をお楽しみに!