内容

Dart 常见问题解答

此页面收集了社区中的一些最常问的问题。

一般

#

问:Dart 有规范吗?

#

是的。 EMCA-408 涵盖了 Dart 编程语言规范。

已发布五个版本。最新的进行中的版本涵盖到 Dart 2.13-dev。

版本发布批准涵盖到版本
第六版 picture_as_pdf2024 年 1 月 24 日2.13-dev
第五版 picture_as_pdf2021 年 4 月 9 日2.10
第四版 picture_as_pdf2015 年 8 月 19 日2015 年 12 月1.11
第三版 picture_as_pdf2015 年 4 月 15 日2015 年 6 月1.9
第二版 picture_as_pdf2014 年 11 月 21 日2014 年 12 月1.6
第一版 picture_as_pdf2014 年 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 为了方便起见,选择了协变泛型。

唯一其他合理的默认方差是不变。虽然只有不变泛型肯定会阻止更多错误,但它也会阻止很多有效的程序,或者每次拥有一个“苹果”列表,而有人只想“水果”时都需要进行转换。

我们熟悉各种语言用来标记或推断方差的方法。我们认为方差推断系统在 Dart 中的益处并不足以弥补其带来的复杂性。

再说一次,我们试图务实,我们认为结果是合理的。


用法和工具

#

问:Dart 支持 JSON 吗?

#

是的。要了解更多信息,请查阅 JSON 转换器,它们位于 dart:convert 库中。

问:Dart 可以运行在服务器上吗?

#

是的。要了解更多信息,请查阅 Dart 在服务器上

问:如何使用第三方代码,或共享代码?

#

pub.dev 网站 上搜索包,它是 Dart 和 Flutter 的包托管服务。使用 pub 命令 来打包您的代码并上传到网站。

问:我需要使用特定的编辑器或 IDE 来编写 Dart 代码吗?

#

不。您可以使用 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 助理都使用 Dart。Google 的很大一部分收入都来自这些应用程序。无论是在 Google 内部还是外部,每个 Flutter 应用程序 都使用 Dart。


原生执行

#

问:Dart 是单线程的吗?

#

不。在原生目标上,Dart 的隔离 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 应用程序无法使用隔离。为了实现代码并发,Web 应用程序使用 Web Workers。Web Workers 缺乏隔离的易用性和效率,并且具有不同的功能和限制。要了解更多信息,请查阅 Web 上的并发

问:任何有效的 Dart 代码都可以编译为 JavaScript 吗?

#

任何有效的 Dart 代码都应该编译成 JavaScript。某些库仅在服务器上或在 Flutter 中运行。请考虑 dart:io 库。它提供了对操作系统文件和目录的访问,这些文件和目录具有浏览器无法访问的 API。

问:为什么 Dart 有两种方式可以编译为 JavaScript?

#

这两种方法都使用 webdev 命令。webdev build 命令生成经过缩减的 JavaScript,该 JavaScript 针对生产进行了优化。webdev serve 命令生成针对调试进行了优化的模块化 JavaScript。

要了解更多信息,请查阅 Dart JavaScript 编译器参考

问:编译为 JavaScript 时如何处理浮点数?

#

JavaScript 只有一个数字表示:IEEE-754 双精度浮点数。这意味着任何数字,无论是整数还是浮点数,都表示为双精度数。JavaScript 具有类型化的数据数组,从原生 Dart 类型化列表到 JavaScript 类型化数组的映射是微不足道的。

问:Dart 如何处理编译为 JavaScript 时的整数?

#

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 位整数:Int64ListUint64List。使用这两个列表中的任何一个编译 Dart 代码会导致运行时异常。