Kotlin1.4-M1がリリースされ、ついにKotlinインターフェースのSAM変換をサポートします!

序文

優れた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インテリジェントに特定の型にキャスト変数CatDogした後、あなたは参照の異なるメンバーを使用することができるanimal :: meowanimal :: 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をターゲットの型に変換します。FloattoShort()toByte()

3.4。一般的な起動API

一般的なリフレクションAPIを変更しました。現在、3つのターゲットプラットフォーム(JVM、JS、ネイティブ)すべてで使用可能なメンバーが含まれているため、これらのプラットフォームのいずれでも同じコードが確実に機能するようになりました。

3.5。KotlinリフレクションのProguard構成

1.4-M1以降、kotlin-reflect.jarKotlin 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.jsmultiplatform、の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コードに例外を認識させるためには、@ThrowsKotlin関数に、潜在的な例外クラスのリストを指定する注釈付ける必要があります。

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変換をサポートすることです。他の機能もいくつか試してみることができますが、詳しくは公式サイトで公開予定を確認し、リリース版をお楽しみに!

488件のオリジナル記事を公開 85 件を賞賛 230,000回の閲覧+

おすすめ

転載: blog.csdn.net/Coo123_/article/details/105631846