Dart 常見問題
本頁收集了社群中的一些熱門問題。
通用
#問:Dart 有規範嗎?
#是的。ECMA-408 涵蓋了 Dart 程式設計語言規範。
已釋出五個版本。最新的進行中版本涵蓋到 Dart 2.13-dev。
| 版本 | 釋出日期 | 批准日期 | 涵蓋版本 |
|---|---|---|---|
| 第 6 版 picture_as_pdf | 2024 年 1 月 24 日 | 2.13-dev | |
| 第 5 版 picture_as_pdf | 2021 年 4 月 9 日 | 2.10 | |
| 第 4 版 picture_as_pdf | 2015 年 8 月 19 日 | 2015 年 12 月 | 1.11 |
| 第 3 版 picture_as_pdf | 2015 年 4 月 15 日 | 2015 年 6 月 | 1.9 |
| 第 2 版 picture_as_pdf | 2014 年 11 月 21 日 | 2014 年 12 月 | 1.6 |
| 第 1 版 picture_as_pdf | 2014 年 3 月 27 日 | 2014 年 6 月 | 1.3 |
要了解更多關於規範的資訊,請檢視 Dart 語言規範頁面。
問:你們如何接收有關 Dart 變更的意見?
#團隊會聽取反饋、閱讀問題報告,並審查貢獻者提交的補丁。有良好記錄的貢獻者可以獲得倉庫的寫入許可權。Google 工程師也在公共倉庫中工作,進行可見的變更。該專案已收到許多外部補丁,並歡迎分散式提交者。
語言
#問:Dart 和 Java 很像嗎?
#Dart 和 Java 有一些相似之處。要檢視使用熟悉語法的簡短示例,請參閱 Dart 簡介中的程式碼示例。
問:Dart 和 Go 有什麼關係?
#Google 啟動了 Dart 和 Go 語言專案。這些獨立的專案有不同的目標,因此做出了不同的選擇。這兩種語言本質上非常不同,但團隊成員可以相互學習。
問:為什麼 Dart 和 Haskell / Smalltalk / Python / Scala / 其他語言不像?
#原因多種多樣,取決於用於比較的語言。
- 與 JavaScript 的差異
- Dart 必須編譯為高效的 JavaScript。與 JavaScript 差異過大的源語言可能會生成複雜的輸出程式碼來模擬源語言的行為。這會導致效能以程式設計師不易察覺的方式變化。
- 編譯為原生程式碼的語言
- Dart 優先考慮高效編譯為機器碼。因此,它與一些其他編譯型語言有一些共同之處。
- 被認為比 Dart“更動態”的語言
- Dart 選擇犧牲一些任意的執行時修改能力,以實現更好的效能和更高效的工具。
問:為什麼 Dart 語法不更有趣?
#一些不錯的語法特性確實存在,比如 this. 建構函式引數和用於單行函式的 =>。Dart 選擇熟悉性而非新穎性。
問:Dart 支援反射嗎?
#- 伺服器和命令列指令碼
- 是的,Dart 透過 mirrors API 支援反射。
- Web 或 Flutter 應用
- 不,Dart 不支援編譯到 web 或 Flutter 應用時的反射。
問:Dart 能新增我想要的語言特性嗎?
#未來版本可能包含您想要的特性。有些特性不符合語言的本質。有些特性與其他特性不相容。簡潔性是給予未來程式設計師最重要的禮物。
要檢視是否有人已提交您的請求,請檢視語言提案漏斗和語言問題列表。
如果問題已存在,請點贊。
如果問題不存在,請提交新的問題。
為您的特性提出深思熟慮的論證。為您的論證新增證據。包括使用或不使用您的特性的示例程式碼,或提供可觀的程式碼庫。
要了解更多資訊,請參閱語言演進流程。
如果 Dart 語言團隊拒絕了您的請求,請不要感到驚訝。移除語言特性比新增更痛苦。Dart 語言團隊首先新增最顯而易見的特性,稍後再回顧下一層次的特性。
社群提出的特性請求會比任何單一語言在不變得一團糟的情況下所能滿足的都要多。Dart 語言團隊確實重視建議和證據。這種重視應透過仔細的設計選擇和公平的溝通體現出來。
型別系統
#問:Dart 使用靜態型別嗎?
#是的,Dart 使用靜態型別。要了解更多資訊,請參閱 Dart 的型別系統。
結合靜態和執行時檢查,Dart 擁有健全的型別系統。這保證了某種型別的表示式不會產生另一種型別的值。
如果您需要動態型別的靈活性,可以使用 dynamic 註解任何變數。這個 dynamic 型別是靜態的,但在執行時可以包含任何型別。這會使該變數失去許多型別安全語言的好處。
問:為什麼泛型是協變的?
#協變泛型符合程式設計師的普遍直覺,而且這種直覺通常是正確的,例如在常見的泛型“只讀”使用場景中。儘管這種直覺並非總是正確,但 Dart 透過採用協變泛型來傾向於便利性。
唯一合理的其他預設變體是不可變(invariance)。雖然只使用不可變泛型肯定會防止更多錯誤,但它也會阻止許多有效的程式,或者要求每次您有一個“蘋果”列表而有人只想要“水果”時進行轉換。
我們熟悉各種語言嘗試標記或推斷變體的方式。我們認為變體推斷系統在 Dart 中帶來的好處不足以彌補其增加的複雜性。
再再一次,我們力求務實,並且認為結果是合理的。
用法與工具
#問:Dart 支援 JSON 嗎?
#是的。要了解更多資訊,請查閱 dart:convert 庫中的 JSON 轉換器。
問:Dart 可以在伺服器端執行嗎?
#是的。要了解更多資訊,請參閱 伺服器端 Dart。
問:如何使用第三方程式碼或共享程式碼?
#在 pub.dev 網站(Dart 和 Flutter 的包託管服務)上搜索包。使用 pub 命令打包您的程式碼並上傳到該網站。
問:編寫 Dart 程式碼是否需要特定的編輯器或 IDE?
#不。您可以使用 DartPad 試用 Dart 程式碼,然後使用您喜歡的編輯器或 IDE 進行開發。一些功能齊全的 IDE,例如 IntelliJ IDEA、WebStorm 和 Visual Studio Code,都有 Dart 外掛。許多編輯器也存在開源的 Dart 外掛。有關更多資訊,請參閱 Dart 工具。
問:我可以用 Dart 構建 Android 應用嗎?
#是的!您可以使用 Flutter 框架和 Dart 語言構建 Android 應用。您編寫的任何 Flutter 應用也可以在 iOS、Web 和桌面平臺執行。
問:有哪些 Dart 在實際生產環境中的部署案例?
#Google Ads、AdSense、AdMob 和 Google Assistant 都使用 Dart。Google 的很大一部分收入來自這些應用。在 Google 內部或外部,每個 Flutter 應用都使用 Dart。
原生執行
#問:Dart 是單執行緒的嗎?
#不。在原生目標上,Dart 的 isolate API 可以在需要時啟動多個執行執行緒。Dart VM 使用多個 CPU 核心同時執行這些執行緒。
Dart 的併發架構抽象了典型共享記憶體執行緒中複雜且易出錯的程式碼。這也許解釋了為什麼人們誤認為 Dart 是單執行緒的。
併發在 Dart Web 應用中的工作方式不同。要了解更多資訊,請參閱 Dart 在 Web 上是單執行緒的嗎?
問:我可以將 Dart 程式碼編譯為原生程式碼嗎?
#是的。在編譯針對桌面或移動裝置等目標的應用時,Dart Native 包含一個帶有即時 (JIT) 編譯器的 Dart VM 和一個提前 (AOT) 編譯器,用於生成原生程式碼。
上。 Flutter 框架使用 Dart 的原生編譯能力來生成快速的原生應用。
問:我可以將 Dart 程式編譯後在終端中執行嗎?
#是的。Dart 程式可以編譯為原生程式碼,在 macOS 終端、Windows 命令提示符或 Linux shell 中執行。
請查閱 dart compile 文件。
問:AOT 編譯的程式碼和 JIT 編譯的程式碼哪個更快?
#這取決於情況。Dart 編譯程式碼的方式會產生具有不同效能特徵的應用。
AOT 編譯的程式碼啟動速度快,執行時效能穩定,早期執行沒有延遲。
JIT 編譯的程式碼啟動速度較慢,但在執行足夠長時間以應用執行時最佳化後會達到峰值效能。
Web 執行
#問:你們支援哪些瀏覽器作為 JavaScript 編譯目標?
#生產環境 Web 編譯器支援以下瀏覽器的最新兩個主要版本
- Google Chrome
- Microsoft Edge
- Firefox
- Apple Safari
上。 開發環境 JavaScript 編譯器僅支援 Chrome 進行除錯。
問:Dart 在 Web 上是單執行緒的嗎?
#有點區別。Dart Web 應用不能使用 isolate。為了實現程式碼併發,Web 應用使用 Web Worker。Web Worker 缺乏 isolate 的易用性和效率,並且具有不同的能力和限制。要了解更多資訊,請參閱 Web 上的併發。
問:任何有效的 Dart 程式碼都能編譯為 JavaScript 嗎?
#任何有效的 Dart 程式碼都應能編譯為 JavaScript。有些庫僅在伺服器或 Flutter 中執行。例如 dart:io 庫。它提供了對作業系統檔案和目錄的訪問,其 API 在瀏覽器中不可用。
問:為什麼 Dart 有兩種方式編譯到 JavaScript?
#這兩種方式都使用 webdev 命令。webdev build 命令生成為生產環境最佳化的壓縮 JavaScript。webdev serve 命令生成為除錯最佳化的模組化 JavaScript。
要了解更多資訊,請查閱 Dart JavaScript 編譯器參考
問:編譯到 JavaScript 時如何處理浮點數?
#JavaScript 只有一種數字表示:IEEE-754 雙精度浮點數。這意味著任何數字(無論是整數還是浮點數)都被表示為雙精度數。JavaScript 具有型別化資料陣列,並且從原生 Dart 型別化列表到 JavaScript 型別化陣列的對映非常簡單。
問:編譯到 JavaScript 時 Dart 如何處理整數?
#JavaScript 將所有數字儲存為雙精度數。這將整數精度限制在 53 位,取值範圍為 -253 到 253。JavaScript 可以在此範圍內儲存整數而不會丟失精度。由於 JavaScript VM 會運算元字的內部表示,因此請保持在小整數 (SMI) 範圍內。在 JavaScript 中,該範圍介於 -231 到 231 之間(包括 0,即 -2,147,483,647 到 2,147,483,648)。
問:編譯到 JavaScript 時如何處理型別化列表?
#JavaScript 提供了與 Dart 型別化列表相容的 32 位型別化陣列。例如,Float32List 會對映為 Float32Array。生產環境的 JavaScript 編譯器不支援 64 位整數:Int64List 或 Uint64List。使用這些列表之一編譯 Dart 程式碼將導致執行時異常。