011年,JetBrains宣布開發Kotlin編程語言。這門新語言可以用來編寫在Java虛擬機上運行的代碼,是Java和Scala語言之外的又一選擇。六年后,Google宣布,Kotlin正式獲得官方支持,可用于Android應用開發。
Kotlin的應用范圍迅速擴展,它從一門前途光明的編程語言搖身一變,成了這個世界上最重要的移動操作系統的欽定開發語言。Kotlin語法簡潔,具備現代高級語言特性,并且能和Java遺留代碼無縫互操作。因為具備這些優勢,今天,越來越多的大公司已開始接納Kotlin,如Google、Uber、Netflix、Capital One、Amazon等。
要想知道為什么Kotlin廣受歡迎,首先要理解Java在現代軟件開發領域中所扮演的角色。這兩門語言聯系得非常緊密,因為很多時候,Kotlin代碼的開發目標就是要在Java虛擬機上運行。
Java語言比較穩健,久經考驗。多年來,它一直是最常用的一種編程語言,造就了龐大的生產代碼庫。自從1995年Java問世以來,對于優秀的編程語言應滿足什么條件,人們已通過實踐積攢了很多經驗教訓。然而,Java卻裹足不前,開發者喜歡的很多現代語言高級特性,它都沒有,或者遲遲才加入。
Kotlin從這些經驗教訓中受益良多,而Java(和其他語言,比如Scala)中的某些早期設計卻愈顯陳舊。脫胎于舊語言,Kotlin解決了它們的很多痛點,進化成了一門優秀的語言。相比Java,Kotlin進步巨大,帶來了更可靠的開發體驗。
作為一門新秀語言,Kotlin不僅支持編寫代碼在虛擬機上運行,而且還是一門跨平臺的通用型語言:你可以用Kotlin開發各種類型的原生應用,如macOS應用、Windows應用、JavaScript應用,當然還有Android應用。平臺獨立性意味著Kotlin有各種各樣的用途。
下面我們就來體驗一下Kotlin。
下面我們來學習使用IntelliJ IDEA開發首個Kotlin應用。借此,來熟悉開發環境,創建Kotlin新項目,編寫并運行Kotlin代碼,以及查看輸出結果。本文創建的是一個沙盒項目,可演練代碼,以學習理解本文中的各種新概念。
一、安裝IntelliJ IDEA
IntelliJ IDEA是一套Kotlin集成開發環境。JetBrains公司創建了Kotlin語言并打造出了這套開發工具。開始學習前,請先訪問JetBrains公司網站https://www.jetbrains.com/idea/download,下載IntelliJ IDEA社區開發版軟件(見圖1)。
圖1 下載IntelliJ IDEA社區開發版軟件
下載完畢后,請參考https://www.jetbrains.com/help/idea/install-and-set-up-product.html網頁,完成對應平臺IntelliJ IDEA開發工具的安裝與配置。
IntelliJ IDEA簡稱IntelliJ,能幫助開發者編寫風格良好的Kotlin代碼。利用其內建工具,運行、調試、檢查以及重構代碼的整個開發過程能無縫銜接,一氣呵成。有鑒于此,我們推薦使用IntelliJ做Kotlin開發。若想進一步了解使用IntelliJ做Kotlin開發的理由,請接著往下閱讀。
二、第一個Kotlin項目
Kotlin語言及強大的開發環境都有了,接下來只剩一件事要做:學會流暢運用Kotlin語言。作為首個練手任務,我們來創建一個Kotlin項目。
啟動IntelliJ。如圖2所示,映入眼簾的是IntelliJ IDEA的歡迎界面。
圖2 歡迎界面
若非首次安裝使用,IntelliJ會直接打開上一個項目。要回到歡迎界面,選擇File → Close Project關閉項目即可。
單擊Create New Project選項,會看到如圖3所示的創建新項目對話框。
圖3 創建新項目對話框
在創建新項目對話框中,選擇左側的Kotlin選項,然后選擇右邊出現的Kotlin/JVM選項,結果如圖4所示。
圖4 創建一個Kotlin/JVM項目
除了Kotlin,IntelliJ還支持Java、Python、Scala以及Groovy等其他編程語言。選擇Kotlin/JVM就是告訴IntelliJ你要用Kotlin編程。更確切地講,就是要編寫面向并且在Java虛擬機上運行的Kotlin代碼。順便提一下,Kotlin還有個優勢:內置的工具鏈支持編寫能在不同操作系統和平臺上運行的Kotlin代碼。
(從現在起,提到Java虛擬機,都以Java開發社區常用的JVM來替代。后面還會介紹更多有關面向JVM的知識。)
單擊Next按鈕繼續。你會看到新項目設置界面,如圖5所示。輸入“Sandbox”作為項目名稱,IntelliJ會自動給出默認項目路徑。如有需要,可以單擊右側的…按鈕自定義項目路徑。在Project SDK的下拉框中點選Java 1.8,這樣,新項目就關聯上了JDK 8。
圖5 給新項目命名
你可能會問,編寫Kotlin程序為什么需要JDK?答案就是,為了把Kotlin代碼轉譯為字節碼(稍后詳述),IntelliJ需要JDK提供JVM和Java工具。理論上講,JDK 6及其后的版本都能用,但是經驗表明,至本書撰稿之時,還是JDK 8用起來更順暢。
如果在Project SDK下拉框里看不到Java 1.8,說明你還沒有安裝過JDK 8。繼續學習之前,請先訪問https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html,下載相應平臺的安裝包完成安裝,然后重啟IntelliJ使其生效。最后,按照前述步驟從頭開始創建新項目。
言歸正傳,確認新項目設置如圖5所示,然后單擊Finish按鈕。
如圖6所示,IntelliJ隨即創建一個名為Sandbox的新項目,并在默認的雙面板視圖里顯示出來。反映在硬盤上,IntelliJ會在項目指定路徑創建一個文件夾、一系列子文件夾以及對應的項目文件。
圖6 默認的雙面板視圖
圖6中,左面板顯示的是項目工具窗口。右面板現在空著。待會你會看到,這里會顯示編輯器窗口,供你查看和編輯Kotlin代碼文件。先來看左邊的項目工具窗口。單擊項目名稱Sandbox左側的展開箭頭,可以展現項目包含的文件,如圖7所示。
圖7 項目視圖
在IntelliJ中,項目既包含我們應用的所有源代碼,也包含有相關的依賴和配置信息。項目可以分成一個或多個類似于子項目的模塊。新建項目默認含有一個模塊,對于簡單的Kotlin項目來說,一個就夠了。
如圖7所示,Sandbox.iml文件包含項目模塊的配置信息。.idea文件夾存放整個項目的設置文件,以及用戶在IDE中和項目交互相關的設置文件(例如,當前編輯器打開了哪個文件)。上述文件都是系統自動生成的,現在不用管它們。
External Libraries項包含項目依賴庫的信息。單擊展開該項,可以看到,IntelliJ已自動為項目添加了Java 1.8以及KotlinJavaRuntime依賴庫。
想了解更多有關IntelliJ項目結構的知識,請訪問JetBrains文檔網址:https://www.jetbrains.org/intellij/sdk/docs/basics/project_structure.html。
src文件夾用來存放為Sandbox項目創建的所有Kotlin代碼文件。好了,是時候來創建并編輯首個Kotlin代碼文件了。
1. 創建首個Kotlin文件
在項目工具窗口中,右擊src文件夾。如圖8所示,在彈出的菜單中,依次選擇New和Kotlin File/Class菜單項。
圖8 新建一個Kotlin文件
在New Kotlin File/Class對話框中,在Name處輸入文件名“Hello”,保持Kind處的File選項不變(見圖9)。
圖9 給Kotlin文件命名
單擊OK按鈕確認。如圖10所示,IntelliJ隨即新建了src/Hello.kt這樣一個項目文件,同時在IntelliJ右邊窗口的編輯器里打開該文件。我們知道,.java后綴用于Java文件,.py后綴用于Python文件,同樣,.kt后綴說明新建文件存放著Kotlin代碼。
圖10 編輯器中的Hello.kt空文件
現在,可以開始編寫Kotlin代碼了。在Hello.kt編輯器中,動動手,輸入代碼清單1-1所示的代碼。
注意,本文中所有需要讀者輸入的代碼都顯示為粗體。
代碼清單1-1 “Hello,World!”Kotlin語言版(Hello.kt)
fun main(args: Array<String>) { println("Hello, world!") }
不太明白剛剛輸入的代碼?不要擔心,之后你一定能自然、流利地讀寫Kotlin代碼?,F在只要大致知道是輸出“Hello,World!”字符串就可以了。
代碼清單1-1中的代碼定義了一個main新函數。函數實際就是一組可以稍后運行的代碼指令。
對于Kotlin語言來講,main函數有特別的意義。它是應用程序開始啟動的地方,又稱為應用程序入口點。Sandbox或任何應用程序要能運行,都必須定義這樣的入口點。
上述代碼中的main函數僅包含一條指令(也叫語句):println("Hello, world!")。println()也是個函數,內置于Kotlin標準庫中。Sandbox應用程序一旦運行,println("Hello, world!")就會執行,IntelliJ隨即在屏幕上輸出圓括號中的Hello, world!字符串。
2.運行Kotlin文件
如圖11所示,一旦輸入完代碼清單1-1中的代碼,在第一行代碼左側,會出現一個綠色的運行按鈕
如果綠色運行按鈕沒出現,或者Hello.kt文件名或某段代碼下方被打上了紅色波浪線,則說明代碼有誤,請對照代碼清單1-1仔細核對修改。另外,如果看到Kotlin的紅藍K標志也沒問題,它相當于運行按鈕。
圖11 運行按鈕
代碼無誤的話,Hello, world!應用程序就可以運行了。如圖12所示,單擊運行按鈕,選擇Run ‘HelloKt’菜單項。這相當于告訴IntelliJ,你想看著應用程序運行起來。
圖12 運行Hello.kt文件
應用程序運行時,IntelliJ就一行一行執行花括號({})里的代碼,同時在IDE界面底部顯示兩個新工具窗口,如圖13所示。
圖13 運行和事件日志工具窗口
圖13中,左邊是運行工具窗口,又叫控制臺(后續都這樣稱呼)??刂婆_顯示IntelliJ執行應用程序時產生的各種信息,也包括應用程序本身的輸出。就本例來說,你會看到控制臺顯示Hello, world!字符串,還會看到標志應用程序成功執行的語句:Process finished with exit code 0。這條語句會出現在控制臺各種輸出信息的最后。
macOS用戶可能會看到紅色的錯誤文本,指出JavaLauncherHelper有問題,如圖13所示。不要擔心。這是在macOS上安裝Java運行時環境的方式所帶來的副作用。要想移除它得費一番工夫,不過這個問題并沒有什么影響,所以大可忽略它,繼續操作。
圖13中,右邊是事件日志工具窗口。該窗口顯示IntelliJ為應用程序執行所做工作的相關信息。顯然,控制臺才是我們要關心的地方,所以事件日志窗口后續不會再提起。(同理,你也不用管事件日志窗口在應用程序運行時是否打開。)要關閉事件日志窗口,單擊右上角的隱藏按鈕
即可。
編譯并運行Kotlin代碼
從點選Run ‘HelloKt’菜單項至控制臺輸出Hello, World!結果只需很短的時間,但后臺實際已忙活了不少事。
首先,IntelliJ使用kotlinc-jvm編譯器編譯Kotlin代碼。具體來講,就是把Kotlin代碼轉換為JVM語言:字節碼。轉換過程中,如有問題,kotlinc-jvm會報錯并給出排錯提示;一切順利的話,IntelliJ就進入執行階段。
在執行階段,kotlinc-jvm生成的字節碼會在JVM上執行。控制臺隨后會打印程序輸出,例如,在JVM一條條執行指令時,調用println()函數會輸出傳入其中的文字。
字節碼指令執行完畢后,JVM隨即終止。IntelliJ在控制臺顯示終止狀態,告訴用戶執行成功完成或是有錯并給出錯誤碼。
這里要說的是,即使不能完全理解Kotlin的編譯過程,也不妨礙你閱讀本文及接下來的內容。
三、Kotlin REPL
就像拿張稿紙就某個計算一步步演算那樣,有時候,你可能需要測試一小段Kotlin代碼,看看運行結果如何。這在學習Kotlin語言時非常有用。幸運的是,IntelliJ就提供了這種工具,能夠實現無須創建文件就快速測試代碼。該工具叫作Kotlin REPL。稍后會解釋REPL的含義,現在先打開它,看看能用它做些什么。
如圖14所示,在IntelliJ中,選擇Tools → Kotlin → Kotlin REPL打開Kotlin REPL工具窗口。
圖14 打開Kotlin REPL工具窗口
如圖15所示,IntelliJ會在底部顯示REPL窗口。
圖15 Kotlin REPL工具窗口
你可以在里面輸入代碼,就像使用代碼編輯器一樣,但有一點不同:REPL不用編譯整個項目,就能立即給出結果。
在REPL中輸入代碼清單1-2所示的代碼。
代碼清單1-2 “Hello, Kotlin!”(REPL)
println("Hello, Kotlin!")
輸入完成后,按Command-Return(Ctrl-Return)組合鍵在REPL中執行代碼。如圖16所示,很快,你就會在下面看到Hello, Kotlin!輸出結果。
圖16 執行代碼
REPL是英文單詞read(讀?。valuate(求值)、print(輸出)和loop(循環)的首字母縮寫。整個運轉流程如下:在提示符下輸入一段代碼,然后單擊REPL左側的綠色運行按鈕或按Command-Return(Ctrl-Return)組合鍵提交。REPL讀取代碼,代碼求值(運行代碼),輸出結果或副作用結果。運行完畢,REPL交回控制權,循環再次開始。
Kotlin之旅已然啟航!你在本文學了不少內容,已為進一步掌握Kotlin編程打下基礎。接下來可以繼續跟著《Kotlin編程權威指南》的第2章(在圖靈社區免費開放,點擊閱讀原文跳轉),繼續探索Kotlin語言的細節,學習如何使用變量、常量以及各種數據類型。
——本文內容節選自《Kotlin編程權威指南》
它源自大名鼎鼎的Big Nerd Ranch訓練營培訓講義,該訓練營已經為Google、Facebook、微軟等行業巨頭培養了眾多專業人才。通過搭建各種示例項目,在實踐中掌握Kotlin。
四、深入學習:為什么要用IntelliJ
任何文本編輯器都可以用來編寫Kotlin代碼,不過,我們推薦使用IntelliJ,尤其是在學習這門語言的時候。如同憑借文字處理軟件的拼寫和語法檢查功能,能更輕松地寫出規范的文章一樣,IntelliJ也更便于編寫規范的Kotlin代碼。這主要體現在以下幾個方面。
而且,由于Kotlin和IntelliJ都出自JetBrains公司,它們之間的集成設計更為細致周全,為用戶帶來了愉快的開發體驗。另外,Android Studio基于IntelliJ開發,所以使用IntelliJ時學會的快捷操作和工具都可以直接運用。
五、深入學習:面向JVM
JVM本質上是個軟件,它知道如何執行字節碼指令?!懊嫦騄VM”就是把Kotlin代碼編譯或轉譯成Java字節碼,以實現在JVM上運行,如圖17所示。
圖17 編譯和執行流程
Windows平臺也好,macOS平臺也罷,它們都有各自的指令集。JVM搭起了字節碼與不同軟硬件平臺間的橋梁,讀取字節碼并調用平臺特有的與之匹配的指令。顯然,不同軟硬件平臺有不同版本的JVM。這樣一來,Kotlin開發人員就可以編寫平臺獨立的程序代碼,無論什么系統平臺,都可實現一次編寫,然后編譯成字節碼,在不同設備上執行。
既然能轉換成JVM可以執行的字節碼,Kotlin也就是JVM語言。作為首門JVM語言,Java最為知名。在后來者,如Scala和Kotlin語言中,開發人員揚長避短,已消除了“前輩”Java的一些弊端。
不過,Kotlin并未局限于JVM。如今,Kotlin已能編譯成JavaScript,甚至能脫離虛擬機層,直接編譯成可以在Windows、Linux和macOS平臺上運行的原生二進制代碼。
六、挑戰練習:使用REPL研究Kotlin中的算數運算符
《Kotlin編程權威指南》很多章最后都配有挑戰練習。請獨立完成它們,以加深對Kotlin語言的理解,積累更多經驗。
使用REPL研究Kotlin中的+、-、*、/以及%這些算數運算符是如何工作的。例如,在REPL中,嘗試輸入(9+12)*2。結果符合預期嗎?
還想深入研究的話,可以看看https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/index.html網頁列出的Kotlin標準庫里的數學函數,在REPL里做做演練。例如,試試minOf (94, -99),求出最小值。
——
【圖靈教育】
閱讀改變世界,閱讀塑造人生
讓我們站在巨人的肩膀上,解鎖更多IT技能!
近日,開發者 Samuel Tulach 在個人博客上感嘆道,“在 Windows 上編寫 GUI 應用程序真是太難了!”在文中, Samuel Tulach 討論了使用 C++ 編寫 GUI 應用的各種困難。他詳細列舉了幾種流行的庫,但這些庫通常會面臨諸如依賴項管理、應用程序大小以及樣式定制等問題,并沒有完全契合的解決方案。
萬萬沒想到,這個小吐槽引起了不少開發者的共鳴,甚至登上了 HN 熱榜。接下來,我們將通過本文看看難點究竟在哪里?
過去幾天里,來自捷克的程序員 Samuel Tulach,一直在尋找一個能夠讓他用 C++ 編寫帶有 GUI 程序的庫。他給出的要求非常簡單:
所以,Samuel Tulach 開始挑選一些稱手的工具、框架,結果發現并沒有想象中那么簡單。
首先,Samuel Tulach 從專為 Windows 應用程序開發而設計的現代化的用戶界面(UI)框架——WinUI 3 入手。
乍一看,它是個不錯的選擇。它允許你使用現代的 Windows 組件,還可以自定義樣式顏色。設計方面,你可以使用非常容易掌握的 XAML,或者直接使用 Visual Studio 設計器。
WinUI 3 控件庫
問題:使用 WinUI 3 框架開發的應用程序在發布時不能以無包裝(unpacked)的形式進行分發。這意味著無法將應用程序打包為一個單獨的可執行文件(.exe)及其所需的所有依賴項,而是需要依賴于特定的分發方式,如打包為 AppX 包或者通過 Microsoft Store 進行分發。
對于 Samuel Tulach 而言,大多數情況下,當他嘗試將應用程序遷移到虛擬機或不同計算機時,由于缺少一些不明依賴項而無法正常啟動。更糟糕的是,你需要提供一堆處理 WinUI 功能的 .dll 文件,沒有辦法提供一個可移植的 .exe 文件。使用打包形式通常沒有問題,但它們是以 AppX 包的形式安裝的,這本身就會帶來很多問題(尤其是在需要訪問所有 Win32 API 的情況下)。
緊接著,Samuel Tulach 將目光轉移到了 Win32 身上。Win32 是一種應用程序編程接口(API),它是微軟 Windows 操作系統的核心組成部分。它提供了開發者與操作系統交互的一組標準接口和功能,用于創建和管理 Windows 應用程序的各個方面,包括窗口、消息處理、文件操作、網絡通信等。
Samuel Tulach 表示,其需要高度的可移植性,因此使用操作系統的原生渲染是有道理的。這樣的程序可以是一個單一的 .exe 文件(因為我們對 MFC 進行了靜態鏈接),而且體積超小(只有幾千字節)。
同時,Samuel Tulach 稱,還可以使用別人已經編寫好的更簡約的庫,這意味著從概念到可運行應用程序的快速實現將變得非常容易。
基本 Win32 形式
問題:對原生的 Win32 控件進行樣式化處理是一項非常困難的任務。為了改變這些空間的外觀和風格,Samuel Tulach 需要為每一個控件編寫一個專門的自定義繪制函數,這個過程不僅需要詳細了解 Win32 API 的繪制機制,還需要大量的時間和精力投入。
對此,Samuel Tulach 吐槽稱,“有這個時間,我都可以直接去養家糊口了。”
此外,Windows 文件資源管理器(File Explorer)使用的一些原生 Win32 控件具有一個被稱為 “隱藏” 的暗色模式。用戶可以激活這個模式,但它只會對部分控件生效,并且在視覺效果上并不十分理想或完善。
Qt 在 C++ 圖形用戶界面開發中被認為是一個非常優秀的選擇。盡管它相對復雜,但它提供了 Qt 樣式表(Qt Style Sheets),這使得開發者可以輕松地設計和定制界面的外觀和樣式。Qt 樣式表使用一種類似于 CSS 的語言,讓開發者可以用熟悉的方式來定義控件的外觀、布局和交互效果。
OBS studio 使用 Qt 和自定義樣式表
然而,問題在于,當使用動態鏈接方式時,運行 Qt 應用程序需要大量不同的 .dll 文件,這些文件總共的大小超過了 40MB。為了減少文件大小,可以選擇將 Qt 靜態鏈接到應用程序中,這樣未使用的部分會被移除,從而減小應用程序的體積。
不過,Qt 使用的是 LGPL 許可證。根據 LGPL 的條款,如果選擇靜態鏈接 Qt,那么必須遵守 LGPL 的要求之一:要么開源應用程序的源代碼,要么提供用于重新編譯的目標文件。另外,Qt 也提供了商業許可證選項,可以以幾千美元的價格購買,從而免除遵守 LGPL 條款的義務,只是這樣成本又太高了。
wxWidgets(https://www.wxwidgets.org/)是一個相對容易學習的庫,還可以使用 wxFormBuilder。它所遵循的許可證要比 Qt 更寬松,可以靜態鏈接成一個 3MB 的可執行文件。
wxWidgets 啟用了實驗性的 Windows 暗模式選項
問題:wxWidgets 是一個在 Windows 上使用原生的 Win32 組件的庫。然而,與直接使用 Win32 或 MFC 相比,wxWidgets 并沒有提供輕松覆蓋繪制函數的選項,因此在樣式定制方面甚至比直接使用 Win32 或 MFC 更為困難。
盡管 wxWidgets 支持應用 Windows 文件資源管理器的暗模式控件,但實際效果并不理想。
hikogui
hikogui(https://github.com/hikogui/hikogui)是一個相對較新的保留模式 GUI 庫,它使用 Vulkan 作為后端技術。這意味著它利用 Vulkan 的強大功能來進行圖形渲染和顯示。hikogui 內置了暗模式的支持,開發者可以很容易地自行定制和樣式化界面,以適應應用程序的需求和設計風格。
問題:要成功編譯 hikogui,可能需要具備計算機科學博士學位,特別是在編譯器開發方面的專業知識。在體驗過程中,Samuel Tulach 嘗試了超過 30 分鐘去編譯示例,包括嘗試不同的代碼分支和發布標簽,但最終只得到了一個立即在某個 Vulkan 庫內發生訪問沖突的可執行文件,因此他決定放棄嘗試。
不過,盡管 Samuel Tulach 不太喜歡大量使用 STL(標準模板庫),甚至認為有時候并不是必需的,但他認為 hikogui 看起來確實有前景。
Sciter 實際上是一個不錯的 Electron 替代品,允許開發者使用 HTML/CSS 編寫桌面應用程序的 GUI。
SVG 圖標上抗鋸齒效果不佳的示例
問題:你可能認為應用程序大小或稱為一個問題,但實際上,包含所有必需的 .dll 文件的最終應用程序大小大約只有 25MB,這對 Samuel Tulach 來說完全可以接受。
Samuel Tulach 表示,如果 Sciter 能夠完全開源,那將是更好的選擇,因為這樣開發者可以將靜態鏈接版本用于商業用途(與 Qt 的問題相同)。同時,Sciter 的獨立許可證價格相比 Qt 要低不少(目前為 310 美元),Samuel Tulach 也愿意為此支付費用。
然而,現在不選用這個框架的主要原因在于,如上圖所示(看看標題欄圖標),渲染效果不太好。在體驗過程中,Samuel Tulach 透露其遇到了各種字體和圖像的抗鋸齒問題(啟用了高分辨率選項,即使在預編譯的 scapp.exe 中也存在這個問題)。而且,無論你做什么,窗口都會有一個相當厚(2-3 像素)的灰色邊框,完全無法自定義或修改。
如果你在一些論壇上詢問關于在 Windows 上使用 C++ 編寫 GUI 庫的問題,大概率會收到一些“這不是一個好主意”等類似的反饋,甚至論壇上的專家們會直接建議你采用其他技術堆棧來編寫應用程序的前端部分,然后將用 C++ 編寫的功能作為組件或模塊加載進來。
這種做法可以讓你更輕松地定制和風格化界面,并顯著加快開發速度。從技術角度來看,確實可以使用像 WinForms 或 WPF 這樣的工具生成一個體積較小的單獨可執行文件(.exe)。
詳細來看,有兩種方式可以實現:
問題:.NET Framework 在 Windows 10 及更新版本中是預裝的,因此從技術上來說,我們仍然可以滿足無依賴項的標準。然而,如果我們選擇將 C++ 編寫的功能模塊打包為 .dll 文件,我們仍然需要在運行時將這些 .dll 文件從打包的資源中提取到一個臨時位置,并編寫額外的 P/Invoke 代碼來調用這些模塊。
此外,如果使用 C++/CLI 編譯,生成的代碼將轉換為 .NET IL 代碼。換句話說,生成的應用程序可以在調試工具(如 dnSpy)中打開,你可以看到 C++ 代碼被翻譯為等效的 C# 代碼。這種情況下,生成的應用程序并不是純粹的原生代碼應用程序,而是包含了.NET Framework 的中間代碼。
而正如文章伊始所提及的,Samuel Tulach 想要原生的代碼,所以基于 WinForms 或 WPF 得到的代碼并不他真正想要的。
以上是 Samuel Tulach 考慮過的幾個方案。經過長時間嘗試各種不同的庫,甚至一度編寫自己的 MFC 樣式之后,Samuel Tulach 發現對于簡單的應用程序來說,沒有什么比 Dear ImGui 更合適的了。
Dear ImGui 是一個用于 C++ 的輕量級界面開發框架,它的主要目標是提供高效、靈活和易于使用的界面開發工具。Dear ImGui 是一個基于文本的界面開發框架,它使用簡單的文本命令來創建和更新用戶界面。
不過,Dear ImGui 在設計復雜的用戶界面時也有一些缺點,而且它不是保留模式的用戶界面,而是即時模式的用戶界面,因此想要使用,必須運行像 DirectX 這樣的 GPU 渲染器來渲染每秒 60 幀或更多幀的用戶界面。
正如上圖所示,Samuel Tulach 已經寫了一個示例,如何使用內置的多視口功能來制作簡單的圖形用戶界面應用程序。
編譯后的程序大小只有500KB,非常小巧。這個程序不需要安裝任何額外的依賴項,即使是將 MFC(Microsoft Foundation Classes)靜態鏈接到程序中,也不需要安裝 VC++(Visual C++)的運行時庫。這使得部署和使用這個程序變得非常簡便,用戶可以直接執行這個程序而無需擔心缺少運行時組件或依賴項。
對于 Samuel Tulach 這段經歷,不少開發者感同身受。來自 HN 的網友 pshirshov 表示:
我也有過類似痛苦的經歷。我需要一個真正跨平臺(Windows、Linux/Wayland、Mac、iOS、Android)的 GUI 工具包,它要有豐富的控件庫和合理的主題。事實上,唯一不錯的選擇是 QT,而使用 C++ 很難提高效率,因為它仍然缺乏基本功能,如類型解構和帶窮舉檢查的 ADT/GADT。QT 與其他語言的綁定還不夠成熟。
除了 QT 之外,還有漏洞百出的 Avalonia。對 Linux 的支持非常糟糕。
此外還有 Kotlin/Compose Multiplatform。它缺乏良好的文檔和先進的控件,而且仍然充滿 Bug。
我無法找到任何適用于 JS/TS 的優秀控件庫,即使是付費的控件庫(如 Telerik 和其他控件庫)也非?;靵y。因此,Electron、Capacitor、React Native——它們都認為即使是一個非?;镜膽贸绦蛞残枰度氪罅烤?。
Flutter 給人的感覺極不成熟,尤其是全局單例模式的普及使得在使用 Flutter 時,即使是管理小型代碼庫也變得非常困難。
另一用戶稱:
在 Mac 上我遇到同樣的困擾,我在 Mac 上 SwiftUI 的體驗是,它仍需要大量工作。文檔很差。如果你以直截了當的方式做事,性能可能會很差。支持舊版本的操作系統相當痛苦等等。
至此,你是否體驗過 GUI 開發?有哪些工具推薦?
來源:
https://news.ycombinator.com/item?id=40839208
https://tulach.cc/writing-gui-apps-for-windows-is-painful/