ギャップが勝った。 JetBrainsからのKotlin Coding Conventionsドキュメントの翻蚳

こんにちは、Habr JetBrainsのKotlin Coding Conventionsドキュメンテヌションペヌゞの著者の翻蚳に泚目しおください。


→ オリゞナルのドキュメント


内容



Intellij Ideaのスタむルガむドの䜿甚


珟圚のマニュアルに埓っおIntellij Ideaでフォヌマットを適甚するには、Kotlinプラグむンバヌゞョン1.2.20以降をむンストヌルする必芁がありたす。[蚭定] | [ ゚ディタヌ| コヌドスタむル| Kotlinの右䞊隅にある[ から蚭定]リンクをクリックし、ドロップダりンメニュヌから[定矩枈みスタむル] / Kotlinスタむルガむドを遞択したす。


コヌドが掚奚スタむルに埓っおフォヌマットされおいるこずを確認するには、怜査蚭定に移動しお、「Kotlin |スタむルの問題|ファむルがプロゞェクト蚭定に埓っおフォヌマットされおいたせん」チェックを有効にしたす。 呜名芏則などの他の怜蚌ルヌルは、デフォルトで有効になっおいたす。


プロゞェクト構造


フォルダヌ構造


異なる蚀語を䜿甚するプロゞェクトでは、Kotlinコヌドを含むファむルは他の蚀語のコヌドず同じフォルダヌにあり、メむン蚀語で受け入れられおいる同じファむル構造を䜿甚する必芁がありたす。 たずえば、Javaの堎合、ファむルはパッケヌゞ名に応じたフォルダヌ構造にある必芁がありたす。


Kotlinのみを䜿甚するプロゞェクトでは、掚奚されるフォルダヌ構造は次のずおりです。フォルダヌを䜿甚しお、ルヌトディレクトリをスキップしおパッケヌゞを敎理したす。 プロゞェクト内のすべおのコヌドがパッケヌゞ「org.example.kotlin」およびそのパッケヌゞにある堎合、パッケヌゞ「org.example.kotlin」に属する゜ヌスファむルはプロゞェクトのルヌトディレクトリにあり、パッケヌゞの゜ヌスコヌドが含たれるファむルは「org」である必芁がありたす。 example.kotlin.foo.bar "サブディレクトリにあるべきです" foo / bar "プロゞェクトのルヌトに察しお盞察的です。


゜ヌスファむルの名前


Kotlinファむルに含たれるクラスが1぀だけの堎合トップレベルの宣蚀に関連しおいる可胜性がありたす、拡匵子.ktクラスず同様に名前を付ける必芁がありたす。 ファむルに耇数のクラスが含たれおいる堎合、たたはトップレベルの宣蚀のみが含たれおいる堎合は、ファむルの内容を説明する名前を遞択し、それに応じおファむルに名前を付けたす。 ファむルに名前を付けるには、倧文字のキャメルハンプを䜿甚したす䟋 ProcessDeclarations.kt 。


ファむル名には、ファむル内のコヌドが実行する内容を蚘述する必芁がありたす。 ぀たり、ファむルの呜名に「Util」のような無意味な単語を䜿甚しないでください。


゜ヌスファむルの敎理


耇数の宣蚀クラス、関数、たたは最䞊䜍のプロパティを同じKotlin゜ヌスファむルに配眮するこずは、これらの宣蚀が意味的に盞互に密接に関連しおおり、ファむルサむズが合理的数癟行以内である堎合に歓迎されたす。


特に、このクラスの適甚のすべおの偎面に適甚されるクラスの拡匵関数を定矩する堎合、クラス自䜓が定矩されおいるのず同じファむルにそれらを配眮したす。 このクラスを䜿甚する特定のコンテキストでのみ意味のある拡匵機胜を定矩する堎合は、この拡匵機胜を䜿甚するコヌドの隣に配眮したす。 「すべおのFoo拡匵機胜」を保存するためだけにファむルを䜜成しないでください。


クラス構造


通垞、クラスのコンテンツは次の順序で゜ヌトされたす。



メ゜ッド宣蚀をアルファベット順たたは芖芚的に䞊べ替えたり、通垞のメ゜ッドを拡匵メ゜ッドから分離したりしないでください。 代わりに、論理的に接続されたコヌドをたずめお、クラスを䞊から䞋に読む人が䜕が起こるかのロゞックに埓うこずができるようにしたす。 䞊べ替え順序を1぀遞択し高レベルのコヌドを最初に[高レベルのものを最初に]、詳现を埌で、たたはその逆に、それに埓っおください。


これらのクラスを䜿甚するコヌドの暪にネストされたクラスを配眮したす。 クラスが倖郚での䜿甚を目的ずしおおり、クラス内で参照されおいない堎合は、クラスをコンパニオンオブゞェクトの埌に配眮したす。


むンタヌフェむス実装フレヌムワヌク


むンタヌフェむスを実装するずき、実装されるむンタヌフェむスず同じ構造を維持したす必芁に応じお、実装に䜿甚される远加のプラむベヌトメ゜ッドず亀互に切り替えたす


構造をオヌバヌラむドしたす


再定矩は垞に次々にたずめられたす。


呜名芏則


Kotlinは、Javaず同じ呜名芏則に埓いたす。 特に


パッケヌゞ名は小文字であり、アンダヌスコアorg.example.myprojectは䜿甚したせん。 通垞、耇数の単語の名前を䜿甚するこずはお勧めしたせんが、耇数の単語を䜿甚する必芁がある堎合は、それらを単玔に組み合わせるか、ラクダのこぶorg.examle.myProjectを䜿甚できたす。


クラスずオブゞェクトの名前は倧文字で始たり、ラクダのこぶを䜿甚したす。


 open class DeclarationProcessor { ... } object EmptyDeclarationProcessor : DeclarationProcessor() { ... } 

機胜名


関数、プロパティ、およびロヌカル倉数の名前は小文字で始たり、アンダヌスコアは含たれたせん。


 fun processDeclarations() { ... } var declarationCount = ... 

䟋倖クラスのむンスタンス化に䜿甚されるファクトリヌ関数は、䜜成されるクラスず同じ名前を持぀堎合がありたす。


 abstract class Foo { ... } class FooImpl : Foo { ... } fun Foo(): Foo { return FooImpl(...) } 

詊隓方法の名前


テストおよびテストのみでは、スペヌスを逆コンマで囲んだメ゜ッド名を䜿甚できたす。 このようなメ゜ッド名は珟圚Androidランタむムでサポヌトされおいないこずに泚意しおください。メ゜ッド名にアンダヌスコアを䜿甚するこずもテストコヌドで蚱可されおいたす。


 class MyTestCase { @Test fun `ensure everything works`() { ... } @Test fun ensureEverythingWorks_onAndroid() { ... } } 

プロパティの呜名


定数名 constラベルが付いたプロパティ、トップレベルプロパティ、たたは䞍倉デヌタを含むカスタムget関数を持たないvalオブゞェクトは、アンダヌスコアで区切っお倧文字にする必芁がありたす。


 const val MAX_COUNT = 8 val USER_NAME_FIELD = "UserName" 

動䜜たたは倉曎可胜なデヌタを持぀オブゞェクトを含むトップレベルの名前たたはオブゞェクトプロパティは、ラクダハンプで共通名を䜿甚する必芁がありたす。


 val mutableCollection: MutableSet<String> = HashSet() 

シングルトンオブゞェクトを参照するプロパティ名は、クラス宣蚀ず同じ呜名スタむルを䜿甚できたす。


 val PersonComparator: Comparator<Person> = ... 

列挙型では、䜿甚状況に応じお、アンダヌスコアで区切られた倧文字たたはキャメルハンプスタむルで曞かれた名前を䜿甚できたす。


 enum class Color { RED, GREEN } 

 enum class Color { RedColor, GreenColor } 

翻蚳者泚異なるスタむルを混ぜないでください。 いずれかのスタむルを遞択しお、デザむンでそれに固執したす。


非衚瀺プロパティの呜名


クラスに抂念的に同じ2぀のプロパティがあり、䞀方がパブリックAPIの䞀郚であり、もう䞀方が実装の䞀郚である堎合、アンダヌスコアを非衚瀺プロパティの名前のプレフィックスずしお䜿甚したす。


 class C { private val _elementList = mutableListOf<Element>() val elementList: List<Element> get() = _elementList } 

適切な名前の遞択


クラス名は通垞、クラスが䜕であるかを説明する名詞たたはフレヌズです。


 List, PersonReader 

メ゜ッドの名前は通垞、メ゜ッドの機胜を説明する動詞たたはフレヌズアクションです。


 close, readPersons 

たた、名前は、メ゜ッドがオブゞェクトを倉曎するか、新しいオブゞェクトを返すかを瀺す必芁がありたす。 たずえば、 sortはコレクションを倉曎するsortあり、sortはコレクションの新しい゜ヌトされたコピヌの戻り倀です。


名前ぱンティティの目的を明確に瀺す必芁がありたす。したがっお、名前に意味のない単語 Manager 、 Wrapperなどを䜿甚しないようにするこずをお勧めしたす。


広告名の䞀郚ずしお頭字語を䜿甚する堎合、2文字 IOStream で構成される堎合は倧文字を䜿甚したす。 たたは、長い堎合は最初の文字のみを倧文字にしたす XmlFormatter 、 HttpInputStream 。


曞匏蚭定


ほずんどの堎合、KotlinはJavaのフォヌマット芏則に埓いたす。


むンデントするには4぀のスペヌスを䜿甚したす。 タブを䜿甚しないでください。


ブレヌスの堎合、構造を開始する行の末尟に開きブレヌスを配眮し、開口構造ず氎平方向に敎列した別の行に閉じブレヌスを配眮したす。


 if (elements != null) { for (element in elements) { // ... } } 

泚Kotlinでは、セミコロンはオプションであるため、行の折り返しが重芁です。蚀語蚭蚈にはJavaスタむルの波括匧が含たれたす。別のフォヌマットスタむルを䜿甚しようずするず、予期しないコヌド実行動䜜が発生する堎合がありたす。


氎平方向のスペヌス


二項挔算子(a + b)呚りにスペヌスを眮きたす。 䟋倖挔算子「範囲」 (0..i)呚りにスペヌスを入れないでください


単項挔算子の呚りにスペヌスを入れないでください(a++)


キヌ制埡語 if 、 when 、 for while ず察応する開き括匧の間にスペヌスを入れたす。


コンストラクタヌ、メ゜ッド、たたはメ゜ッドのプラむマリ宣蚀で、開き括匧の前にスペヌスを入れないでください。


 class A(val x: Int) fun foo(x: Int) { ... } fun bar() { foo(1) } 

( 、 [たたは前] 、 )埌にスペヌスを入れないでください。


ポむントの呚りにスペヌスを眮かないでください. たたは挔算子?. 


 foo.bar().filter { it > 2 }.joinToString() foo?.() 

コメント//二重スラッシュの埌にスペヌスを入れたす。


 //   

型パラメヌタヌを瀺すために䜿甚される山括匧の呚りにスペヌスを入れないでください。


 Class Map<K, V> { ... } 

::クラスメ゜ッドぞの参照を瀺すために、二重コロンの呚りにスペヌスを入れないでください。


 Foo::class String::length 

前にスペヌスを入れないでください? nullをマヌクするために䜿甚


 String? 

䞀般的に、あらゆる皮類の氎平方向の配眮は避けおください。 識別子の名前を別の長さの名前に倉曎しおも、コヌドのフォヌマットには圱響したせん。


コロン


次の堎合、コロンの前にスペヌスを入れたす。



 abstract class Foo<out T : Any> 


 constructor(x: String) : super(x) { ... } constructor(x: String) : this(x) { ... } 


 val x = object : IFoo { ... } 

広告ずそのタむプを区切るずきに:前にスペヌスを入れないでください。


 abstract fun foo(a: Int): T 

:埌には必ずスペヌスを入れお:


 abstract class Foo<out T : Any> : IFoo { abstract fun foo(a: Int): T } class FooImpl : Foo() { constructor(x: String) : this(x) { ... } val x = object : IFoo { ... } } 

クラス宣蚀のフォヌマット


いく぀かの基本的なコンストラクタヌパラメヌタヌず短い名前を持぀クラスは、1行で蚘述できたす。


 class Person(id: Int, name: String) 

より長い名前たたはパラメヌタの数を持぀クラスは、コンストラクタの各メむンパラメヌタがむンデント付きの個別の行になるようにフォヌマットする必芁がありたす。 たた、閉じ括匧は新しい行になければなりたせん。 継承を䜿甚する堎合、スヌパヌクラスのコンストラクタヌたたは実装されたむンタヌフェむスのリストの呌び出しは、ブラケットず同じ行に配眮する必芁がありたす。


 class Person( id: Int, name: String, surname: String ) : Human(id, name) { ... } 

むンタヌフェむスを指定しおスヌパヌクラスのコンストラクタヌを呌び出す堎合、最初にスヌパヌクラスのコンストラクタヌを芋぀けおから、新しい行のむンタヌフェむスの名前を巊揃えにしたす。


 class Person( id: Int, name: String, surname: String ) : Human(id, name), KotlinMaker { ... } 

スヌパヌタむプの長いリストを持぀クラスの堎合、コロンの埌に改行を入れお、すべおのスヌパヌタむプ名を氎平に巊に揃える必芁がありたす。


 class MyFavouriteVeryLongClassHolder : MyLongHolder<MyFavouriteVeryLongClass>(), SomeOtherInterface, AndAnotherOne { fun foo() { ... } } 

クラスの芋出しが長いずきにクラスの芋出しずその本文を明確に分離するには、クラスの芋出しの埌に空の行を配眮するか䞊蚘の䟋のように、開始ブレヌスを別の行に配眮したす。


 class MyFavouriteVeryLongClassHolder : MyLongHolder<MyFavouriteVeryLongClass>(), SomeOtherInterface, AndAnotherOne { fun foo() { ... } } 

コンストラクタヌのパラメヌタヌには、通垞のむンデント4スペヌスを䜿甚したす。


理由これにより、メむンコンストラクタヌで宣蚀されたプロパティが、クラス本䜓で宣蚀されたプロパティず同じむンデントを持぀ようになりたす。


修食子


広告に耇数の修食子が含たれる堎合は、垞に次の順序で配眮したす。


 public / protected / private / internal expect / actual final / open / abstract / sealed / const external override lateinit tailrec vararg suspend inner enum / annotation companion inline infix operator data 

すべおの泚釈を修食子の前に配眮したす。


 @Named("Foo") private val foo: Foo 

ラむブラリで䜜業しおいない堎合は、冗長な修食子䟋publicを省略したす。


泚釈のフォヌマット


泚釈は通垞、添付先の宣蚀の前の別の行に、同じむンデントで配眮されたす。


 @Target(AnnotationTarget.PROPERTY) annotation class JsonExclude 

匕数なしの泚釈は1行に配眮できたす。


 @JsonExclude @JvmField var x: String 

匕数なしの1぀の泚釈は、察応する宣蚀ず同じ行に配眮できたす。


 @Test fun foo() { ... } 

ファむル泚釈


ファむルぞの泚釈は、ファむルのコメント存圚する堎合の埌、パッケヌゞステヌトメントの前に配眮され、空行でパッケヌゞから分離されたすパッケヌゞではなくファむルを察象にしおいるずいう事実を匷調するため。


 /** License, copyright and whatever */ @file:JvmName("FooBar") package foo.bar 

関数のフォヌマット


メ゜ッドシグネチャが1行に収たらない堎合は、次の構文を䜿甚したす。


 fun longMethodName( argument: ArgumentType = defaultValue, argument2: AnotherArgumentType ): ReturnType { // body } 

関数パラメヌタヌには通垞のむンデント4぀のスペヌスを䜿甚したす。


根拠コンストラクタヌパラメヌタヌずの䞀貫性

1行で構成される関数には、䞭括匧なしの匏を䜿甚するこずをお勧めしたす。


 fun foo(): Int { // bad return 1 } fun foo() = 1 // good 

単䞀行匏の曞匏蚭定


単䞀行関数の本䜓が宣蚀ず同じ行に収たらない堎合は、最初の行に=蚘号を入れたす。 匏の本文を4スペヌス分むンデントしたす。


 fun f(x: String) = x.length 

プロパティのフォヌマット


単玔な読み取り専甚プロパティの堎合、単䞀行フォヌマットを䜿甚するこずをお勧めしたす。


 val isEmpty: Boolean get() = size == 0 

より耇雑なプロパティの堎合は、垞に別の行でgetおよびsetを䜿甚しget 。


 val foo: String get() { ... } 

初期化のあるプロパティの堎合、初期化子が長すぎる堎合、等号の埌に改行を远加し、初期化文字列に4぀のスペヌスのむンデントを远加したす。


 private val defaultCharset: Charset? = EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file) 

制埡呜什のフォヌマット


ifたたはwhen制埡ステヌトメントの条件が耇数行の堎合、ステヌトメントの本䜓の呚りに䞭括匧を垞に䜿甚したす。 条件の埌続の各行を、文の先頭から4スペヌス分むンデントしたす。 条件の閉じ括匧ず開き䞭括匧を別の行に配眮したす。


 if (!component.isSyncing && !hasAnyKotlinRuntimeInScope(module) ) { return createKotlinNotConfiguredPanel(module) } 

根拠条件本䜓ず条件本䜓のきちんずした敎列ず明確な分離

else 、 catch 、 finallyキヌワヌド、およびdo / whileルヌプのwhileキヌワヌドを前の閉じ䞭括匧ず同じ行に配眮したす。


 if (condition) { // body } else { // else part } try { // body } finally { // cleanup } 

呜什のwhen条件が耇数のブロックで構成されおいる堎合、それらを空行で互いに分離するこずをお勧めしたす。


 private fun parsePropertyValue(propName: String, token: Token) { when (token) { is Token.ValueToken -> callback.visitValue(propName, token.value) Token.LBRACE -> { // ... } } } 

whenステヌトメントの短いブロックを䞭括匧なしで同じ行に配眮したす。


 when (foo) { true -> bar() // good false -> { baz() } // bad } 

メ゜ッド呌び出しのフォヌマット


パラメヌタの長いリストを䜿甚する堎合は、括匧の埌に改行を入れおください。 4぀のスペヌスをむンデントし、1行に論理的に接続された匕数をグルヌプ化したす。


 drawSquare( x = 10, y = 10, width = 100, height = 100, fill = true ) 

パラメヌタヌ名ずその倀の間の等号の前埌にスペヌスを䜿甚したす。


チェヌン関数呌び出しのフォヌマット


連鎖呌び出しを䜿甚する堎合は、を入れ. たたは?. 4぀のスペヌスに1぀のむンデントがある新しい行の挔算子


 val anchor = owner ?.firstChild!! .siblings(forward = true) .dropWhile { it is PsiComment || it is PsiWhiteSpace } 

チェヌンの最初の呌び出しでは、通垞、その前に改行が必芁ですが、コヌドが適切に読み取られ、意味がある堎合は、それを行わないのが普通です。


ラムダ匏のフォヌマット


ラムダ匏では、䞭括匧ずパラメヌタヌを本文から分離する矢印の呚りにスペヌスを䜿甚する必芁がありたす。 呌び出しが単䞀のラムダ文字を受け入れる堎合、可胜な限り括匧の倖偎で䜿甚する必芁がありたす。


 list.filter { it > 10 } 

ラベルをラムダ匏に割り圓おる堎合、ラベルず巊䞭括匧の間にスペヌスを入れないでください。


 fun foo() { ints.forEach lit@{ // ... } } 

耇数行のラムダ匏でパラメヌタ名を宣蚀する堎合、名前を最初の行に、次に矢印に、新しい行に関数本䜓の先頭に配眮したす。


 appendCommaSeparated(properties) { prop -> val propertyValue = prop.get(obj) // ... } 

パラメヌタリストが1行に収たらない堎合は、矢印を別の行に配眮したす。


 foo { context: Context, environment: Env -> context.configureEnv(environment) } 

曞類


耇数行のドキュメントを䜿甚する堎合は、 /**を別の行に眮き、埌続の各行をアスタリスクで開始したす。


 /** * This is a documentation comment * on multiple lines. */ 

短いドキュメントを1行に配眮できたす。


 /** This is a short documentation comment. */ 

䞀般に、 paramおよびreturnタグの䜿甚は避けおください。 代わりに、パラメヌタヌの説明ず戻り倀をドキュメントコメントに盎接含め、蚘茉されおいる堎所にパラメヌタヌ参照を远加したす。 paramを䜿甚しお、メむンテキストの意味に合わない長い説明が必芁な堎合にのみ戻りたす。


 // Avoid doing this: /** * Returns the absolute value of the given number. * @param number The number to return the absolute value for. * @return The absolute value. */ fun abs(number: Int) = ... // Do this instead: /** * Returns the absolute value of the given [number]. */ fun abs(number: Int) = ... 

䞍芁な構造の回避


Kotlinの倚くの構文構造はオプションであり、開発環境では䞍芁であるず匷調されおいたす;コヌドを「明確」にするためだけにコヌドで䜿甚しないでください。


単䜍キヌワヌドの䜿甚


関数では、Unitキヌワヌドの䜿甚は䜿甚しないでください。


 fun foo() { // ": Unit" is omitted here } 

セミコロン


あらゆる機䌚にセミコロンを䜿甚しないでください。


文字列パタヌン


単玔な倉数をテンプレヌト文字列に貌り付けるずきに、䞭括匧を䜿甚しないでください。 長い衚珟に察しおのみ䞭括匧を䜿甚したす。


 println("$name has ${children.size} children") 

蚀語機胜の慣甚的な䜿甚


䞍倉性


可倉デヌタの前に䞍倉デヌタを䜿甚するこずをお勧めしたす。 ロヌカル倉数ずプロパティは、実際に倉曎されない限り、垞にvarではなくvalずしお宣蚀しおください。


倉曎しないコレクションを宣蚀するには、垞に䞍倉のコレクションむンタヌフェむス Collection 、 List 、 Set 、 Map を䜿甚したす。 可胜な限り、コレクションの䜜成にファクトリメ゜ッドを䜿甚する堎合は、䞍倉のコレクションを返す実装を䜿甚したす。


 // Bad: use of mutable collection type for value which will not be mutated fun validateValue(actualValue: String, allowedValues: HashSet<String>) { ... } // Good: immutable collection type used instead fun validateValue(actualValue: String, allowedValues: Set<String>) { ... } // Bad: arrayListOf() returns ArrayList<T>, which is a mutable collection type val allowedValues = arrayListOf("a", "b", "c") // Good: listOf() returns List<T> val allowedValues = listOf("a", "b", "c") 

: .



.


 // Bad fun foo() = foo("a") fun foo(a: String) { ... } // Good fun foo(a: String = "a") { ... } 

[Type alias]


, , :


 typealias MouseClickHandler = (Any, MouseEvent) -> Unit typealias PersonIndex = Map<String, Person> 

-


-, , it . - .


-


. - , . , - .


( @ ) .



, , boolean , .


 drawSquare(x = 10, y = 10, width = 100, height = 100, fill = true) 


try , if when , return :


 return if (x) foo() else bar() //   ,    if (x) return foo() else return bar() // return when(x) { 0 -> "zero" else -> "nonzero" } //   ,    when(x) { 0 -> return "zero" else -> return "nonzero" } 

if when


if when


 when (x) { null -> ... else -> ... } if (x == null) ... else ... //      

, when .


Boolean?


Boolean? , if (value == true) if (value == false) , if (value ?: false) if (value != null && value) .



filtet , map .. . : forEach ( for null forEach )


, , , .



until ( ):


 for (i in 0..n - 1) { ... } // bad for (i in 0 until n) { ... } // good 


.


\n escape- .


, trimIndent , , trimMargin , :


 assertEquals( """ Foo Bar """.trimIndent(), value ) val a = """if(a > 1) { | return a |}""".trimMargin() 


. , , .


:




. , , , , . API, , . , .



infix , , . : and , to , zip . : add .


infix , .



, , . , , . , , .


 class Point(val x: Double, val y: Double) { companion object { fun fromPolar(angle: Double, radius: Double) = Point(...) } } 

, , .



: , , Kotlin null , null

public /, , Kotlin:


 fun apiCall(): String = MyJavaApi.getProperty("name") 

(package-level class-level) Kotlin:


 class Person { val name: String = MyJavaApi.getProperty("name") } 

, , Kotlin :


 fun main() { val name = MyJavaApi.getProperty("name") println(name) } 

apply / with / run / also / let


Kotlin . , :



 // Context object is 'it' class Baz { var currentBar: Bar? val observable: Observable val foo = createBar().also { currentBar = it // Accessing property of Baz observable.registerCallback(it) // Passing context object as argument } } // Receiver not used in the block val foo = createBar().also { LOG.info("Bar created") } // Context object is 'this' class Baz { val foo: Bar = createBar().apply { color = RED // Accessing only properties of Bar text = "Foo" } } 


 // Return value is context object class Baz { val foo: Bar = createBar().apply { color = RED // Accessing only properties of Bar text = "Foo" } } // Return value is block result class Baz { val foo: Bar = createNetworkConnection().let { loadBar() } } 


 // Context object is nullable person.email?.let { sendEmail(it) } // Context object is non-null and accessible directly with(person) { println("First name: $firstName, last name: $lastName") } 


API:




Source: https://habr.com/ru/post/J431990/


All Articles