reified
代码里的应用场景不算多,举几个库的用法作为例子:
Gson:
// JavaUserInfo userInfo = gson.fromJson(jsonString, UserInfo.class); // Kotlinval userInfo = gson.fromJson<UserInfo>(jsonString)
Spring:
// JavaGenericApplicationContext context = new GenericApplicationContext();context.registerBean(Foo.class);context.registerBean(Bar.class, () -> new
Bar(context.getBean(Foo.class)));// Kotlinval context = GenericApplicationContext {
registerBean<Foo>()
registerBean { Bar(it.getBean<Foo>()) }}
Anko:
// JavastartActivity(Intent(this, OtherActivity.class))// KotlinstartActivity<OtherActivity>()
inline扩展函数+后置lambda
大部分成对的操作都可以用inline扩展函数+后置lambda让代码变得更优雅,比如标准库里的这个lock写法,就隐藏了try-finally的模板:
val lock = ReentrantLock();val result = lock.withLock {
// access a locked resource}
val readWriteLock = ReentrantReadWriteLock()readWriteLock.read {
// execute an action with a read lock}readWriteLock.write {
// execute an action with a write lock}
聪明的你应该能联想到:io流、数据库事务之类的操作也能这样子写
inline扩展函数+后置lambda常见的应用还有标准库里的:run、with、apply、also、let等函数,建议灵活使用,有趣的是他们其中有的可以改变上下文(this),比如创建实例并初始化的操作:
// PaintmPaint = Paint().apply {
color = PAINT_COLOR
textSize = textSize
textAlign = Paint.Align.CENTER
strokeWidth = STROKE_WIDTH
strokeCap = Paint.Cap.ROUND}
// WebViewmWebView.settings.run {
javaScriptEnabled = true // NOTICE: XSS builtInZoomControls = false
displayZoomControls = false
// other setting...}
(・ω・)ノ 事实上有了apply,Builder模式已经变得可有可无了
很多刚接触Kotlin的Android开发者常写这样的代码:
var userInfo: UserInfo? = null
tvName.text = userInfo?.userName
tvPhone.text = userInfo?.phone
// show data from userInfo...
毕竟Android框架到处都是回调,很多成员变量都是在生命周期的回调中赋值的,但是Kotlin又需要控制Nullable。这时候可以考虑用lateinit关键字(当然你要记得初始化),或者另外一种写法:
userInfo?.run {
tvName.text = userName
tvPhone.text = phone
// ...
}
这时候在block内,userInfo一直是非null的,run还顺手把上下文打开了 (・ω・)ノ
如果你的代码出现大量的?.或者!!或者?:,那么你可以考虑用run、let等函数换种写法