關於 Kotlin REPL 的兩條小貼士
Kotlin 自帶了互動式程式設計命令列,即 REPL(Read-Eval-Print Loop 的簡寫,直譯為 “讀取-求值-輸出”迴圈),尤其適合快速實驗一些東西。 本文只講關於 Kotlin REPL 的兩條 tips:
- 如何執行 REPL;
- 如何在 REPL 中檢視推斷出的型別。
如何執行 Kotlin REPL
執行 Kotlin REPL 主要有兩種方式:
- 在 IntelliJ IDEA 中執行;
- 執行獨立的命令列。
直接在 IntelliJ IDEA 中執行 REPL
較新版本的 IntelliJ IDEA(以下簡稱 IDEA)中已經內建了 Kotlin 支援,包括 Kotlin REPL。如果已經安裝了 2017 年版的 IDEA,就可以直接在其中執行 Kotlin REPL。
首先需要在 IDEA 中開啟/建立一個 Kotlin 或者 Java 專案,待專案載入完畢之後,點選如下圖所示的選單:Tools -> Kotlin -> Kotlin REPL:
就會出現 Kotlin REPL 視窗:
在 IDEA 內建的 Kotlin REPL 視窗中鍵入的程式碼,需要按 Ctrl-回車(mac 下為 ⌘↩︎)執行。如果想退出 REPL,點視窗左側的叉號按鈕即可。
IDEA 內建的 REPL 有一些優勢,例如像在程式碼視窗當中一樣擁有語法高亮、智慧提示、程式碼補全等,並且能夠執行專案中的程式碼;但是內建的 REPL 也有一些問題,例如,目前版本在 Windows 下漢字輸出為亂碼等。
執行獨立的 REPL 命令列
某些情況下,我們並不適合使用 IDEA 內建的 Kotlin REPL,比如在遠端 Linux 伺服器上,比如需要在 Windows 下輸出漢字時,再如不需要執行專案相關程式碼並希望少佔資源時。這些情況下都更適合使用獨立的 Kotlin REPL 命令列。
如果本機已安裝較新版本的 IDEA,想要執行 Kotlin REPL 就只需找到它然後執行它即可。它位於 IDEA 所安裝目錄下的 plugins/Kotlin/kotlinc/bin
子目錄中,一般來說如果已安裝 JDK 並已設定好 JAVA_HOME
環境變數,只需將上述子目錄設定為命令搜尋路徑即可通過 kotlinc
命令來執行 Kotlin REPL。對於 Windows 在安裝 JDK 並設定好 JAVA_HOME
之後,可以開啟安裝目錄下的相應子目錄,然後直接雙擊 kotlinc.bat
來執行 REPL。
注:如果 IDEA 有更新過小版本(比如 2017.1.3)或者單獨升級過 Kotlin 外掛,那麼較新版本的 Kotlin REPL 有可能不是在 IDEA 的安裝目錄的子目錄下,而是在類似
~/.IdeaIC2017.1/config/plugins/Kotlin/kotlinc/bin
這樣的目錄中(Windows 下在%USERPROFILE%\.IdeaIC2017.1\config\plugins\Kotlin\kotlinc\bin
目錄中)。
如果本機沒有安裝 IDEA 或者在遠端 Linux 伺服器上,還可以安裝獨立的 Kotlin 編譯器。開啟 Kotlin 最新穩定版在 GitHub 上的釋出頁(https://github.com/JetBrains/kotlin/releases/latest)。下載其中的 kotlin-compiler-*.zip 檔案,將其解壓到指定的目錄,然後可以將其中 bin
所在路徑加入到系統的搜尋路徑中。當然這也要求提前安裝好 JDK 並配置好 JAVA_HOME
。然後就可以在命令列通過 kotlinc
命令來執行 Kotlin REPL 了(Windows 下還是可以找到對應的 kotlinc.bat
雙擊執行)。
獨立執行的 REPL 命令列遵循通用的命令列操作,如 Ctrl-D 退出、Ctrl-R 反向搜尋、Ctrl-S 正向搜尋等等。
如何在 Kotlin REPL 中檢視推斷出的型別
昨天看了 Benny 新發的文章《val b = a?: 0,a 是 Double 型別,那 b 是什麼型別?》,文中詳述了相關現象並分析了原因,是篇深度好文,在此也推薦給大家。
當時就想邊看邊在 REPL 中做實驗,畢竟做實驗這種事情最適合 REPL 做不過了。
遺憾的是 Kotlin REPL 並不回顯型別。在 Kotlin REPL 中鍵入 Benny 文中的示例程式碼:
kotlin var a: Double? = null val b = a ?: 0
並不會有任何回顯,如果想看 b
的型別,確實可以這樣來做:
>>> b::class
class kotlin.Int
這回看到的是 Int
,但是這是有問題的。
通過 b::class
這種方式得到的是 b
實際求值結果 0
的型別,而不是 Kotlin 針對 a ?: 0
這個表示式,在實際求值之前(編譯階段)為 b
推斷出的型別。
如果想看 Kotlin 求值之前推斷出的型別,該怎麼辦呢?
答案是用 lambda 表示式,實際上我在上篇文章《Kotlin 版圖解 Functor、Applicative 與 Monad》 中有提及過,只是不明顯:
> {y: Int -> {x: Int -> x + y}} `($)` Maybe.Just(5) Just(value=(kotlin.Int) -> kotlin.Int)
value=
後面的部分就是 Kotlin 對一個 lambda 表示式的輸出形式,我們可以看一個更直觀的例子:
>>> val f = { 1 }
>>> f
() -> kotlin.Int
f
是一個無參且返回值為 1
的 lambda 表示式。當在 REPL 中對 f
求值時,REPL 中輸出了該 lambda 表示式的型別。這個例子還可以進一步簡化為:
>>> {1}
() -> kotlin.Int
這樣通過 lambda 表示式的返回值型別就能看出 1
在 Kotlin 中被推斷為 Int
。如果要在 REPL 中看 Benny 文章標題所說的示例,只需這樣就可以了:
>>> {
... val a: Double? = 2.0
... a ?: 0
... }
() -> kotlin.Any
通過 lambda 返回值的型別可以看出,a ?: 0
會被推斷為 Any
。這裡 a
的值是 null
還是 2.0
並不影響型別推斷的結果。
我們還可以再看幾個例子來印證 Benny 的文章:
>>> {if (true) 1 else 2.0}
() -> kotlin.Any
>>> interface I; class A : I; class B : I;
>>> {if (false) A() else B()}
() -> Line_8.I
Line_8.I
表示第 8 行定義的型別 I
,也就是說,對於 Int
與 Double
推斷出的公共基類是 Any
,而對於 A
與 B
推斷出的公共基類是 I
,完全印證了 Benny 文中所講的內容。
本文也發在我的個人部落格上:https://hltj.me/kotlin/2017/08/31/2tips-for-kotlin-repl.html。
相關文章
- 【小貼士】關於transitionEnd/animate的一個有趣故事
- 程式設計師程式設計的 7 + 1 條小貼士程式設計師
- win10 小貼士怎麼刪除_win10電腦小貼士怎麼關閉Win10
- 【Cron表示式】小貼士
- 【小貼士】資料庫的備份資料庫
- 前端體驗優化小貼士前端優化
- .Net網頁開發小貼士網頁
- Python開發的10個小貼士Python
- 三個快速便捷的命令列小貼士命令列
- 11個實用經典的SQL小貼士SQL
- 【小貼士】探一探javascript中的replaceJavaScript
- dotnet core 3.0 linux 部署小貼士Linux
- Xcode 6檢視除錯小貼士XCode除錯
- 10個自由職業者日常的智慧小貼士
- 程式設計師面試IT公司的37個小貼士程式設計師面試
- Ubuntu——每日小貼士:Linux上的時光機UbuntuLinux
- java/android 做題中整理的碎片小貼士(4)JavaAndroid
- Swift 小貼士:語言的擴充套件和自定義Swift套件
- 給 Git 中級使用者的 25 個小貼士Git
- 25個Linux 伺服器安全小貼士Linux伺服器
- 【小貼士】RedHat虛擬機器mount新硬碟Redhat虛擬機硬碟
- 獨立開發人員通向成功的29個小貼士
- 面對肺炎疫情小貼士-IT奶爸帶娃記
- Linux 命令列工具使用小貼士及技巧(1)Linux命令列
- Linux 命令列工具使用小貼士及技巧(4)Linux命令列
- Linux 命令列工具使用小貼士及技巧(3)Linux命令列
- Linux 命令列工具使用小貼士及技巧(四)Linux命令列
- Linux 命令列工具使用小貼士及技巧(2)Linux命令列
- Java基礎(二) | 零碎知識小貼士Java
- 由 KRACK 攻擊想到的確保網路安全的小貼士
- 理解Linux Shell和基本Shell指令碼語言的小貼士Linux指令碼
- 如何開始程式語言?給初學者的幾個小貼士
- 程式設計大神進階之路:Python技巧小貼士程式設計Python
- iOS開發小貼士—APP介面跳轉卡死問題iOSAPP
- 配置高效能 ElasticSearch 搜尋引擎叢集的9個小貼士Elasticsearch
- 理解Linux Shell和基本Shell指令碼語言的小貼士(一)Linux指令碼
- 8個對程式設計師來說有用的jQuery小貼士和技巧程式設計師jQuery
- 每個程式設計師需掌握的20個程式碼命名小貼士程式設計師