ローマの神は、コトリンがどのように自己進化を達成するかを理解するためにあなたを連れて行きます

ここに写真の説明を挿入
最近のスピーチ、コトリンチームの大物であるローマンレリザロフ、コトリンチームがどのようにユーザーのニーズを収集して洗練し、最終的に形になったのかを共有しました。引用されているいくつかのケースは、すべて声が高く、実装される可能性が高い文法です。一見の価値があります。
https://youtu.be/0FF19HJDqMo

YouTrack&KEEP


Kotlinチームは、YouTrackを介して開発者からさまざまな問題を収集および追跡し、承認された問題の一部は管理のためKEEP入ります。YouTrackの多くの問題は本来の意図がありますが、言語設計の習慣やその他の理由に準拠していないと考えており、継続的な議論と進化の結果、最良の姿勢で形成されます。この記事で紹介したいくつかのケースもこのような進化の過程を経ており、将来のバージョンで登場する可能性があります。


名前空間


KT-11968:一部の開発者は、Companionキーワードを使用してJavaクラスの静的メソッド/変数を拡張的に定義することを提案しました

val android.content.Intent.Companion.SCHEME_SMS:String get() = "sms"

これにより、Javaで静的呼び出しを実装できます

Intent.SCHEME_SMS

これは本質的に正しいnamespace要求です。Kotlinは、Utilクラスの代わりにトップレベル関数の使用を推奨していますがnamespace、これらのメソッドのインデックス作成を容易にするために同様のメカニズムを提供したい場合があります。一般的な方法は、objectクラスを静的メソッドとして定義することです。Delegates.notNull()この無形文字は、新しい場合、オブジェクトオブジェクトの作成を増やします。namespaceキーワードを追加すると、同様の問題を美しく解決できます

//KT-11968
val Delegates.Companion.notNull() = ... 

⬇️⬇️

//NOW
object Delegates {
    
                        
	fun <T : Any> notNull(): ...
	// other declarations
}

⬇️⬇️

//Maybe in FUTURE
namespace Delegates {
    
    
	fun <T : Any> notNull(): ...
	// other declarations
}

複数の受信機


KT-10468:たとえば、Androidでは、メソッドは2つのレシーバーを表示およびフロートする必要があります。現時点では、複数のレシーバー拡張メソッドを定義したいと考えています。

fun (View, Float).dp() = this * resources.displayMetrics.density
// explicitly: fun (View, Float).dp() = this@Float * [email protected]

class SomeView : View {
    
    
  val someDimension = 4f.dp()
}

同様の問題をどのように解決しますか?複数のthisコンテキストを提供するために、通常はwith()

with(view) {
    
    
	42f.dp()
}

with(...){ ... } 入れ子を書きすぎるには、入れ子を避けるために注釈を使用して、Pythonや他の言語から学びます(デコレーター):

#python的decorator:

def hello(fn):
    def wrapper():
        print "hello, %s" % fn.__name__
        fn()
        print "goodby, %s" % fn.__name__
    return wrapper
  
@hello
def foo():
    print "i am foo"

では、デコレータアノテーションを組み合わせて、with(){}によって提供されるレシーバー効果を実現することは可能ですか?

//KT-10468
fun (View, Float).dp() = this * resources.displayMetrics.density

⬇️⬇️

//NOW
with(view) {
    
    
	42f.dp()
}

⬇️⬇️

//Maybe in FUTURE
@with<View>
fun Float.dp() = this * resources.displayMetrics.density

パブリック/プライベートプロパティタイプ


KT-14663:属性を宣言すると、パブリック修飾子とプライベート修飾子の両方が表示されます

private val items = mutableListOf<Item>()
        public get(): List<Item>
//or
val items = mutableListOf<Item>()
        get(): List<Item>

日常の開発では、属性が外部の抽象型と内部の具体型であることが望まれます。
現在の慣行では、次の2つの属性を宣言しています。

private val _items = mutableListOf<Item>()
val item : List<Item> by _items

この問題は非常に自然で理解しやすいので、あまり介入したり変更したりする必要はなく、着陸の条件があります


バリュークラス


以前はdata class不変のデータを表し、元のデータの変更によるdiffの失敗を回避するために、更新のコピーを生成することによって実行されたコピーを使用していました。

// 1. 定义data class
data class State(
	val lastUpdate: Instant,
	val tags: List<String>
)

// 2. 通过copy进行update
state = state.copy(
	lastUpdate = now(),
	tag = state.tags + tag
)

// 3. 使用
notifyOnChange(state)

しかし、入れ子が深すぎると、コピー方法を使用するのが非常に面倒になります。もちろん、メンバーをvarとして定義して直接変更できると言う人もいますが、これにより、後続のdiffの実際の効果が発生します。

// 1. 定义data class
data class State(
	var lastUpdate: Instant,
	var tags: List<String>
)

// 2. 直接update
state.lastUpdate = now()
state.tags += tag

// 3. copy后使用
notifyOnChange(state.copy) //此时如果后续有diff逻辑,会失效

現時点では、このValue Classような問題を解決するために、更新中にコピーを生成できる新しいタイプの設計を試みています。

//val关键字定义class
val class State(
	val lastUpdate: Instant,
	val tags: List<String>
)

// update后,会产生副本
state.lastUpdate = now()
state.tags += tag

概要


Kotlinが好きな場合は、YouTrackをフォローして使用してください。おそらく、Kotlinの将来のバージョンにあなたの考えが現れるでしょう。そして、あなたの貢献はYouTrackに永久に記録されます。

おすすめ

転載: blog.csdn.net/vitaviva/article/details/109129600