コトリンについて少し

画像



先日、JetBrainsは、5年間の仕事の後、 Kotlin言語の最初のリリースをリリースしました。 それがどんな言語なのかを見てみましょう。なぜ、誰のために、どんな機能があるのか​​を考えてみましょう。 ほとんどの場合、言語の個人的な印象は記事で埋められましたが、有用な情報の表示に影響を与えないようにしました。 あなたがまだKotlinについて何もまたはほとんど何も知らないなら、私はあなたがうらやましいです、あなたの長い間待っていた楽器について読んでいる私の意見では、新年の贈り物を開けるのに似ているからです。 ただし、自分で判断してください。







コトリンとは



コトリンは、サンクトペテルブルクに近いフィンランド湾の小さな島です。 どうやら、それによってクリエイターは、コトリン島のような新しい言語は、 ジャワ島のロシアの弟であるという事実に言及しています



この言語の対象者



実際、新しい言語はJVMバイトコードにコンパイルされます(JavaScriptでのコンパイルもありますが、コンパイラーのリリースはJVMにあるため、このトピックは再度延期する必要があります)。 そしてこれは、一般にガベージコレクターでJavaマシンと言語を扱うすべての人にとって興味深いことを意味します(そしてJavaScriptでのコンパイルリリースのリリースにより、カバレッジと機能はさらに広くなります)。



シンプルで互換性のある



私の意見では、Kotlinの2つの主な機能は、そのシンプルさとJavaとの完全な互換性です。 Kotlinは、多くのJava製品を製造する会社によって作成され、最新の開発ツールに精通しています。 新しい言語の要求は長い間空中にありましたが、Javaの(巨大な)既製のコードベースを利用できる言語を作成するために、通常のJava開発者に新しいツールを提供し、kotlinまでシームレスに(より効率的に)そのようなツールを開発し続けます存在しませんでした。 私の意見では、新しい言語の作成者はビジネスと開発者のニーズを非常によく感じていました。ビジネスには開発者の有効性を高め、開発者に最新の開発ツールを提供する機会が与えられました。 もちろん、「最新のツール」について話すとき、コンパイラだけでなくIDEでのサポートも意味します。それなしでは、私の開発活動は私にはまったく考えられないように思えます。

要約すると、単純さにより、チュートリアルや言語仕様を30分見ても構わないJava開発者のほとんどがこの言語を使用でき、下位互換性により既存のプロジェクトでその言語を使用できます。



生産準備完了



もちろん、まず第一に、JetBrains自体にこの言語に対する要求があったため、それがどうあるべきかをある程度理解していました。 さらに、JetBrainsは社内でテストしました。このリリースがリリースされるまでに、同社はすでにKotlinで純粋に作られた少なくとも1つの大きな製品を所有していました(はい、プラットフォームはまだJavaで書かれていることを理解しています)。 このことから、生産のための言語の準備についてのステートメントは根拠がないと仮定できます。 2012年以降のKotlinの使用経験から、リリース前に遭遇した問題については、リリースまで生き残った問題はないと言えます。 IDEAのプラグインにはまだ小さな問題がありますが、コンパイラー自体は時計のように機能します。



Java 1.6との互換性



この特定のバージョンのJavaはAndroidのすべての最新バージョンで使用されているため、これは非常に重要なポイントです。OpenJDKへ計画的な移行にもかかわらず、8番目のバージョンはモバイルデバイスの開発者の手に落ちます。 もちろん、あらゆる種類のレトロラムダやその他のトリックがありますが、KotlinはAndroidのラムダであるだけでなく、特別な費用なしでAndroidの開発をより簡単に 、より楽しくする最新の言語でもあります。 また、apkサイズの増加は現時点ではまったく重要ではありません:823KB(バージョン1.0.0の場合)



特徴



もちろん、機能の完全なリストはドキュメントで探すのが最適ですが、私は意見で最も重要な点を一般的な用語で反映するようにします:



ヌルの安全性


何らかの理由で、歴史的に、Kotlinのこの機能が最初に記憶されることが判明しました。 そして、それは確かに重要ですが、私の意見では、それは最も重要ではありません。 ここで、言語は、変数、フィールド、定数などを定義することにより、nullへの参照をそれらに格納できるかどうかを示すことができます。 @NullableやNotNullなどの注釈の概念を新しいレベルに引き上げ、nullをチェックした後、null不可の型にインテリジェントにキャストできるようにします。 この機能は、特定のことをどのように行うべきかという私の骨の詰まったJava開発とは異なる場合があることに注意する必要がありますが、考えた後、常に良い解決策が見つかります。



/*  ,    null */ fun someFunction(someNullableParam:SomeType?) { if(someNullableParam != null) { // smart cast.  ,   //   null       anotherFunction(someNullableParam) } } /*    null  ,    * null  nullable     */ fun anotherFunction(someParam:SomeType) { //  -  ,    null }
      
      







型推論


はい、Kotlinは可能な限りほとんどどこでも型を推測できますが、型はパブリックメソッドとプロパティに対して決定する必要がありますが、これは非常に合理的です(これは真実ではないことを教えてくれます-それはいくつかのバージョンから削除されました):

 // Kotlin  ,   List<Char> val result = sequenceOf(10).map { it.toString() }.flatMap { it.toCharArray().asSequence() }.toList()
      
      







拡張メソッド


言語とソリューションの柔軟性を高めるために、Javaで私がひどく見逃している機会 。 (型)宣言とは別に、型のメソッドを定義することができます。 もちろん、このような関数は仮想ではなく、メソッドを追加するクラスを変更しませんが、既存のコードに実用的な機能を追加し、同じ実用的なメソッドからインターフェイスをアンロードできます。



 interface Vector2 { val x:Float //   ,    (property) val y:Float //  Java    getX()  getY() } /* Extension property.    ,  getLength() */ val Vector2.length:Float get() = (x * x + y * y).sqrt() // ,   extension-  Float   /*   + */ operator fun Vector2.plus(other:Vector2):Vector2 = createVector(x+this.x, y+this.y) // -     /*  ,   =    */ fun Vector2.dot(x: Float, y: Float): Float = x * this.x + y * this.y /*       infix, *      : v1 dot v2 */ infix fun Vector2.dot(vec2: Vector2): Float = dot(vec2.x, vec2.y) fun usage(vec1:Vector2, vec2:Vector2) { val dotProduct = vec1 dot vec2 val sum = vec1 + vec2 //     val length = sum.length //      }
      
      







ラムダス


もちろん、Kotlinの関数型プログラミングの可能性を主張する他の現代言語と同様に、文字通りに翻訳された場合、関数は第一級の本質です。 つまり 関数はパッケージ内で直接宣言できるだけでなく(Javaからクラス内でとにかく見える-ファイル名で)、他の関数などから返されるパラメーターとして渡すこともできます。 そしてもちろん、これで誰も驚かないでしょうが、たとえば、構文的に機能するような機能はない(ただし、機能的なインターフェースのみである)Javaと比較すると、Kotlinには機能を宣言するための完全な構文があります:



 /*      --    Int *  Int  .   ,    *     */ fun passTen(func: (Int)->Int ): ()->Int { return { func(10) } }
      
      







拡張ラムダ


拡張メソッドとともに、これは私のお気に入りの機能の1つです。 拡張メソッドでもあるラムダを定義できます。 それは非常に良く聞こえません、はい。 例を見てみましょう:



 class World(val name:String = "world") val printName:World.()->Unit = { //       //       println("Hello $name") } val world = World() //         ! world.printName()
      
      







この機能は、 ビルダーで特に興味深いように見えます。このような構造がどのように取得されるかに興味がある場合は、自分自身を確認することを提案します。



 html { head { title {+"XML encoding with Kotlin"} } body { h1 {+"XML encoding with Kotlin"} a(href = "http://kotlinlang.org") {+"Kotlin"} } }
      
      







インライン関数


関数をインラインとしてマークする場合、コンパイラーに使用場所に配置するように依頼します。 ほとんどの場合、ランタイムはそのようなことを処理しますが、関数がアクションのショートカットにすぎないことを確信している場合があります。特に、送信されたラムダでうまく機能します。



 /*   block     . * ,          , *   ,   -   */ inline fun lock(lock:Lock, block:()->Unit) { lock.lock() try { block() } finally { lock.unlock() } } fun usage() { lock(Lock()) { //  -   } }
      
      







もちろん、このような関数には一連の制限が課されます 。詳細については、 ドキュメントを参照してください。



代表団


Kotlinには2種類の委任があります。 最初に 、実装されたインターフェースのすべてのメソッドをこのタイプのある種のインスタンスに委任することができます:



 interface Connection { fun connect() } /*         *        -- *    connection       . *       *  https://kotlinlang.org/docs/reference/classes.html#constructors * , ,       Connection,   *        Connection-. *          */ class ConnectionWrapper(val connection:Connection) : Connection by connection
      
      







この構文には多くの制限があります。 たとえば、委任のインスタンスは、コンストラクターを呼び出す前に認識されている必要があります。



委任の2番目のタイプは、 委任されたプロパティです。 オブジェクトのプロパティにアクセスするときにアクセスを委任するget(およびvarに設定)メソッドでオブジェクトを定義できます。



 class Foo { /*     ,          */ private val someProeprty by lazy { HavyType() } }
      
      







ジェネリック


Kotlinの作成者は、Javaジェネリックをわずかに改善しました 。 Javaとの互換性のため、すべてが期待どおりに機能したわけではありませんが、Java 5で作業する際に前任者が考慮しなかった多くの不快な瞬間を修正できました。



再編


 val (first, second) = someFunc()
      
      





このコードが機能するためには、someFunc()からの戻り値は、メソッドcomponent1()、component2()を持っている(拡張の可能性がある)型である必要があります。

 class Foo { fun component1():String = "test" fun component2():Int = 10 } fun someFunc():Foo = Foo() //  , to --    infix extension-  //  Any,     Pair,  hashMapOf //     vararg    val map = hashMapOf(1 to "test") for ((id, name) in map) { //   ,    Map-   iterator() //   Map.Entry,         // extension- component1()  component2() }
      
      







データクラス


Beanを作成するためのSugarコンパイラー:

 data class Bean(val a:String, val b:Int)
      
      





上記のセクションからフィールド+自動生成と等しいビン+ hashCode + toString()+ componentNを含むビンを作成します。これにより、このようなコードを記述できます。

 fun someFunc():Bean = Bean("test", 10) val (a, b) = someFunc()
      
      





便利なことですが、ニュアンスについては、「悲しいことについて」の段落を参照してください。



標準ライブラリ



もちろん、 標準ライブラリに言及することは間違いありません。 Kotlinは主にJavaでの作業を目的としているため、標準ライブラリ全体がありません。 Kotlin標準ライブラリのほとんどは、古いライブラリであるJavaの改善と修正を目的としています。 ただし、これは別のすばらしい記事のトピックです。



ああ悲しい



これは理想的な製品だと思うかもしれませんが、いや、不快な瞬間があります:



IDE


彼はまだプラグインで作業して作業しなければならず、定期的に実行を発行し、デバッグでtoString()が苦手で、ソースへのリンクを見逃しがちです。 もちろん、これは確かに時間の経過とともに修正されますが、今ではそれだけです。



データクラス


アイデアは良かったと認めざるを得ませんが、現時点では、このタイプのクラスには多くの制限が課されており、これにより、私たちが望むよりもはるかに限られたケースで使用することができます。 言語の作成者は、この問題の解決に取り組むことを約束しますが、これまでのところ。



ずさんな


もちろん、ずさんなことは主に頭にありますが、構文の簡潔さは時々トリックを演じ、一部の場所ではコードが良く見えません。 おそらく、スタイルガイドがあればこの問題はいくらか解決するでしょうが、これまでのところ、うまく機能するだけでなく、見栄えもよくする必要があります。 特に私の主観的な意見では、プロパティの設定は恐ろしく見えます。



結論として



1つの記事で言語のすべての機能と側面を網羅することはできませんが、私は試していません。 私の仕事は言語を紹介することでした。多分それに注意を払ってください。 興味のある方はドキュメンテーションをもっと見つけ、 ソースを見て、 試して質問して ください 。 この言語の人気を予測することは困難ですが、今では多くの人がそのような製品を待っていたことが明らかになり、Kotlinのプロジェクトはキノコのように見え、リリース後、その出現頻度はさらに増加し​​ます。 私の意見では、言語はバランスが取れており、考え抜かれています。コードを書いている時点で、すべてが適切に配置されているという感覚が得られます。 jvmまたはガベージコレクションで他の言語を使用する場合、kotlinに注意を払うのは理にかなっています。 個人的には、コトリンは私が長い間待っていた楽器であり、今ではそれなしでどのようにできるか想像できません。



All Articles