Kotlinを導入する
Kotlinは、JVMの新しい言語の1つで、IntelliJを製作したJetBrains社が開発しました。これは、静的型付け言語であり、OOとFPのプログラミングスタイルを混ぜたものを提供することを目的としています。Kotlinコンパイラは、JVMと互換性のあるバイトコードを作成します。そのバイトコードは、JVM上で実行して既存のライブラリと同時に利用できます。Kotlinは、Android開発のため、2017年にGoogleに推奨された時、大きなブレイクが起こりました。
JetBrainsは、Kotlinをマルチプラットフォーム言語にして、100%のJava相互運用性を提供するという公式の目的があります。最近の成功と成熟度により、Kotlinはサーバサイドに入り込むのに適した場所にいます。
Kotlinの場合
多数の言語がよりよいJavaを目指してきました。Kotlinは、言語とエコシステムの両方に関して、たくさんのことを成し遂げました。JVMと巨大なライブラリ空間を維持しながら、よりよいJavaへと待望の進化を遂げています。JetBrainsとGoogleの支持を得て組み合わされたこのアプローチは、Kotlinを真剣な競争者にしました。Kotlinがもたらした、いくつかの機能を見てみましょう。
型推論 - 型推論は第一の機能です。Kotlinは、明確に指定せずに、変数の型を推論します。明確にするために型が必要なインスタンスでは、型を指定することもできます。
Java 10は、varキーワードを導入して、同じ方向に進みました。これは、表面上、同じように見えますが、ローカル変数の範囲に限定されます。フィールドやメソッドシグニチャでは利用できません。
厳格なnullチェック - Kotlinはコンパイル時エラーとして、nullになり得るコードフローを扱います。そして、nullチェックを扱う追加のシンタックスを提供します。特に、連鎖したコールのNPEに対して、保護を提供します。
Javaとの相互運用性 - Kotlinは、この分野において、他のJVM言語よりもかなり優れています。Javaとはシームレスな互換性があります。フレームワークからJavaクラスをインポートして、Kotlinで利用できます。また、その反対も可能です。明らかに、Kotlinのコレクションは、Javaコレクションと互換性があります。
不変性 - Kotlinは、不変データ構造を促進します。一般的に使われるデータ構造 (Set/ List/ Map)は、可変であることを明確に述べていなければ、不変です。変数もまた、不変(val)と可変(var)を指定されます。これらの変更が重なり、状態の管理容易性の影響は注目に値するものになります。
クリーンで表現豊かなシンタックス - Kotlinは、コードの可読性に大きな影響を与える、多くの改善を導入しました。いくつか述べると、以下の点があります。
- セミコロンは任意です。
- 波括弧は、インスタンスが使われないところでは任意です。
- Getter/Setterは任意です。
- すべてはオブジェクト - プリミティブは、必要であれば、自動的に裏側で使われます。
- エクスプレッション:エクスプレッションは、評価された時に結果を返します。
Kotlinでは、すべての関数がエクスプレッションであり、少なくともUnitを返します。if, tryやwhen(switchと同様)のような制御フロー文もエクスプレッションです。例えば、
String result = null;
try {
result = callFn();
} catch (Exception ex) {
result = “”;
}
は、次のようになります。
val result = try {
callFn()
} catch (ex:Exception) {
“”
}
- ループは範囲をサポートします。例えば、
for (i in 1..100) { println(i) }
いくつか他の改善があります。これから見ていきましょう。
JavaプロジェクトにKotlinを導入する
小さなステップ
Javaの相互運用性を前提として、小さなステップで、既存のJavaプロジェクトにKotlinを追加することを推奨します。主要製品をサポートするプロジェクトは、一般的によい候補になります。チームの不安がなくなったら、完全に切り替えたいかどうか評価できます。
どのようなプロジェクトがよい候補か?
すべてのJavaプロジェクトはKotlinの利益を受けられます。しかし、次のような特徴を持つプロジェクトは、より簡単に決められます。
多数のDTO、または、モデル/エンティティオブジェクトを含むプロジェクト - これは、CRUDやデータ変換を扱うプロジェクトでは代表的なものです。これらは、getter/setterで混乱する傾向があります。Kotlinプロパティがここで影響を与え、クラスをかなり単純化します。
ユーティリティクラスで重くなったクラス - Javaのユーティリティクラスは、通常、Javaのトップレベル関数の不足を補うために存在します。多くのインスタンスにおいて、これらはpublic static経由でグローバルな状態を持たない関数を含みます。これらは、純粋な関数の中に取り除かれます。さらに、関数型や高階関数のようなFPコンストラクトのKotlinのサポートにより、コードはよりメンテナンスやテストがしやすくなります。
ロジックで重くなったクラスがあるプロジェクト - これらは、Nullポインタ例外(NPE)が発生しやすい傾向があります。NPEは、Kotlinがうまく解決できる問題分野の1つです。NPEが発生する可能性のあるコードパスを分析させることによって、開発者はサポートを受けます。Kotlinの「when」コンストラクト(「switch」よりもよいもの)は、管理できる関数の中に、ネストしたロジックツリーを分解するのに役立ちます。変数とコレクションの不変性サポートは、ロジックを単純化し、露出したリファレンスから発生するバグを見つけるのが難しくなるのを避けるのに役立ちます。上記のいくつかはJavaで達成できることですが、Kotlinの強さは、これらのパラダイムを促進し、クリーンで首尾一貫したものにすることです。
ここで一休みして、典型的なJavaロジックスニペットと、Kotlinのそれに対応するものを見てみましょう。
public class Sample {
public String logic(String paramA, String paramB) {
String result = null;
try {
if (paramA.length() > 10) {
throw new InvalidArgumentException(new String[]{"Unknown"});
} else if ("AB".equals(paramA) && paramB == null) {
result = subLogicA(paramA + "A", "DEFAULT");
} else if ("XX".equals(paramA) && "YY".equals(paramB)) {
result = subLogicA(paramA + "X", paramB + "Y");
} else if (paramB != null) {
result = subLogicA(paramA, paramB);
} else {
result = subLogicA(paramA, "DEFAULT");
}
} catch (Exception ex) {
result = ex.getMessage();
}
return result;
}
private String subLogicA(String paramA, String paramB) {
return paramA + "|" + paramB;
}
}
Kotlinで対応するもの:
fun logic(paramA:String, paramB:String?):String {
return try {
when {
(paramA.length > 10) -> throw InvalidArgumentException(arrayOf("Unknown"))
(paramA == "AB" && paramB == null) -> subLogicA(paramA + "A")
(paramA == "XX" && paramB == "YY") -> subLogicA(paramA + "X", paramB + "X")
else -> if (paramB != null) subLogicA(paramA, paramB) else subLogicA(paramA)
}
} catch (ex:Exception) {
ex.message ?:"UNKNOWN"
}
}
private fun subLogicA(paramA:String, paramB:String = "DEFAULT"):String {
return "$paramA|$paramB"
}
これらのスニペットは機能的に同等ですが、いくつかはっきりとした違いがあります。
logic()関数は、クラスの中にある必要はありません。Kotlinはトップレベル関数を持ちます。これにより、大きな空間か広がり、何かが本当にオブジェクトである必要があるかどうか、私たちは考えさせられます。スタンドアローンで純粋な関数は、テストが簡単です。これは、よりクリーンな関数のアプローチを採用するように、チームに選択肢を与えます。
Kotlinは、条件付きのフローを組織化するための強力なコントスラクトである「when」を導入します。これは、「if」や「switch」ステートメントよりもずっと有能です。任意のロジックは、「when」を使って明確に組織化できます。
Kotlinバージョンの中で、リターン変数を決して宣言しないことに注意してください。Kotlinは、エクスプレッションとして「when」と「try」を使うことができるので、これが可能です。
subLogicA関数で、ファンクション宣言のparamBへデフォルト値を割り当てました。
private fun subLogicA(paramA:String, paramB:String = "DEFAULT"):String {
今、どちらの関数シグニチャも呼び出すことができます。
subLogicA(paramA, paramB)
または、
subLogicA(paramA)
#ここでは、paramBが関数宣言のデフォルト値を使いました。
ロジックが追いやすくなり、ライン数は〜35%減少します。
JavaビルドにKotlinを追加する
MavenとGradleは、プラグインでKotlinをサポートします。KotlinコードはJavaクラスへコンパイルされ、ビルドプロセスに含まれます。 Kobaltのような新しいビルドツールも、期待できそうです。Kobaltは、Maven/Gradleの影響を受けましたが、純粋にKotlinで書かれています。
始めるために、 Maven、または、 Gradleビルドファイルに、Kotlinプラグインの依存を追加します。
SpringとJPAを使っている場合は、kotlin-springとkotlin-jpa コンパイラプラグインも使うべきです。まったく違いに気づくことなく、プロジェクトはコンパイルして、ビルドするでしょう。
このプラグインは、KotlinコードベースにJavaDocを生成するために必要です。
IDEプラグインは、IntelliJとEclipseスタジオで利用できますが、当然ながら、Kotlinの開発とビルドツールは、IntelliJに関連して、多くの利益があります。IDEは、コミニュティエディションから始まっている、Kotlinの第一のサポートです。注目に値する機能の1つは、既存のJavaコードをKotlinへ自動的に変換するサポートです。変換は正確で、慣用的なKotlinを書くためのよい学習ツールです。
人気のあるフレームワークとの統合
私たちは既存プロジェクトにKotlinを導入しているので、フレームワークの互換性に関心を持っています。Kotlinは、Javaバイトコードへコンパイルし、Javaエコシステムの中へ円滑に適合します。Sprint、Vert.x、Sparkその他、いくつかの人気のあるフレームワークは、Kotlinのサポートを発表しています。SpringとHibernateをKotlinと一緒に使った場合を見てみましょう。
Spring
Springは、Kotlinの初期のサポータの1つで、最初にサポートを追加したのは2016年でした。Spring 5はよりクリーンなDSLを試すように、Kotlinに影響を与えました。既存のJava Springコードは、何も変更せずに動き続けることを期待できます。
KotlinのSpringアノテーション
SpringアノテーションとAOPは、追加設定なしで動きます。Javaでアノテーションを使うのと同じように、Kotlinクラスでアノテーションを使えます。以下のサービス宣言スニペットを検討してください。
@Service
@CacheConfig(cacheNames = [TOKEN_CACHE_NAME], cacheResolver = "envCacheResolver")
open class TokenCache @Autowired constructor(private val repo:TokenRepository) {
これらは、標準的なSpringアノテーションです。
@Service: org.springframework.stereotype.Service
@CacheConfig: org.springframework.cache
コンストラクタは、クラス宣言の一部であることに注意してください。
@Autowired constructor(private val tokenRepo:TokenRepository)
Kotlinは、これをプライマリコントストラクタとして参照し、クラス宣言の一部となることができます。このインスタンスの中で、tokenRepoは、インラインで宣言されたプロパティです。
コンパイル時定数はアノテーションで使うことができ、これらは一般的にタイプミスを避けるのに役立ちます。
ファイナルクラスを扱う
Kotlinクラスは、デフォルトでfinalです。意識的な設計の選択として、継承を許すアプローチを推奨します。これは、Spring AOPではうまくいきませんが、補うのは難しくありません。finalではないことを表すKotlinのキーワード、openとして、関連するクラスにしるしをつける必要があります。
IntelliJは、親切な警告を与えます。
これは、「all open」Mavenプラグインを使って、避けられます。このプラグインによって、特定のアノテーションを持つクラスをオープンにします。このより簡単なオプションは、「open」としてクラスにしるしをつけるものです。
自動ワイヤリングとnullチェック
Kotlinは、厳しくnullチェックを実行します。初期化するために、すべてのプロパティがnullableでないとしてマークされる必要があります。これらは、宣言の場か、コンストラクタの中で初期化されます。実行時にプロパティを入れる、ディペンデンシインジェクションとは反対に動きます。
lateinit修飾子は、プロパティが使われる前に初期化されることを指定できるようにします。次のスニペットにおいて、Kotlinは、configオブジェクトが最初に使われる前に初期化されるものとします。
@Component
class MyService {
@Autowired
lateinit var config:SessionConfig
}
lateinitは自動ワイヤリングで役に立ちますが、控えめに使うことをお勧めします。その一方で、lateinitは、プロパティのコンパイル時のnullチェックをオフにします。最初に使うときにnullの場合はランタイムエラーになりますが、コンパイル時のnullチェックがなくなります。
コンストラクタインジェクションは、別の選択肢として使えます。これは、Spring DIと共にうまく動き、多くの混乱を取り除きます。以下は例です。
@Component
class MyService constructor(val config:SessionConfig)
これは、あなたをベストプラクティスに従うようにさせるKotlinのよい例です。
Hibernate
HibernateはすぐにKotlinとうまく動き、主要な変更は求められません。典型的なエンティティクラスを以下に示します。
@Entity
@Table(name = "device_model")
class Device {
@Id
@Column(name = "deviceId")
var deviceId:String? = null
@Column(unique = true)
@Type(type = "encryptedString")
var modelNumber = "AC-100"
override fun toString():String = "Device(id=$id, channelId=$modelNumber)"
override fun equals(other:Any?) =
other is Device
&& other.deviceId?.length == this.deviceId?.length
&& other.modelNumber == this.modelNumber
override fun hashCode():Int {
var result = deviceId?.hashCode() ?:0
result = 31 * result + modelNumber.hashCode()
return result
}
}
上記のスニペットでは、いくつかのKotlinの機能を強化しました。
プロパティ
プロパティのシンタックスを使うことで、getterとsetterを明示的に定義する必要がありません。
このため、雑然とすることなく、私たちはデータモデルに集中できます。
型推論
私たちが初期値を提供できるインスタンスは、型を推論できるため、型を特定する部分を飛ばすことができます。例えば、
var modelNumber = "AC-100"
modelNumberプロパティは、型がStringであると推論されます。
エクスプレッション
toString()メソッドをよく見てみると、Javaと少し違いがあります。
override fun toString():String = "Device(id=$id, channelId=$modelNumber)"
returnステートメントはありません。ここでは、Kotlinのエクスプレッションを使っています。1つのエクスプレッションを返す関数では、波括弧を省略して「=」で割り当てます。
Stringテンプレート
"Device(id=$id, channelId=$modelNumber)"
ここで、より自然にテンプレートを使えます。Kotlinは、どのStringでも${エクスプレッション}を組み込むことができます。これにより、扱いにくい連結や、String.formatのような外部ヘルパの必要性を減らします。
等式テスト
equalsメソッドで、このエクスプレッションに気付いていたかもしれません。
other.deviceId?.length == this.deviceId?.length
==サインで2つのStringを比較しています。これはJavaで長い間分かっていたことであり、等式テストでは特別なケースとしてStringを扱います。Kotlinは、構造上の等式(Javaのequals())で、首尾一貫して==を使うことで、ついにこれを修正しました。参照等式は、===でチェックされます。
データクラス
Kotlinは、データクラスとして知られる特別なタイプのクラスも提供します。これらは、クラスの第一の目的がデータを保持することだというシナリオに対して、特に適しています。データクラスは、自動的にequals()、hashCode()、toString()メソッドを生成し、さらに定型的な表現を減らします。
データクラスは、最後の例をこのように変えます。
@Entity
@Table(name = "device_model")
data class Device2(
@Id
@Column(name = "deviceId")
var deviceId:String? = null,
@Column(unique = true)
@Type(type = "encryptedString")
var modelNumber:String = "AC-100"
)
属性は両方とも、コンストラクタパラメタとして渡されます。equals、hashCode、toStringは、データクラスによって提供されます。
しかし、データクラスは、デフォルトコンストラクタを提供しません。これは、エンティティオブジェクトを生成するために、デフォルトのコンストラクタを使うHibernateの問題です。私たちは、ここで、 kotlin-jpaプラグインを利用できます。このプラグインは、JPAエンティティクラスのために、追加で引数のないコンストラクタを生成します。
JVM言語空間とは別にKotlinが設定することの1つは、エンジニアリングの優雅さだけでなく、現実世界の問題を扱うことです。
Kotlinを採用することの実用的な利点
Nullポインタ例外を減らす
JavaのNPEを扱うことは、Kotlinの主要な目的の1つです。Kotlinがプロジェクトに導入される時に、明示的なnullチェックはもっとも目立つ変更です。
Kotlinはいくつかの新しいオペレータを導入して、nullの安全性に取り組んでいます。 ?オペレータで、Kotlinはnull安全の呼び出しを提供します。例えば、
val model:Model? = car?.model
carオブジェクトがnullでない場合にだけ、model属性が読み込まれます。carがnullの場合、modelはnullと評価します。modelの型はModel?であることに注意してください。結果がnullになりえることを示しています。この時点で、フロー分析が始まり、model変数を利用するどのコードでも、コンパイル時にNPEをチェックします。
これは、連鎖したコールでも使われます。
val year = car?.model?.year
以下は、同等のJavaコードです。
Integer year = null;
if (car != null && car.model != null) {
year = car.model.year;
}
大きなコードベースでは、多数のこれらのnullチェックは見逃されます。コンパイル時に安全に、自動でこれらのチェックを行うため、かなりの開発時間を節約できます。
エクスプレッションがnullを評価する場合、エルビス演算子 ( ?:) は、デフォルト値を提供するために使われます。
val year = car?.model?.year ?:1990
上述のスニペットでは、結局、yearがnullの場合、値の1990が代わりに使われます。 ?: オペレータは、左側のエクスプレッションがnullの場合、右側の値を取ります。
関数プログラミングオプション
Kotlinは、Java8機能上に構築され、一流の関数を提供します。一流の関数は、変数/データ構造の中に保持されて、順に回されます。例えば、Javaでは関数を返せます。
@FunctionalInterface
interface CalcStrategy {
Double calc(Double principal);
}
class StrategyFactory {
public static CalcStrategy getStrategy(Double taxRate) {
return (principal) -> (taxRate / 100) * principal;
}
}
Kotlinでは、目的を明確に表現しながら、これをもっとずっと自然に書くことができます。
// 型としての関数
typealias CalcStrategy = (principal:Double) -> Double
fun getStrategy(taxRate:Double):CalcStrategy = { principal -> (taxRate / 100) * principal }
関数をより深く利用するようになると、物事は変わります。Kotlinの次のスニペットは、他の関数を生成する関数を定義します。
val fn1 = { principal:Double ->
{ taxRate:Double -> (taxRate / 100) * principal }
}
fn1
は簡単に呼び出せます。出来上がった関数は、以下の通りです。
fn1(1000.0) (2.5)
Output
25.0
Javaでも上記のようにできますが、単純ではなく、決まりきったコードを含みます。
これらの機能を利用できるようにすることで、チームはFPコンセプトを実験するよう励まされます。これにより、より安定した製品になるように、最終的に目指しているコードによりよく合うようになります。
ラムダシンタックスは、KotlinとJavaではわずかに異なることに注意してください。これは、最初の頃は困ることもあります。
Java
( Integer first, Integer second ) -> first * second
同等のKotlin
{ first:Int, second:Int -> first * second }
時間が経つにつれて、Kotlinがサポートしているユースケースにおいて、変更したシンタックスが必要であることが明らかになっています。
プロジェクトの足跡を減らす
Kotlinのもっとも控えめに言われている利点の1つは、プロジェクトのファイルカウントを減らせることです。Kotlinファイルは、複数/混じり合ったクラス宣言、関数、enumクラスのような他の構造体を含むことができます。これにより、Javaでは利用できなかった沢山の可能性が開きます。その一方で、新しい選択を表します。クラスや関数をまとめる正しい方法は何でしょうか?
Clean Codeという本の中で、Robert C Martin氏は、新聞紙のメタファを紹介します。よいコードは新聞のように読むべきです。上の方はハイレベルな構成で、ファイルを読み進めるにつれて、詳細が増えます。ファイルは、まとまりのある話を語るべきです。Kotlinのコードレイアウトは、このメタファからヒントを得られます。
おすすめするのは、大きなコンテキストの中で、似たようなことを1つにまとめることです。
Kotlinは、構造を見捨てることを止めはしませんが、そうすると後でコードをナビゲートするのが難しくなります。使用する関係と順番によって、物事をまとめましょう。例えば、
enum class Topic {
AUTHORIZE_REQUEST,
CANCEL_REQUEST,
DEREG_REQUEST,
CACHE_ENTRY_EXPIRED
}
enum class AuthTopicAttribute {APP_ID, DEVICE_ID}
enum class ExpiryTopicAttribute {APP_ID, REQ_ID}
typealias onPublish = (data:Map<String, String?>) -> Unit
interface IPubSub {
fun publish(topic:Topic, data:Map<String, String?>)
fun addSubscriber(topic:Topic, onPublish: onPublish):Long
fun unSubscribe(topic:Topic, subscriberId:Long)
}
class RedisPubSub constructor(internal val redis:RedissonClient):IPubSub {
...}
実際に、完全なイメージを形作るためにジャンプしなければならないファイルの数を減らすことによって、大幅に精神的なオーバヘッドを減らします。
共通のケースは、パッケージで一杯になるSpring JPAリポジトリです。これらは、同じファイルで再整理できます。
@Repository
@Transactional
interface DeviceRepository :CrudRepository<DeviceModel, String> {
fun findFirstByDeviceId(deviceId:String):DeviceModel?
}
@Repository
@Transactional
interface MachineRepository :CrudRepository<MachineModel, String> {
fun findFirstByMachinePK(pk:MachinePKModel):MachineModel?
}
@Repository
@Transactional
interface UserRepository :CrudRepository<UserModel, String> {
fun findFirstByUserPK(pk:UserPKModel):UserModel?
}
上記の最後の結果は、コード行数(LOC)が大幅に少なくなります。これは、納品スピードとメンテナンス性に直接的な影響を与えます。
Javaプロジェクトでファイル数とコード行数を測定しましたが、それは、Kotlinに移植されました。これは、データモデル、いくつかのロジックとキャッシングを含む、典型的なRESTサービスです。Kotlinバージョンでは、LOCは〜50%少なくなります。開発者たちは、ファイルの場所を確かめたり、決まり切ったコードを書いたりする時間を大幅に減らしました。
クリアで表現的なコードを可能に
クリーンコードを書くことは広範囲のトピックで、言語、設計、技術の組み合わせによります。しかし、Kotlinは優れたツールセットを提供することによって、チームを成功に導きます。以下に例を示します。
型推論
型推論は、最終的にコードのノイズを減らします。これにより、開発者たちはコードの目的に集中することができるようになります。
型推論は、自分たちが扱っているオブジェクトをたどるのをより難しくするかもしれないというのは、一般に言われている懸念です。実際的な経験から、この懸念は、通常は5%以下の少数のシナリオでのみ有効です。大多数のシナリオにおいて、型は明らかです。
以下は例です。
LocalDate date = LocalDate.now();
String text = "Banner";
は、次のようになります。
val date = LocalDate.now()
val text = "Banner"
Kotlinは、型を指定することもできます。
val date:LocalDate = LocalDate.now()
val text:String = "Banner"
Kotlinが包括的な解決策を提供することは注目に値します。例えば、Kotlinでは関数型を次のように定義できます。
val sq = { num:Int -> num * num }
一方、Java v10は、右側のエクスプレッションの型を見て、型を推測します。これは、いくつかの制限をもたらします。上記の操作をJavaで行おうとすると、エラーになります。
型エイリアス
これは、Kotlinの便利な機能で、既存の型にエイリアスを割り当てられます。新しい型を導入するものではありませんが、別名で既存の型を参照できるようになります。例えば、
typealias SerialNumber = String
SerialNumberがString型のエイリアスになり、String型と互換性を保ちながら、利用できます。例えば、
val serial:SerialNumber = "FC-100-AC"
は、以下と同等です。
val serial:String = "FC-100-AC"
多くの場合、型エイリアスは、明快さを導入するために「変数を説明するもの」として動くことができます。次の宣言を考慮しましょう。
val myMap:Map<String, String> = HashMap()
私たちは、myMapがStringを保持することを知っていますが、これらのStringが何を表しているかという情報は持っていません。String型に型エイリアスを導入することにより、このコードを明確にすることができました。
typealias ProductId = String
typealias SerialNumber = String
今、上記のmap宣言は次のように変更できます。
val myMap:Map<ProductId, SerialNumber> = HashMap()
myMapの上記の2つの定義は同等ですが、後者はmapの中身を簡単に識別できます。
Kotlinコンパイラは、基本的な型で型エイリアスを置き換えます。このため、myMapのランタイムのふるまいは影響を受けません。例えば、
myMap.put(“MyKey”, “MyValue”)
そのような石灰化した累積的な効果により、とらえがたい不具合の数を減らします。大規模な分散チームでは、意味を伝え損なった結果、不具合が発生します。
初期の採用
初期の段階で支持を得ることは、通常、変化を導入するもっとも難しい部分です。実験にふさわしいプロジェクトを識別することから始めましょう。一般的に、初期のKotlinコードを試しに書く気のある初期利用者がいます。何週間かのうちに、より大規模なチームがこのコードを見る機会があるでしょう。人の最初の反応は、新しくて、よく知らないことを避けます。変更を念入りに調べるために、少し時間をあげましょう。利用可能なリソースと技術的な話を読ませて、評価する手助けをしましょう。最初の2、3週間の終わりに、より多くの人たちが、導入レベルを決定できます。
Javaを知っている開発者の場合、学習カーブは小さくなります。私の経験では、大抵のJava開発者は、1週間以内にKotlinで生産性が上がります。経験が浅い開発者は、特別なトレーニングなしでKotlinを習得し、動かせました。別の言語を以前使ったことがあったり、FPコンセプトに精通していたりする場合、さらに導入時間は減少します。
これから起こること
バージョン1.1から、共同ルーチーンがKotlinで使えるようになりました。概念的に、それらはJavaScriptのasync/awaitと同様です。スレッドをブロックせずに、フローを一時停止することで、非同期プログラミングの複雑さを減らします。
今までは、これは実験用とされていました。共同ルーチーンは、1.3リリースで実験的な状態から卒業するでしょう。これにより、もっと刺激的な機会が広がります。
Kotlinロードマップは、Kotlinの発展と拡張プロセス(KEEP)を経て案内されます。議論ともうすぐ発表される機能のために、このことから目を離さないでください。
著者について
Baljeet Sandhu氏は、製造業からファイナンスまでのドメインに渡り、ソフトウェアを提供する深い経験を持つテクニカルリードです。彼は、クリーンなコード、セキュリティ、そして、拡大可能な分散システムに興味を持っています。Baljeet氏は、現在、HYPRで働き、詐欺を無くし、ユーザエクスペリエンスを高め、真のパスワードレスセキュリティを可能にするための分散認証のソリューションを構築しています。