標籤:

Kotlin傳教文 上

本文向您介紹Kotlin語言的一些奇特之處,方便您對Kotlin這門語言建立一個簡單的概念。

很久沒發文章了,我覺得應該勤奮一點。。。嚯呀。。

我搞了個微型新聞

既然Kotlin是門強大的語言,看看anko就知道它有多厲害了。於是我也基於Kotlin的extension給FriceEngine寫了個DSL系統。先看看它長啥樣吧:

創建遊戲窗口:

game {nn}n

設置寬為80,添加一個橢圓並設置一些屬性:

game {ntbounds {nttwidth = 800nt}ntoval {nttx = 20.0nttwidth = 120.0nttcolor = BLUEnt}n}n

多麼簡單的寫遊戲方法啊,這就創建了一個FriceEngine的遊戲窗口,添加物體的代碼看起來也是那麼友善。類似的API還有rectangle、button、text等,用於向畫面添加元素。

那麼原理是什麼呢?這就涉及Kotlin的高級姿勢——extension啦。建議閱讀本文之前,先對前文中所描述的這個引擎有個基本概念,方便理解引擎的工作流程。

extension是啥

用過anko開發Android的朋友們應該都知道。在Kotlin中,有一種神奇的黑科技語法,它為Kotlin構造UI DSL和Gradle做成了最主要的貢獻:

infix fun Range.step(step: Int): Range {nt// codesn}n

這段代碼定義了一個方法,這個方法屬於Range類,參數是一個Int。infix表示該方法可以寫成中綴表達式的形式。調用的話就能這樣調用了:

(0..width step 2).forEach { i ->n}n

這個給類添加方法的語言特性看起來神奇到爆,就像Ruby的打開類一樣。這是在元編程嗎?顯然不是的,JVM位元組碼不可能幹這種事。又不是Groovy。這種寫法可比Groovy的Gradle簡單啊。

因此我作為一個追求真理的人,寫了一段extension之後自行逆向位元組碼+使用Java成功調用,發現並證實了其中的奧秘。這段代碼被編譯到JVM後變成了這樣:

public Range step(Range $reciever, int step) {nt// codesn}n

原來如此!調用者成為了一個參數。這也是extension不能用於Kotlin庫文件作用域之外的原因,因為它其實只是個普通的方法。

通過這個原理我封裝了我的Android的讀取URL資源的工具方法:

fun String.webResource(submit: (String) -> Unit, default: String = DEFAULT_VALUE) {ntasync() {nttvar ret = readString(default)nttuiThread { submit(ret) }n//ttLog.i("important", "ret = $ret")nttLog.i(this@BaseActivity.toString(), this@webResource)nttif (!ret.equals(DEFAULT_VALUE) && !haveNetwork) {ntttuiThread { submit(ret) }ntt} else {ntttret = java.net.URL(this@webResource).readText(Charsets.UTF_8)ntttuiThread { submit(ret) }ntttsave(ret)ntt}nt}n}n

然後要獲取網路資源的話,直接使用」Frice Group · GitHub」.webResource { s -> textView_main.text = s }就能獲取網路資源了。這種寫法顯然高大上多了。

於是就有了這樣的代碼:

// 聲明nfun Int.elapsed(): Boolean {n}nn// 調用nif (1000.elapsed()) {nt/* codes */n}n

嗯,差不多就是這樣。而且由於方法是擴展方法,方法內部的上下文是被擴展的類。什麼意思呢?考慮如上代碼。在elapsed函數內部使用this,得到的是Int,而不是Game。因此,擴展方法是可以修改局部上下文的。這為DSL的構建提供了方便。

下次講代碼塊、inline、crossinline、noinline。預計三篇能把Kotlin這特性說完。

嘛,就這樣啦。歡迎圍觀寒冰Frice全家桶:

  • Frice-JVM
  • Frice-CLR
  • Frice-Designer
  • Frice-Demo
  • Frice-DSL

,求star求follow!QwQ


推薦閱讀:

val b = a?: 0,a 是 Double 類型,那 b 是什麼類型?
#Kotlin# Activity 之朝花夕拾

TAG:Kotlin |