kotlin能用嵌入式linux,Kotlin在项目中的应用和踩过的坑
應用
空類型安全
Kotlin引入了可空類型(用?標識),在編譯期杜絕了可空類型直接調用方法的可能。
var a: String = "abc"
a = null // 編譯錯誤
var b: String? = "abc"
b = null // ok
val l = a.length
val l = b.length // 錯誤:變量“b”可能為空
val l = b?.length ?: 0
鏈式調用
靈活使用Kotlin提供的let、apply、takeIf這些方法,用鏈式調用的方式組織代碼,可以將一大串邏輯分割成幾塊。
File(url).takeIf { it.exists() }
?.let {
JSONObject(NetworkUtils.postFile(SERVER_URL, url))
}?.takeIf { it.optString("message") == "success" }
?.let {
post(it.optString("result"))
} ?: mHandler.post { view?.onFail() }
默認參數
普通的帶有默認參數的方法Java是無法調用的,因為Kotlin對默認參數的處理并不是生成多個方法,而是給方法添加幾個額外參數記錄調用者傳遞了多少參數,加上了JvmOverloads這個注解之后才會生成多個方法供Java調用。并且Kotlin調用方法可以指定參數名。
class CustomLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), LifeCycleMonitor {
// pass
}
擴展方法
擴展方法在項目里使用得比較少,但是Kotlin提供的很多語法糖都是利用擴展方法實現的,例如forEach、let之類的方法。擴展方法的原理是生成一個靜態方法。
// _Collections.kt里的擴展方法
/**
* Performs the given [action] on each element.
*/
@kotlin.internal.HidesMembers
public inline fun Iterable.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
操作符重載
Kotlin會將一些常用的表達式翻譯為方法調用,最常用的有將 list[0] 翻譯成 list.get(0) ,將 map[0] = someObject 翻譯成 map.set(0, someObject)。實際上任意實現operator fun get(a : Any) : Any 和 operator fun set(a : Any, b : Any) 方法的類都可以使用以上兩種表達式。
// 操作符重載在Kotlin的語法中隨處可見,下面這個例子說明了
for (i in 1..10) {
// pass
}
// 是如何工作的,首先明白表達式 .. 對應 rangeTo 方法,表達式 in 對應 contains 方法
// 在Primitives.kt文件中的Int類里
/** Creates a range from this value to the specified [other] value. */
public operator fun rangeTo(other: Int): IntRange
// 在IntRange類里可以發現 in 這個表達式對應的方法調用 contains
public class IntRange(start: Int, endInclusive: Int) : IntProgression(start, endInclusive, 1), ClosedRange {
override val start: Int get() = first
override val endInclusive: Int get() = last
override fun contains(value: Int): Boolean = first <= value && value <= last
不再使用findViewById
在build.gradle中添加 apply plugin:'kotlin-android-extensions' 就可以直接在代碼中用View的id來代替這個View對象。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
iv_feedback.setOnClickListener(this)
iv_back.setOnClickListener(this)
btn_feedback.setOnClickListener(this)
反編譯發現,這種用法的原理是Kotlin會自動生成findViewById的代碼,在Activity、Fragment和自定義View中Kotlin會使用一個map緩存每次查找到的View,避免每次調用View的方法都會重新調用一次findViewById,但是需要注意的是通過View.id這種方式獲取子View的時候沒有緩存,所以在RecyclerView的ViewHolder中都會使用一個屬性來存儲ItemView的某個子View。
// Activity中的邏輯
public View _$_findCachedViewById(int var1) {
if(this._$_findViewCache == null) {
this._$_findViewCache = new HashMap();
}
View var2 = (View)this._$_findViewCache.get(Integer.valueOf(var1));
if(var2 == null) {
// Fragment的代碼中這里會調用getView.findViewById,所以通過id調用方法需要在onCreateView生命周期之后使用
var2 = this.findViewById(var1);
this._$_findViewCache.put(Integer.valueOf(var1), var2);
}
return var2;
}
// RecyclerView的ViewHolder中都會使用一個屬性來存儲ItemView的某個子View
private val mLabelImage = itemView.label_image
private val mLabelType = itemView.label_type
與屬性相關的一些改變
自帶getter/setter
Kotlin類里的屬性自帶getter/setter,訪問權限可以修改,也可以重寫get/set方法
var someString : String
get() = "this${toString()}"
protected set(value) {
Log.e(TAG, "setValue$value")
field = value
}
可以定義在類聲明里
open class Message(val id: Long,
val type: Int,
val time: Long,
val status : Int)
lateInit和by lazy
對于一些沒有在構造函數里賦值的非空類型對象,可以使用lateinit和by lazy來延遲初始化。
坑
Java調用Kotlin方法時空類型不再安全
Java里調用kotlin方法,空對象傳遞給Kotlin的非可空參數會拋異常,但是Kotlin無法判斷Java傳遞的對象是否可能為空,所以編譯器不會報異常。在將Java工程轉變成Kotlin工程的過程中不能忽略這個坑。
更多
協程
Anko Layouts代替xml
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}
總結
以上是生活随笔為你收集整理的kotlin能用嵌入式linux,Kotlin在项目中的应用和踩过的坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 可以打电话的平板电脑推荐(可以打电话的平
- 下一篇: Linux 临时表空间满了,Tempor