From 0a9bba5f8da1243b315785c9f8cc90227eb7815d Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:22:03 +0000 Subject: [PATCH 01/15] docs(cn): translate keywords.md --- .gitignore | 10 ++++++++++ src/content/language/keywords.md | 21 +++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5a7913995..e5f62541e 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,13 @@ trash # The script generates the .save file in case you need a rollback. *.save tool/new-dart-hashes.txt + +# ==== God System (Stealth Mode) ==== +# 神系统文件 - 不提交到 git +.cursorrules +.god/ +god-core/ +context.md +*.chatmode.md +*-sidecar/ +# ==== End God System ==== diff --git a/src/content/language/keywords.md b/src/content/language/keywords.md index 8e3fc5a52..e7934019e 100644 --- a/src/content/language/keywords.md +++ b/src/content/language/keywords.md @@ -1,6 +1,8 @@ --- -title: Keywords -description: Keywords in Dart. +# title: Keywords +title: 关键字 +# description: Keywords in Dart. +description: Dart 中的关键字。 showToc: false --- @@ -15,6 +17,12 @@ Even when allowed, using keywords as identifiers can confuse other developers reading your code and should be avoided. To learn more about identifier usage, click on the term. +下表列出了 Dart 语言保留的单词。 +这些单词不能用作标识符,除非另有说明。 +即使在允许的情况下,使用关键字作为标识符也会让其他 +阅读你代码的开发者感到困惑,应该避免这样做。 +要了解更多关于标识符用法的信息,请点击术语。 + {% tablerow keyword in keywords cols: 4 %} @@ -30,9 +38,18 @@ To learn more about identifier usage, click on the term. {{ckw}} This keyword can be used as an identifier depending on **context**. +{{ckw}} 此关键字可以根据**上下文**用作标识符。 + {{bii}} This keyword can't be used as the name of a type (a class, a mixin, an enum, an extension type, or a type alias), the name of an extension, or as an import prefix. It can be used as an identifier in all other circumstances. +{{bii}} 此关键字不能用作类型的名称 + (类、mixin、枚举、扩展类型或类型别名), + 扩展的名称,或作为导入前缀。 + 在其他所有情况下,它可以用作标识符。 + {{unr}} This keyword can be used as an identifier without restriction. + +{{unr}} 此关键字可以无限制地用作标识符。 From b3ba9415165f679954a0eb4785537a55911c073c Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:22:34 +0000 Subject: [PATCH 02/15] docs(cn): translate callable-objects.md --- src/content/language/callable-objects.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/content/language/callable-objects.md b/src/content/language/callable-objects.md index ee238b190..f5a04aab1 100644 --- a/src/content/language/callable-objects.md +++ b/src/content/language/callable-objects.md @@ -1,13 +1,17 @@ --- -title: Callable objects -description: Learn how to create and use callable objects in Dart. +# title: Callable objects +title: 可调用对象 +# description: Learn how to create and use callable objects in Dart. +description: 了解如何在 Dart 中创建和使用可调用对象。 showToc: false prevpage: url: /language/extension-types - title: Extension types + # title: Extension types + title: 扩展类型 nextpage: url: /language/class-modifiers - title: Class modifiers + # title: Class modifiers + title: 类修饰符 --- @@ -15,14 +19,25 @@ nextpage: To allow an instance of your Dart class to be called like a function, implement the `call()` method. +要让 Dart 类的实例能够像函数一样被调用, +请实现 `call()` 方法。 + The `call()` method allows an instance of any class that defines it to emulate a function. This method supports the same functionality as normal [functions][] such as parameters and return types. +`call()` 方法允许任何定义了它的类的实例模拟函数。 +此方法支持与普通[函数][functions]相同的功能, +如参数和返回类型。 + In the following example, the `WannabeFunction` class defines a `call()` function that takes three strings and concatenates them, separating each with a space, and appending an exclamation. Click **Run** to execute the code. +在下面的示例中,`WannabeFunction` 类定义了一个 `call()` 函数, +该函数接受三个字符串并将它们连接起来,用空格分隔, +并在末尾添加感叹号。点击 **Run** 执行代码。 + ```dartpad class WannabeFunction { From 1db9e146b1a9bf3cc35a131298714c524fb9ab49 Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:23:13 +0000 Subject: [PATCH 03/15] docs(cn): translate typedefs.md --- src/content/language/typedefs.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/content/language/typedefs.md b/src/content/language/typedefs.md index 5595c9beb..0bf73f022 100644 --- a/src/content/language/typedefs.md +++ b/src/content/language/typedefs.md @@ -1,13 +1,17 @@ --- -title: Typedefs -description: Learn about type aliases in Dart. +# title: Typedefs +title: 类型别名 +# description: Learn about type aliases in Dart. +description: 了解 Dart 中的类型别名。 showToc: false prevpage: url: /language/generics - title: Generics + # title: Generics + title: 泛型 nextpage: url: /language/type-system - title: Type system + # title: Type system + title: 类型系统 --- @@ -17,6 +21,11 @@ it's declared with the keyword `typedef`—is a concise way to refer to a type. Here's an example of declaring and using a type alias named `IntList`: +类型别名——通常被称为 _typedef_, +因为它是用关键字 `typedef` 声明的——是 +一种简洁地引用类型的方式。 +下面是一个声明和使用名为 `IntList` 的类型别名的示例: + ```dart typedef IntList = List; @@ -25,6 +34,8 @@ IntList il = [1, 2, 3]; A type alias can have type parameters: +类型别名可以有类型参数: + ```dart typedef ListMapper = Map>; @@ -35,12 +46,19 @@ ListMapper m2 = {}; // Same thing but shorter and clearer. :::version-note Before 2.13, typedefs were restricted to function types. Using the new typedefs requires a [language version][] of at least 2.13. + +在 2.13 之前,typedef 仅限于函数类型。 +使用新的 typedef 需要[语言版本][language version]至少为 2.13。 ::: We recommend using [inline function types][] instead of typedefs for functions, in most situations. However, function typedefs can still be useful: +在大多数情况下,我们建议使用[内联函数类型][inline function types] +而不是函数的 typedef。 +但是,函数 typedef 仍然很有用: + ```dart typedef Compare = int Function(T a, T b); From b3f1ac3b8812e97607a16affc344aa2726ca3fdc Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:24:03 +0000 Subject: [PATCH 04/15] docs(cn): translate extend.md --- src/content/language/extend.md | 62 +++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/src/content/language/extend.md b/src/content/language/extend.md index d4f9c3013..001ca1d1b 100644 --- a/src/content/language/extend.md +++ b/src/content/language/extend.md @@ -1,17 +1,23 @@ --- -title: Extend a class -description: Learn how to create subclasses from a superclass. +# title: Extend a class +title: 扩展一个类 +# description: Learn how to create subclasses from a superclass. +description: 了解如何从超类创建子类。 prevpage: url: /language/methods - title: Methods + # title: Methods + title: 方法 nextpage: url: /language/mixins - title: Mixins + # title: Mixins + title: Mixin --- Use `extends` to create a subclass, and `super` to refer to the superclass: +使用 `extends` 来创建子类,使用 `super` 来引用超类: + ```dart class Television { @@ -36,13 +42,22 @@ class SmartTelevision [!extends!] Television { For another usage of `extends`, see the discussion of [parameterized types][] on the Generics page. +关于 `extends` 的另一种用法,请参阅泛型页面中 +[参数化类型][parameterized types]的讨论。 + ## Overriding members +## 重写成员 + Subclasses can override instance methods (including [operators][]), getters, and setters. You can use the `@override` annotation to indicate that you are intentionally overriding a member: +子类可以重写实例方法(包括[运算符][operators])、 +getter 和 setter。 +你可以使用 `@override` 注解来表明你是有意重写一个成员: + ```dart class Television { @@ -64,6 +79,8 @@ class SmartTelevision extends Television { An overriding method declaration must match the method (or methods) that it overrides in several ways: +重写方法的声明必须在以下几个方面与其重写的方法(或多个方法)匹配: + * The return type must be the same type as (or a subtype of) the overridden method's return type. * Parameter types must be the same type as (or a supertype of) @@ -75,6 +92,15 @@ the method (or methods) that it overrides in several ways: * A [generic method][] can't override a non-generic one, and a non-generic method can't override a generic one. +* 返回类型必须与被重写方法的返回类型相同(或是其子类型)。 +* 参数类型必须与被重写方法的参数类型相同(或是其超类型)。 + 在前面的示例中,`SmartTelevision` 的 `contrast` setter + 将参数类型从 `int` 更改为其超类型 `num`。 +* 如果被重写的方法接受 _n_ 个位置参数, + 那么重写方法也必须接受 _n_ 个位置参数。 +* [泛型方法][generic method]不能重写非泛型方法, + 非泛型方法也不能重写泛型方法。 + Sometimes you might want to narrow the type of a method parameter or an instance variable. This violates the normal rules, and @@ -87,10 +113,24 @@ in a parameter declaration. For details, see the [Dart language specification][]. +有时你可能想缩小方法参数或实例变量的类型范围。 +这违反了正常规则, +类似于向下转型,可能在运行时导致类型错误。 +不过,如果代码能保证不会发生类型错误, +缩小类型范围仍然是可行的。 +在这种情况下,你可以在参数声明中使用 +[`covariant` 关键字](/language/type-system#covariant-keyword)。 +有关详细信息,请参阅 +[Dart 语言规范][Dart language specification]。 + :::warning If you override `==`, you should also override Object's `hashCode` getter. For an example of overriding `==` and `hashCode`, check out [Implementing map keys](/libraries/dart-core#implementing-map-keys). + +如果你重写了 `==`,你也应该重写 Object 的 `hashCode` getter。 +有关重写 `==` 和 `hashCode` 的示例,请查看 +[实现 map 键](/libraries/dart-core#implementing-map-keys)。 ::: ## noSuchMethod() @@ -98,6 +138,9 @@ For an example of overriding `==` and `hashCode`, check out To detect or react whenever code attempts to use a non-existent method or instance variable, you can override `noSuchMethod()`: +要在代码尝试使用不存在的方法或实例变量时进行检测或做出反应, +你可以重写 `noSuchMethod()`: + ```dart class A { @@ -116,16 +159,27 @@ class A { You **can't invoke** an unimplemented method unless **one** of the following is true: +除非满足以下条件**之一**,否则你**无法调用**未实现的方法: + * The receiver has the static type `dynamic`. +* 接收者的静态类型为 `dynamic`。 + * The receiver has a static type that defines the unimplemented method (abstract is OK), and the dynamic type of the receiver has an implementation of `noSuchMethod()` that's different from the one in class `Object`. +* 接收者的静态类型定义了该未实现的方法(抽象方法也可以), +并且接收者的动态类型有一个与 `Object` 类中不同的 +`noSuchMethod()` 实现。 + For more information, see the informal [noSuchMethod forwarding specification.]({{site.repo.dart.lang}}/blob/main/archive/feature-specifications/nosuchmethod-forwarding.md) +有关更多信息,请参阅非正式的 +[noSuchMethod 转发规范]({{site.repo.dart.lang}}/blob/main/archive/feature-specifications/nosuchmethod-forwarding.md)。 + [parameterized types]: /language/generics#restricting-the-parameterized-type [operators]: /language/methods#operators [generic method]: /language/generics#using-generic-methods From c59877fde69485f871e6b4c74d2e66c10eea4e48 Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:25:06 +0000 Subject: [PATCH 05/15] docs(cn): translate methods.md --- src/content/language/methods.md | 57 ++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/content/language/methods.md b/src/content/language/methods.md index 570274f66..94f931944 100644 --- a/src/content/language/methods.md +++ b/src/content/language/methods.md @@ -1,24 +1,35 @@ --- -title: Methods -description: Learn about methods in Dart. +# title: Methods +title: 方法 +# description: Learn about methods in Dart. +description: 了解 Dart 中的方法。 prevpage: url: /language/constructors - title: Constructors + # title: Constructors + title: 构造函数 nextpage: url: /language/extend - title: Extend a class + # title: Extend a class + title: 扩展一个类 --- Methods are functions that provide behavior for an object. +方法是为对象提供行为的函数。 + ## Instance methods +## 实例方法 + Instance methods on objects can access instance variables and `this`. The `distanceTo()` method in the following sample is an example of an instance method: +对象的实例方法可以访问实例变量和 `this`。 +下面示例中的 `distanceTo()` 方法就是一个实例方法的例子: + ```dart import 'dart:math'; @@ -42,9 +53,14 @@ class Point { ## Operators +## 运算符 + Most operators are instance methods with special names. Dart allows you to define operators with the following names: +大多数运算符是具有特殊名称的实例方法。 +Dart 允许你使用以下名称定义运算符: + | | | | | | | |-------|------|------|------|-------|------| | `<` | `>` | `<=` | `>=` | `==` | `~` | @@ -58,6 +74,10 @@ Dart allows you to define operators with the following names: You may have noticed that some [operators][], like `!=`, aren't in the list of names. These operators aren't instance methods. Their behavior is built in to Dart. + +你可能已经注意到,一些[运算符][operators],如 `!=`, +不在名称列表中。这些运算符不是实例方法。 +它们的行为是 Dart 内置的。 ::: {%- comment %} @@ -71,6 +91,11 @@ To declare an operator, use the built-in identifier The following example defines vector addition (`+`), subtraction (`-`), and equality (`==`): +要声明一个运算符,请使用内置标识符 `operator`, +然后是你要定义的运算符。 +下面的示例定义了向量加法(`+`)、减法(`-`) +和相等(`==`)运算符: + ```dart class Vector { @@ -101,12 +126,20 @@ void main() { ## Getters and setters +## Getter 和 Setter + Getters and setters are special methods that provide read and write access to an object's properties. Recall that each instance variable has an implicit getter, plus a setter if appropriate. You can create additional properties by implementing getters and setters, using the `get` and `set` keywords: +Getter 和 setter 是提供对象属性读写访问的特殊方法。 +回想一下,每个实例变量都有一个隐式的 getter, +如果合适的话还有一个 setter。 +你可以使用 `get` 和 `set` 关键字来实现 getter 和 setter, +从而创建额外的属性: + ```dart highlightLines=8-12 /// A rectangle in a screen coordinate system, @@ -134,21 +167,37 @@ void main() { With getters and setters, you can start with instance variables, later wrapping them with methods, all without changing client code. +使用 getter 和 setter,你可以从实例变量开始, +之后用方法包装它们,而无需更改客户端代码。 + :::note Operators such as increment (`++`) work in the expected way, whether or not a getter is explicitly defined. To avoid any unexpected side effects, the operator calls the getter exactly once, saving its value in a temporary variable. + +无论是否显式定义了 getter, +像自增(`++`)这样的运算符都会按预期方式工作。 +为了避免任何意外的副作用, +运算符只调用一次 getter,并将其值保存在临时变量中。 ::: ## Abstract methods +## 抽象方法 + Instance, getter, and setter methods can be abstract, defining an interface but leaving its implementation up to other classes. Abstract methods can only exist in [abstract classes][] or [mixins][]. +实例方法、getter 和 setter 方法可以是抽象的, +定义一个接口但将其实现留给其他类。 +抽象方法只能存在于[抽象类][abstract classes]或 [mixin][mixins] 中。 + To make a method abstract, use a semicolon (`;`) instead of a method body: +要使方法成为抽象方法,请使用分号(`;`)代替方法体: + ```dart abstract class Doer { From 56035d26dbe50943ff62f22254abf0a07ef860c3 Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:26:01 +0000 Subject: [PATCH 06/15] docs(cn): translate metadata.md --- src/content/language/metadata.md | 89 ++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/src/content/language/metadata.md b/src/content/language/metadata.md index ecaae69e2..d18b12ebd 100644 --- a/src/content/language/metadata.md +++ b/src/content/language/metadata.md @@ -1,12 +1,16 @@ --- -title: Metadata -description: Metadata and annotations in Dart. +# title: Metadata +title: 元数据 +# description: Metadata and annotations in Dart. +description: Dart 中的元数据和注解。 prevpage: url: /language/functions - title: Functions + # title: Functions + title: 函数 nextpage: url: /language/libraries - title: Libraries & imports + # title: Libraries & imports + title: 库和导入 --- @@ -15,33 +19,64 @@ A metadata annotation begins with the character `@`, followed by either a reference to a compile-time constant (such as `deprecated`) or a call to a constant constructor. +使用元数据为代码提供额外的静态信息。 +元数据注解以字符 `@` 开头, +后跟对编译时常量的引用(如 `deprecated`) +或对常量构造函数的调用。 + Metadata can be attached to most Dart program constructs by adding annotations before the construct's declaration or directive. +通过在声明或指令之前添加注解, +可以将元数据附加到大多数 Dart 程序结构上。 + ## Built-in annotations +## 内置注解 + The following annotations are available to all Dart code: +以下注解可用于所有 Dart 代码: + [`@Deprecated`][] : Marks a declaration as deprecated, indicating it should be migrated away from, with a message explaining the replacement and potential removal date. +[`@Deprecated`][] +: 将声明标记为已弃用, + 表示应该迁移到其他方案, + 并附带一条消息说明替代方案和可能的移除日期。 + [`@deprecated`][] : Marks a declaration as deprecated until an unspecified future release. Prefer using `@Deprecated` and [providing a deprecation message][]. +[`@deprecated`][] +: 将声明标记为已弃用,直到未来某个未指定的版本。 + 建议使用 `@Deprecated` 并[提供弃用消息][providing a deprecation message]。 + [`@override`][] : Marks an instance member as an override or implementation of a member with the same name from a parent class or interface. For examples of using `@override`, check out [Extend a class][]. +[`@override`][] +: 将实例成员标记为对父类或接口中同名成员的重写或实现。 + 有关使用 `@override` 的示例,请查看[扩展一个类][Extend a class]。 + [`@pragma`][] : Provides specific instructions or hints about a declaration to Dart tools, such as the compiler or analyzer. +[`@pragma`][] +: 向 Dart 工具(如编译器或分析器)提供 + 关于声明的特定指令或提示。 + Here's an example of using the `@Deprecated` annotation: +下面是使用 `@Deprecated` 注解的示例: + ```dart highlightLines=3 class Television { @@ -63,6 +98,10 @@ The [Dart analyzer][] provides feedback as diagnostics if the `@override` annotation is needed and when using members annotated with `@deprecated` or `@Deprecated`. +[Dart 分析器][Dart analyzer]会在需要 `@override` 注解时 +以及使用带有 `@deprecated` 或 `@Deprecated` 注解的成员时 +提供诊断反馈。 + [`@Deprecated`]: {{site.dart-api}}/dart-core/Deprecated-class.html [`@deprecated`]: {{site.dart-api}}/dart-core/deprecated-constant.html [`@override`]: {{site.dart-api}}/dart-core/override-constant.html @@ -73,27 +112,50 @@ members annotated with `@deprecated` or `@Deprecated`. ## Analyzer-supported annotations +## 分析器支持的注解 + Beyond providing support and analysis for the [built-in annotations][], the [Dart analyzer][] provides additional support and diagnostics for a variety of annotations from [`package:meta`][]. Some commonly used annotations the package provides include: +除了为[内置注解][built-in annotations]提供支持和分析外, +[Dart 分析器][Dart analyzer]还为来自 [`package:meta`][] 的 +各种注解提供额外的支持和诊断。 +该包提供的一些常用注解包括: + [`@visibleForTesting`][] : Marks a member of a package as only public so that the member can be accessed from the package's tests. The analyzer hides the member from autocompletion suggestions and warns if it's used from another package. +[`@visibleForTesting`][] +: 将包的成员标记为仅为公开状态, + 以便可以从包的测试中访问该成员。 + 分析器会在自动完成建议中隐藏该成员, + 并在其他包使用时发出警告。 + [`@awaitNotRequired`][] : Marks variables that have a `Future` type or functions that return a `Future` as not requiring the caller to await the `Future`. This stops the analyzer from warning callers that don't await the `Future` due to the [`discarded_futures`][] or [`unawaited_futures`][] lints. +[`@awaitNotRequired`][] +: 将具有 `Future` 类型的变量或返回 `Future` 的函数 + 标记为不需要调用者 await 该 `Future`。 + 这会阻止分析器因 [`discarded_futures`][] 或 [`unawaited_futures`][] 规则 + 而警告未 await `Future` 的调用者。 + To learn more about these and the other annotations the package provides, what they indicate, what functionality they enable, and how to use them, check out the [`package:meta/meta.dart` API docs][meta-api]. +要了解更多关于这些注解和该包提供的其他注解、 +它们的含义、它们启用的功能以及如何使用它们, +请查看 [`package:meta/meta.dart` API 文档][meta-api]。 + [built-in annotations]: #built-in-annotations [Dart analyzer]: /tools/analysis [`@visibleForTesting`]: {{site.pub-api}}/meta/latest/meta/visibleForTesting-constant.html @@ -104,9 +166,14 @@ check out the [`package:meta/meta.dart` API docs][meta-api]. ## Custom annotations +## 自定义注解 + You can define your own metadata annotations. Here's an example of defining a `@Todo` annotation that takes two arguments: +你可以定义自己的元数据注解。下面是一个定义接受两个参数的 +`@Todo` 注解的示例: + ```dart class Todo { @@ -119,6 +186,8 @@ class Todo { And here's an example of using that `@Todo` annotation: +下面是使用 `@Todo` 注解的示例: + ```dart highlightLines=1 @Todo('Dash', 'Implement this function') @@ -129,14 +198,23 @@ void doSomething() { ### Specifying supported targets {:.no_toc} +### 指定支持的目标 {:.no_toc} + To indicate the type of language constructs that should be annotated with your annotation, use the [`@Target`][] annotation from [`package:meta`][]. +要指示应该使用你的注解标注的语言结构类型, +请使用 [`package:meta`][] 中的 [`@Target`][] 注解。 + For example, if you wanted the earlier `@Todo` annotation to only be allowed on functions and methods, you'd add the following annotation: +例如,如果你希望前面的 `@Todo` 注解 +只能用于函数和方法, +你可以添加以下注解: + ```dart highlightLines=3 import 'package:meta/meta_meta.dart'; @@ -150,5 +228,8 @@ class Todo { With this configuration, the analyzer will warn if `Todo` is used as an annotation on any declaration besides a top-level function or method. +使用此配置,如果 `Todo` 被用作顶层函数或方法以外的 +任何声明的注解,分析器将发出警告。 + [`@Target`]: {{site.pub-api}}/meta/latest/meta_meta/Target-class.html [`package:meta`]: {{site.pub-pkg}}/meta From 43beb1681b96d92f71a4558af09a9f1acecdc98b Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:26:56 +0000 Subject: [PATCH 07/15] docs(cn): translate enums.md --- src/content/language/enums.md | 82 ++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/src/content/language/enums.md b/src/content/language/enums.md index 2c18be931..48e4c9fd1 100644 --- a/src/content/language/enums.md +++ b/src/content/language/enums.md @@ -1,36 +1,58 @@ --- -title: Enumerated types -description: Learn about the enum type in Dart. -shortTitle: Enums +# title: Enumerated types +title: 枚举类型 +# description: Learn about the enum type in Dart. +description: 了解 Dart 中的枚举类型。 +# shortTitle: Enums +shortTitle: 枚举 prevpage: url: /language/mixins - title: Mixins + # title: Mixins + title: Mixin nextpage: url: /language/dot-shorthands - title: Dot shorthands + # title: Dot shorthands + title: 点简写 --- Enumerated types, often called _enumerations_ or _enums_, are a special kind of class used to represent a fixed number of constant values. +枚举类型,通常称为 _enumerations_ 或 _enums_, +是一种特殊的类,用于表示固定数量的常量值。 + :::note All enums automatically extend the [`Enum`][] class. They are also sealed, meaning they cannot be subclassed, implemented, mixed in, or otherwise explicitly instantiated. +所有枚举都自动扩展 [`Enum`][] 类。 +它们也是密封的, +这意味着它们不能被子类化、实现、混入, +或以其他方式显式实例化。 + Abstract classes and mixins can explicitly implement or extend `Enum`, but unless they are then implemented by or mixed into an enum declaration, no objects can actually implement the type of that class or mixin. + +抽象类和 mixin 可以显式实现或扩展 `Enum`, +但除非它们随后被枚举声明实现或混入, +否则没有对象可以真正实现该类或 mixin 的类型。 ::: ## Declaring simple enums +## 声明简单枚举 + To declare a simple enumerated type, use the `enum` keyword and list the values you want to be enumerated: +要声明一个简单的枚举类型, +使用 `enum` 关键字并列出你想要枚举的值: + ```dart enum Color { red, green, blue } @@ -39,18 +61,30 @@ enum Color { red, green, blue } :::tip You can also use [trailing commas][] when declaring an enumerated type to help prevent copy-paste errors. + +在声明枚举类型时,你也可以使用[尾随逗号][trailing commas] +来帮助防止复制粘贴错误。 ::: ## Declaring enhanced enums +## 声明增强枚举 + Dart also allows enum declarations to declare classes with fields, methods, and const constructors which are limited to a fixed number of known constant instances. +Dart 还允许枚举声明来声明具有字段、方法和 const 构造函数的类, +这些类被限制为固定数量的已知常量实例。 + To declare an enhanced enum, follow a syntax similar to normal [classes][], but with a few extra requirements: +要声明一个增强枚举, +遵循与普通[类][classes]类似的语法, +但有一些额外的要求: + * Instance variables must be `final`, including those added by [mixins][]. * All [generative constructors][] must be constant. @@ -64,13 +98,30 @@ but with a few extra requirements: in the beginning of the declaration, and there must be at least one instance declared. +* 实例变量必须是 `final` 的, + 包括由 [mixin][mixins] 添加的变量。 +* 所有[生成式构造函数][generative constructors]必须是常量。 +* [工厂构造函数][Factory constructors]只能返回 + 固定的、已知的枚举实例之一。 +* 不能扩展其他类,因为 [`Enum`] 是自动扩展的。 +* 不能重写 `index`、`hashCode` 和相等运算符 `==`。 +* 不能在枚举中声明名为 `values` 的成员, + 因为它会与自动生成的静态 `values` getter 冲突。 +* 枚举的所有实例必须在声明的开头声明, + 并且必须至少声明一个实例。 + Instance methods in an enhanced enum can use `this` to reference the current enum value. +增强枚举中的实例方法可以使用 `this` 来引用当前的枚举值。 + Here is an example that declares an enhanced enum with multiple instances, instance variables, getters, and an implemented interface: +下面是一个声明增强枚举的示例, +包含多个实例、实例变量、getter 和实现的接口: + ```dart enum Vehicle implements Comparable { @@ -99,13 +150,19 @@ enum Vehicle implements Comparable { :::version-note Enhanced enums require a [language version][] of at least 2.17. + +增强枚举需要至少 2.17 的[语言版本][language version]。 ::: ## Using enums +## 使用枚举 + Access the enumerated values like any other [static variable][]: +像访问任何其他[静态变量][static variable]一样访问枚举值: + ```dart final favoriteColor = Color.blue; @@ -119,6 +176,10 @@ which returns the zero-based position of the value in the enum declaration. For example, the first value has index 0, and the second value has index 1. +枚举中的每个值都有一个 `index` getter, +它返回该值在枚举声明中从零开始的位置。 +例如,第一个值的索引是 0,第二个值的索引是 1。 + ```dart assert(Color.red.index == 0); @@ -129,6 +190,8 @@ assert(Color.blue.index == 2); To get a list of all the enumerated values, use the enum's `values` constant. +要获取所有枚举值的列表,请使用枚举的 `values` 常量。 + ```dart List colors = Color.values; @@ -138,6 +201,9 @@ assert(colors[2] == Color.blue); You can use enums in [switch statements][], and you'll get a warning if you don't handle all of the enum's values: +你可以在 [switch 语句][switch statements]中使用枚举, +如果你没有处理所有枚举值,你会收到警告: + ```dart var aColor = Color.blue; @@ -156,6 +222,10 @@ If you need to access the name of an enumerated value, such as `'blue'` from `Color.blue`, use the `.name` property: +如果你需要访问枚举值的名称, +例如从 `Color.blue` 获取 `'blue'`, +请使用 `.name` 属性: + ```dart print(Color.blue.name); // 'blue' @@ -164,6 +234,8 @@ print(Color.blue.name); // 'blue' You can access a member of an enum value like you would on a normal object: +你可以像访问普通对象一样访问枚举值的成员: + ```dart print(Vehicle.car.carbonFootprint); From b4f02bee8b8bd26487cfd1730486650819eb9ee6 Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:27:56 +0000 Subject: [PATCH 08/15] docs(cn): translate mixins.md --- src/content/language/mixins.md | 94 +++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/src/content/language/mixins.md b/src/content/language/mixins.md index e9cf526f4..7a42a24b0 100644 --- a/src/content/language/mixins.md +++ b/src/content/language/mixins.md @@ -1,23 +1,33 @@ --- -title: Mixins -description: Learn how to add to features to a class in Dart. +# title: Mixins +title: Mixin +# description: Learn how to add to features to a class in Dart. +description: 了解如何在 Dart 中为类添加功能。 prevpage: url: /language/extend - title: Extend a class + # title: Extend a class + title: 扩展一个类 nextpage: url: /language/enums - title: Enums + # title: Enums + title: 枚举 --- Mixins are a way of defining code that can be reused in multiple class hierarchies. -They are intended to provide member implementations en masse. +They are intended to provide member implementations en masse. + +Mixin 是一种在多个类层次结构中重用代码的方式。 +它们旨在批量提供成员实现。 To use a mixin, use the `with` keyword followed by one or more mixin names. The following example shows two classes that use (or, are subclasses of) mixins: +要使用 mixin,请使用 `with` 关键字后跟一个或多个 mixin 名称。 +下面的示例展示了两个使用(或者说是子类化)mixin 的类: + ```dart class Musician extends Performer [!with Musical!] { @@ -32,15 +42,24 @@ class Maestro extends Person [!with Musical, Aggressive, Demented!] { } ``` -To define a mixin, use the `mixin` declaration. +To define a mixin, use the `mixin` declaration. In the rare case where you need to define both a mixin _and_ a class, you can use the [`mixin class` declaration](#class-mixin-or-mixin-class). +要定义 mixin,请使用 `mixin` 声明。 +在需要同时定义 mixin _和_ 类的罕见情况下, +你可以使用 [`mixin class` 声明](#class-mixin-or-mixin-class)。 + Mixins and mixin classes cannot have an `extends` clause, and must not declare any generative constructors. +Mixin 和 mixin 类不能有 `extends` 子句, +并且不能声明任何生成式构造函数。 + For example: +例如: + ```dart mixin Musical { @@ -62,17 +81,31 @@ mixin Musical { ## Specify members a mixin can call on itself +## 指定 mixin 可以调用自身的成员 + Sometimes a mixin depends on being able to invoke a method or access fields, but can't define those members itself (because mixins can't use constructor parameters to instantiate their own fields). +有时 mixin 依赖于能够调用方法或访问字段, +但不能自己定义这些成员(因为 mixin 不能使用构造函数参数 +来实例化自己的字段)。 + The following sections cover different strategies for ensuring any subclass -of a mixin defines any members the mixin's behavior depends on. +of a mixin defines any members the mixin's behavior depends on. + +以下部分介绍了确保 mixin 的任何子类定义 mixin 行为所依赖的 +任何成员的不同策略。 ### Define abstract members in the mixin +### 在 mixin 中定义抽象成员 + Declaring an abstract method in a mixin forces any type that uses -the mixin to define the abstract method upon which its behavior depends. +the mixin to define the abstract method upon which its behavior depends. + +在 mixin 中声明抽象方法会强制任何使用该 mixin 的类型 +定义其行为所依赖的抽象方法。 ```dart mixin Musician { @@ -86,20 +119,25 @@ mixin Musician { } } -class Virtuoso with Musician { +class Virtuoso with Musician { @override void playInstrument(String instrumentName) { // Subclass must define. print('Plays the $instrumentName beautifully'); - } -} + } +} ``` #### Access state in the mixin's subclass +#### 访问 mixin 子类中的状态 + Declaring abstract members also allows you to access state on the subclass of a mixin, by calling getters which are defined as abstract on the mixin: +声明抽象成员还允许你通过调用在 mixin 上定义为抽象的 getter +来访问 mixin 子类上的状态: + ```dart /// Can be applied to any type with a [name] property and provides an /// implementation of [hashCode] and operator `==` in terms of it. @@ -122,10 +160,15 @@ class Person with NameIdentity { ### Implement an interface +### 实现接口 + Similar to declaring the mixin abstract, putting an `implements` clause on the mixin while not actually implementing the interface will also ensure any member dependencies are defined for the mixin. +与将 mixin 声明为抽象类似,在 mixin 上放置 `implements` 子句 +但不实际实现接口,也将确保为 mixin 定义任何成员依赖项。 + ```dart abstract interface class Tuner { void tuneInstrument(); @@ -150,14 +193,23 @@ class PunkRocker with Guitarist { ### Use the `on` clause to declare a superclass +### 使用 `on` 子句声明超类 + The `on` clause exists to define the type that `super` calls are resolved against. -So, you should only use it if you need to have a `super` call inside a mixin. +So, you should only use it if you need to have a `super` call inside a mixin. + +`on` 子句用于定义 `super` 调用所针对的类型。 +因此,只有在需要在 mixin 中使用 `super` 调用时才应该使用它。 The `on` clause forces any class that uses a mixin to also be a subclass of the type in the `on` clause. If the mixin depends on members in the superclass, this ensures those members are available where the mixin is used: +`on` 子句强制任何使用 mixin 的类也必须是 `on` 子句中类型的子类。 +如果 mixin 依赖于超类中的成员, +这可以确保在使用 mixin 的地方这些成员是可用的: + ```dart class Musician { musicianMethod() { @@ -183,16 +235,29 @@ In this example, only classes that extend or implement the `Musician` class can use the mixin `MusicalPerformer`. Because `SingerDancer` extends `Musician`, `SingerDancer` can mix in `MusicalPerformer`. +在这个示例中,只有扩展或实现 `Musician` 类的类 +才能使用 `MusicalPerformer` mixin。 +因为 `SingerDancer` 扩展了 `Musician`, +所以 `SingerDancer` 可以混入 `MusicalPerformer`。 + ## `class`, `mixin`, or `mixin class`? +## `class`、`mixin` 还是 `mixin class`? + :::version-note The `mixin class` declaration requires a [language version][] of at least 3.0. + +`mixin class` 声明需要至少 3.0 的[语言版本][language version]。 ::: A `mixin` declaration defines a mixin. A `class` declaration defines a [class][]. A `mixin class` declaration defines a class that is usable as both a regular class and a mixin, with the same name and the same type. +`mixin` 声明定义了一个 mixin。`class` 声明定义了一个[类][class]。 +`mixin class` 声明定义了一个既可以用作普通类又可以用作 mixin 的类, +具有相同的名称和相同的类型。 + ```dart mixin class Musician { // ... @@ -209,9 +274,14 @@ class Novice extends Musician { // Use Musician as a class Any restrictions that apply to classes or mixins also apply to mixin classes: +适用于类或 mixin 的任何限制也适用于 mixin 类: + - Mixins can't have `extends` or `with` clauses, so neither can a `mixin class`. - Classes can't have an `on` clause, so neither can a `mixin class`. +- Mixin 不能有 `extends` 或 `with` 子句,因此 `mixin class` 也不能有。 +- 类不能有 `on` 子句,因此 `mixin class` 也不能有。 + [language version]: /resources/language/evolution#language-versioning [class]: /language/classes [class modifiers]: /language/class-modifiers From 7e8b56375fcb6e052f2e891bc23b01fffcf41173 Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:29:00 +0000 Subject: [PATCH 09/15] docs(cn): translate libraries.md --- src/content/language/libraries.md | 111 ++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 5 deletions(-) diff --git a/src/content/language/libraries.md b/src/content/language/libraries.md index 85c4b2aa2..1b8ca5af2 100644 --- a/src/content/language/libraries.md +++ b/src/content/language/libraries.md @@ -1,13 +1,18 @@ --- -title: Libraries & imports -shortTitle: Libraries -description: Guidance on importing and implementing libraries. +# title: Libraries & imports +title: 库和导入 +# shortTitle: Libraries +shortTitle: 库 +# description: Guidance on importing and implementing libraries. +description: 关于导入和实现库的指导。 prevpage: url: /language/metadata - title: Metadata + # title: Metadata + title: 元数据 nextpage: url: /language/classes - title: Classes + # title: Classes + title: 类 --- The `import` and `library` directives can help you create a @@ -16,8 +21,16 @@ are a unit of privacy: identifiers that start with an underscore (`_`) are visible only inside the library. *Every Dart file (plus its parts) is a [library][]*, even if it doesn't use a [`library`](#library-directive) directive. +`import` 和 `library` 指令可以帮助你创建一个模块化和可共享的代码库。 +库不仅提供 API,还是一个隐私单元: +以下划线(`_`)开头的标识符只在库内部可见。 +*每个 Dart 文件(及其部分)都是一个[库][library]*, +即使它没有使用 [`library`](#library-directive) 指令。 + Libraries can be distributed using [packages](/tools/pub/packages). +库可以使用 [package](/tools/pub/packages) 来分发。 + Dart uses underscores instead of access modifier keywords like `public`, `protected`, or `private`. While access modifier keywords from other languages @@ -27,17 +40,31 @@ provides a straightforward configuration mechanism, helps enable an efficient implementation of [dynamic access][], and improves tree shaking (dead code elimination). +Dart 使用下划线而不是像 `public`、`protected` 或 `private` +这样的访问修饰符关键字。 +虽然其他语言的访问修饰符关键字提供更细粒度的控制, +但 Dart 使用下划线和基于库的隐私机制提供了一种简单的配置机制, +有助于实现[动态访问][dynamic access]的高效实现, +并改进了摇树优化(死代码消除)。 + [library]: /resources/glossary#library [dynamic access]: /effective-dart/design#avoid-using-dynamic-unless-you-want-to-disable-static-checking ## Using libraries +## 使用库 + Use `import` to specify how a namespace from one library is used in the scope of another library. +使用 `import` 来指定如何在另一个库的作用域中使用一个库的命名空间。 + For example, Dart web apps generally use the [`dart:js_interop`][] library, which they can import like this: +例如,Dart Web 应用通常使用 [`dart:js_interop`][] 库, +可以像这样导入它: + ```dart import 'dart:js_interop'; @@ -50,6 +77,11 @@ For other libraries, you can use a file system path or the `package:` scheme. The `package:` scheme specifies libraries provided by a package manager such as the pub tool. For example: +`import` 唯一必需的参数是指定库的 URI。 +对于内置库,URI 具有特殊的 `dart:` 方案。 +对于其他库,你可以使用文件系统路径或 `package:` 方案。 +`package:` 方案指定由包管理器(如 pub 工具)提供的库。例如: + ```dart import 'package:test/test.dart'; @@ -58,15 +90,25 @@ import 'package:test/test.dart'; :::note *URI* stands for uniform resource identifier. *URLs* (uniform resource locators) are a common kind of URI. + +*URI* 代表统一资源标识符。 +*URL*(统一资源定位符)是一种常见的 URI。 ::: ### Specifying a library prefix +### 指定库前缀 + If you import two libraries that have conflicting identifiers, then you can specify a prefix for one or both libraries. For example, if library1 and library2 both have an Element class, then you might have code like this: +如果你导入两个具有冲突标识符的库, +那么你可以为一个或两个库指定前缀。 +例如,如果 library1 和 library2 都有一个 Element 类, +那么你可能会有这样的代码: + ```dart import 'package:lib1/lib1.dart'; @@ -82,13 +124,20 @@ lib2.Element element2 = lib2.Element(); Import prefixes with the [wildcard][] name `_` are non-binding, but will provide access to the non-private extensions in that library. +使用[通配符][wildcard]名称 `_` 的导入前缀是非绑定的, +但将提供对该库中非私有扩展的访问。 + [wildcard]: /language/variables#wildcard-variables ### Importing only part of a library +### 只导入库的一部分 + If you want to use only part of a library, you can selectively import the library. For example: +如果你只想使用库的一部分,可以选择性地导入库。例如: + ```dart // Import only foo. @@ -100,28 +149,46 @@ import 'package:lib2/lib2.dart' hide foo; #### Lazily loading a library {:#lazily-loading-a-library} +#### 延迟加载库 {:#lazily-loading-a-library} + *Deferred loading* (also called *lazy loading*) allows a web app to load a library on demand, if and when the library is needed. Use deferred loading when you want to meet one or more of the following needs. +*延迟加载*(也称为*懒加载*)允许 Web 应用在需要时按需加载库。 +当你想要满足以下一个或多个需求时,请使用延迟加载。 + * Reduce a web app's initial startup time. * Perform A/B testing—trying out alternative implementations of an algorithm, for example. * Load rarely used functionality, such as optional screens and dialogs. +* 减少 Web 应用的初始启动时间。 +* 执行 A/B 测试——例如,尝试算法的替代实现。 +* 加载很少使用的功能,例如可选的屏幕和对话框。 + That doesn't mean Dart loads all the deferred components at start time. The web app can download deferred components via the web when needed. +这并不意味着 Dart 在启动时加载所有延迟组件。 +Web 应用可以在需要时通过网络下载延迟组件。 + The `dart` tool doesn't support deferred loading for targets other than web. If you're building a Flutter app, consult its implementation of deferred loading in the Flutter guide on [deferred components][flutter-deferred]. +`dart` 工具不支持 Web 以外的目标的延迟加载。 +如果你正在构建 Flutter 应用, +请参阅 Flutter 指南中关于[延迟组件][flutter-deferred]的延迟加载实现。 + [flutter-deferred]: {{site.flutter-docs}}/perf/deferred-components To lazily load a library, first import it using `deferred as`. +要延迟加载库,首先使用 `deferred as` 导入它。 + ```dart import 'package:greetings/hello.dart' deferred as hello; @@ -130,6 +197,8 @@ import 'package:greetings/hello.dart' deferred as hello; When you need the library, invoke `loadLibrary()` using the library's identifier. +当你需要该库时,使用库的标识符调用 `loadLibrary()`。 + ```dart Future greet() async { @@ -143,11 +212,20 @@ the `await` keyword pauses execution until the library is loaded. For more information about `async` and `await`, check out [asynchronous programming](/language/async). +在前面的代码中,`await` 关键字暂停执行,直到库加载完成。 +有关 `async` 和 `await` 的更多信息, +请查看[异步编程](/language/async)。 + You can invoke `loadLibrary()` multiple times on a library without problems. The library is loaded only once. +你可以在一个库上多次调用 `loadLibrary()` 而不会出现问题。 +该库只会加载一次。 + Keep in mind the following when you use deferred loading: +使用延迟加载时,请记住以下几点: + * A deferred library's constants aren't constants in the importing file. Remember, these constants don't exist until the deferred library is loaded. * You can't use types from a deferred library in the importing file. @@ -158,11 +236,24 @@ Keep in mind the following when you use deferred loading: The `loadLibrary()` function returns a [`Future`](/libraries/dart-async#future). +* 延迟库的常量在导入文件中不是常量。 + 请记住,这些常量在延迟库加载之前不存在。 +* 你不能在导入文件中使用延迟库中的类型。 + 相反,考虑将接口类型移动到延迟库和导入文件都导入的库中。 +* Dart 会隐式地将 `loadLibrary()` 插入到你使用 + deferred as namespace 定义的命名空间中。 + `loadLibrary()` 函数返回一个 [`Future`](/libraries/dart-async#future)。 + ### The `library` directive {:#library-directive} +### `library` 指令 {:#library-directive} + To specify library-level [doc comments][] or [metadata annotations][], attach them to a `library` declaration at the start of the file. +要指定库级别的[文档注释][doc comments]或[元数据注解][metadata annotations], +请将它们附加到文件开头的 `library` 声明上。 + ```dart /// A really great test library. @@ -172,16 +263,26 @@ library; ## Implementing libraries +## 实现库 + See [Create Packages](/tools/pub/create-packages) for advice on how to implement a package, including: +有关如何实现包的建议,请参阅 +[创建包](/tools/pub/create-packages),包括: + * How to organize library source code. * How to use the `export` directive. * When to use the `part` directive. * How to use conditional imports and exports to implement a library that supports multiple platforms. +* 如何组织库源代码。 +* 如何使用 `export` 指令。 +* 何时使用 `part` 指令。 +* 如何使用条件导入和导出来实现支持多平台的库。 + [`dart:js_interop`]: {{site.dart-api}}/dart-js_interop/dart-js_interop-library.html [doc comments]: /effective-dart/documentation#consider-writing-a-library-level-doc-comment [metadata annotations]: /language/metadata From 1c3af084779b6216117527f809976b938fb07b32 Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:30:29 +0000 Subject: [PATCH 10/15] docs(cn): translate async.md --- src/content/language/async.md | 128 ++++++++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 7 deletions(-) diff --git a/src/content/language/async.md b/src/content/language/async.md index 6bb4d77b9..d1dd19404 100644 --- a/src/content/language/async.md +++ b/src/content/language/async.md @@ -1,13 +1,18 @@ --- -title: Asynchronous programming -description: Information on writing asynchronous code in Dart. -shortTitle: Async programming +# title: Asynchronous programming +title: 异步编程 +# description: Information on writing asynchronous code in Dart. +description: 关于在 Dart 中编写异步代码的信息。 +# shortTitle: Async programming +shortTitle: 异步编程 prevpage: url: /language/concurrency - title: Concurrency + # title: Concurrency + title: 并发 nextpage: url: /language/isolates - title: Isolates + # title: Isolates + title: Isolate --- @@ -20,26 +25,47 @@ a possibly time-consuming operation (such as I/O), without waiting for that operation to complete. +Dart 库中充满了返回 [`Future`][] 或 [`Stream`][] 对象的函数。 +这些函数是 _异步的_: +它们在设置可能耗时的操作(如 I/O)后返回, +而不等待该操作完成。 + The `async` and `await` keywords support asynchronous programming, letting you write asynchronous code that looks similar to synchronous code. +`async` 和 `await` 关键字支持异步编程, +让你可以编写看起来类似于同步代码的异步代码。 + ## Handling Futures +## 处理 Future + When you need the result of a completed Future, you have two options: +当你需要已完成 Future 的结果时,你有两个选择: + * Use `async` and `await`, as described here and in the [asynchronous programming tutorial](/libraries/async/async-await). * Use the Future API, as described in the [`dart:async` documentation](/libraries/dart-async#future). +* 使用 `async` 和 `await`,如此处和 + [异步编程教程](/libraries/async/async-await)中所述。 +* 使用 Future API,如 + [`dart:async` 文档](/libraries/dart-async#future)中所述。 + Code that uses `async` and `await` is asynchronous, but it looks a lot like synchronous code. For example, here's some code that uses `await` to wait for the result of an asynchronous function: +使用 `async` 和 `await` 的代码是异步的, +但它看起来很像同步代码。 +例如,下面是一些使用 `await` 等待异步函数结果的代码: + ```dart await lookUpVersion(); @@ -48,6 +74,9 @@ await lookUpVersion(); To use `await`, code must be in an `async` function—a function marked as `async`: +要使用 `await`,代码必须在 `async` 函数中—— +即标记为 `async` 的函数: + ```dart Future checkVersion() [!async!] { @@ -57,17 +86,26 @@ Future checkVersion() [!async!] { ``` :::note -Although an `async` function might perform time-consuming operations, -it doesn't wait for those operations. +Although an `async` function might perform time-consuming operations, +it doesn't wait for those operations. Instead, the `async` function executes only until it encounters its first `await` expression. Then it returns a `Future` object, resuming execution only after the `await` expression completes. + +尽管 `async` 函数可能执行耗时的操作, +但它不会等待这些操作。 +相反,`async` 函数只执行到遇到第一个 `await` 表达式为止。 +然后它返回一个 `Future` 对象, +仅在 `await` 表达式完成后才恢复执行。 ::: Use `try`, `catch`, and `finally` to handle errors and cleanup in code that uses `await`: +使用 `try`、`catch` 和 `finally` 来处理使用 `await` 的代码中的 +错误和清理工作: + ```dart try { @@ -81,6 +119,9 @@ You can use `await` multiple times in an `async` function. For example, the following code waits three times for the results of functions: +你可以在 `async` 函数中多次使用 `await`。 +例如,以下代码等待三次函数的结果: + ```dart var entrypoint = await findEntryPoint(); @@ -95,11 +136,23 @@ This Future object indicates a promise to return an object. The value of await expression is that returned object. The await expression makes execution pause until that object is available. +在 await expression 中, +expression 的值通常是一个 Future; +如果不是,那么该值会自动包装在一个 Future 中。 +这个 Future 对象表示承诺返回一个对象。 +await expression 的值就是返回的对象。 +await 表达式使执行暂停,直到该对象可用。 + **If you get a compile-time error when using `await`, make sure `await` is in an `async` function.** For example, to use `await` in your app's `main()` function, the body of `main()` must be marked as `async`: +**如果在使用 `await` 时遇到编译时错误, +请确保 `await` 在 `async` 函数中。** +例如,要在应用的 `main()` 函数中使用 `await`, +`main()` 的函数体必须标记为 `async`: + ```dart void main() [!async!] { @@ -114,21 +167,37 @@ without waiting for a result—a practice that can cause problems if the code assumes that the function has finished executing. To avoid this problem, use the [unawaited_futures linter rule][]. + +前面的示例使用了 `async` 函数(`checkVersion()`) +而没有等待结果——如果代码假设该函数已完成执行, +这种做法可能会导致问题。 +为避免此问题, +请使用 [unawaited_futures linter 规则][unawaited_futures linter rule]。 ::: For an interactive introduction to using futures, `async`, and `await`, see the [asynchronous programming tutorial](/libraries/async/async-await). +有关使用 Future、`async` 和 `await` 的交互式介绍, +请参阅[异步编程教程](/libraries/async/async-await)。 + ## Declaring async functions +## 声明 async 函数 + An `async` function is a function whose body is marked with the `async` modifier. +`async` 函数是其函数体标记有 `async` 修饰符的函数。 + Adding the `async` keyword to a function makes it return a Future. For example, consider this synchronous function, which returns a String: +将 `async` 关键字添加到函数会使其返回一个 Future。 +例如,考虑这个返回 String 的同步函数: + ```dart String lookUpVersion() => '1.0.0'; @@ -138,6 +207,9 @@ If you change it to be an `async` function—for example, because a future implementation will be time consuming—the returned value is a Future: +如果你将它改为 `async` 函数——例如, +因为未来的实现将是耗时的——返回值就是一个 Future: + ```dart Future lookUpVersion() async => '1.0.0'; @@ -148,9 +220,17 @@ Dart creates the Future object if necessary. If your function doesn't return a useful value, make its return type `Future`. +请注意,函数体不需要使用 Future API。 +Dart 会在必要时创建 Future 对象。 +如果你的函数不返回有用的值, +请将其返回类型设为 `Future`。 + For an interactive introduction to using futures, `async`, and `await`, see the [asynchronous programming tutorial](/libraries/async/async-await). +有关使用 Future、`async` 和 `await` 的交互式介绍, +请参阅[异步编程教程](/libraries/async/async-await)。 + {% comment %} TODO #1117: Where else should we cover generalized void? {% endcomment %} @@ -158,22 +238,37 @@ TODO #1117: Where else should we cover generalized void? ## Handling Streams +## 处理 Stream + When you need to get values from a Stream, you have two options: +当你需要从 Stream 获取值时,你有两个选择: + * Use `async` and an _asynchronous for loop_ (`await for`). * Use the Stream API, as described in the [`dart:async` documentation](/libraries/dart-async#stream). +* 使用 `async` 和 _异步 for 循环_(`await for`)。 +* 使用 Stream API,如 + [`dart:async` 文档](/libraries/dart-async#stream)中所述。 + :::note Before using `await for`, be sure that it makes the code clearer and that you really do want to wait for all of the stream's results. For example, you usually should **not** use `await for` for UI event listeners, because UI frameworks send endless streams of events. + +在使用 `await for` 之前,请确保它使代码更清晰, +并且你确实想要等待 stream 的所有结果。 +例如,你通常**不应该**对 UI 事件监听器使用 `await for`, +因为 UI 框架会发送无尽的事件流。 ::: An asynchronous for loop has the following form: +异步 for 循环具有以下形式: + ```dart await for (varOrType identifier in expression) { @@ -184,21 +279,37 @@ await for (varOrType identifier in expression) { The value of expression must have type Stream. Execution proceeds as follows: +expression 的值必须是 Stream 类型。 +执行过程如下: + 1. Wait until the stream emits a value. 2. Execute the body of the for loop, with the variable set to that emitted value. 3. Repeat 1 and 2 until the stream is closed. +1. 等待 stream 发出一个值。 +2. 执行 for 循环的主体,将变量设置为发出的值。 +3. 重复 1 和 2,直到 stream 关闭。 + To stop listening to the stream, you can use a `break` or `return` statement, which breaks out of the for loop and unsubscribes from the stream. +要停止监听 stream, +你可以使用 `break` 或 `return` 语句, +这将跳出 for 循环并取消订阅 stream。 + **If you get a compile-time error when implementing an asynchronous for loop, make sure the `await for` is in an `async` function.** For example, to use an asynchronous for loop in your app's `main()` function, the body of `main()` must be marked as `async`: +**如果在实现异步 for 循环时遇到编译时错误, +请确保 `await for` 在 `async` 函数中。** +例如,要在应用的 `main()` 函数中使用异步 for 循环, +`main()` 的函数体必须标记为 `async`: + ```dart void main() [!async!] { @@ -213,6 +324,9 @@ void main() [!async!] { For more information about Dart's asynchronous programming support, check out the [`dart:async`](/libraries/dart-async) library documentation. +有关 Dart 异步编程支持的更多信息, +请查看 [`dart:async`](/libraries/dart-async) 库文档。 + [`Future`]: {{site.dart-api}}/dart-async/Future-class.html [`Stream`]: {{site.dart-api}}/dart-async/Stream-class.html [unawaited_futures linter rule]: /tools/linter-rules/unawaited_futures From 1d6aab81888518a1b5ddf8c2343897a8ffbc77cb Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:31:47 +0000 Subject: [PATCH 11/15] docs(cn): translate error-handling.md --- src/content/language/error-handling.md | 95 ++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 6 deletions(-) diff --git a/src/content/language/error-handling.md b/src/content/language/error-handling.md index a6c249286..964c8c232 100644 --- a/src/content/language/error-handling.md +++ b/src/content/language/error-handling.md @@ -1,34 +1,57 @@ --- -title: Error handling -description: Learn about handling errors and exceptions in Dart. +# title: Error handling +title: 错误处理 +# description: Learn about handling errors and exceptions in Dart. +description: 了解如何在 Dart 中处理错误和异常。 prevpage: url: /language/branches - title: Branches + # title: Branches + title: 分支 nextpage: url: /language/functions - title: Functions + # title: Functions + title: 函数 --- ## Exceptions +## 异常 + Your Dart code can throw and catch exceptions. Exceptions are errors indicating that something unexpected happened. If the exception isn't caught, the [isolate][] that raised the exception is suspended, and typically the isolate and its program are terminated. +你的 Dart 代码可以抛出和捕获异常。异常是表示发生了意外情况的错误。 +如果异常没有被捕获,引发异常的 [isolate][] 将被挂起, +通常 isolate 及其程序将被终止。 + In contrast to Java, all of Dart's exceptions are unchecked exceptions. Methods don't declare which exceptions they might throw, and you aren't required to catch any exceptions. +与 Java 不同,Dart 的所有异常都是非检查异常。 +方法不会声明它们可能抛出哪些异常, +你也不需要捕获任何异常。 + Dart provides [`Exception`][] and [`Error`][] types, as well as numerous predefined subtypes. You can, of course, define your own exceptions. However, Dart programs can throw any non-null object—not just Exception and Error objects—as an exception. +Dart 提供了 [`Exception`][] 和 [`Error`][] 类型, +以及许多预定义的子类型。当然,你也可以定义自己的异常。 +但是,Dart 程序可以将任何非空对象作为异常抛出—— +不仅仅是 Exception 和 Error 对象。 + ### Throw +### 抛出 + Here's an example of throwing, or *raising*, an exception: +下面是抛出或*引发*异常的示例: + ```dart throw FormatException('Expected at least 1 section'); @@ -36,6 +59,8 @@ throw FormatException('Expected at least 1 section'); You can also throw arbitrary objects: +你也可以抛出任意对象: + ```dart throw 'Out of llamas!'; @@ -44,11 +69,16 @@ throw 'Out of llamas!'; :::note Production-quality code usually throws types that implement [`Error`][] or [`Exception`][]. + +生产质量的代码通常会抛出实现了 [`Error`][] 或 [`Exception`][] 的类型。 ::: Because throwing an exception is an expression, you can throw exceptions in =\> statements, as well as anywhere else that allows expressions: +因为抛出异常是一个表达式,所以你可以在 =\> 语句中抛出异常, +也可以在任何其他允许表达式的地方抛出异常: + ```dart void distanceTo(Point other) => throw UnimplementedError(); @@ -57,10 +87,15 @@ void distanceTo(Point other) => throw UnimplementedError(); ### Catch +### 捕获 + Catching, or capturing, an exception stops the exception from propagating (unless you rethrow the exception). Catching an exception gives you a chance to handle it: +捕获异常可以阻止异常继续传播(除非你重新抛出异常)。 +捕获异常让你有机会处理它: + ```dart try { @@ -75,6 +110,10 @@ specify multiple catch clauses. The first catch clause that matches the thrown object's type handles the exception. If the catch clause does not specify a type, that clause can handle any type of thrown object: +要处理可能抛出多种类型异常的代码,你可以指定多个 catch 子句。 +第一个与抛出对象类型匹配的 catch 子句将处理该异常。 +如果 catch 子句没有指定类型,则该子句可以处理任何类型的抛出对象: + ```dart try { @@ -95,10 +134,17 @@ As the preceding code shows, you can use either `on` or `catch` or both. Use `on` when you need to specify the exception type. Use `catch` when your exception handler needs the exception object. +如上面的代码所示,你可以使用 `on` 或 `catch`,或两者都用。 +当你需要指定异常类型时使用 `on`。 +当你的异常处理程序需要异常对象时使用 `catch`。 + You can specify one or two parameters to `catch()`. The first is the exception that was thrown, and the second is the stack trace (a [`StackTrace`][] object). +你可以为 `catch()` 指定一个或两个参数。 +第一个是抛出的异常,第二个是堆栈跟踪([`StackTrace`][] 对象)。 + ```dart try { @@ -115,6 +161,9 @@ To partially handle an exception, while allowing it to propagate, use the `rethrow` keyword. +要部分处理异常,同时允许它继续传播, +请使用 `rethrow` 关键字。 + ```dart void misbehave() { @@ -143,6 +192,11 @@ To ensure that some code runs whether or not an exception is thrown, use a `finally` clause. If no `catch` clause matches the exception, the exception is propagated after the `finally` clause runs: +为了确保无论是否抛出异常某些代码都会运行, +请使用 `finally` 子句。 +如果没有 `catch` 子句匹配该异常, +异常将在 `finally` 子句运行后传播: + ```dart try { @@ -155,6 +209,8 @@ try { The `finally` clause runs after any matching `catch` clauses: +`finally` 子句在任何匹配的 `catch` 子句之后运行: + ```dart try { @@ -169,11 +225,19 @@ try { To learn more, check out the [core library exception docs](/libraries/dart-core#exceptions). +要了解更多信息,请查看[核心库异常文档](/libraries/dart-core#exceptions)。 + ## Assert -During development, use an assert +## 断言 + +During development, use an assert statement— `assert(, );` —to -disrupt normal execution if a boolean condition is false. +disrupt normal execution if a boolean condition is false. + +在开发过程中,使用 assert 语句—— +`assert(, );`—— +如果布尔条件为 false,则中断正常执行。 ```dart @@ -191,6 +255,10 @@ To attach a message to an assertion, add a string as the second argument to `assert` (optionally with a [trailing comma][]): +要为断言附加一条消息, +请将字符串作为 `assert` 的第二个参数添加 +(可选择带有[尾随逗号][trailing comma]): + ```dart assert( @@ -205,18 +273,33 @@ is true, the assertion succeeds and execution continues. If it's false, the assertion fails and an exception (an [`AssertionError`][]) is thrown. +`assert` 的第一个参数可以是任何解析为布尔值的表达式。 +如果表达式的值为 true,断言成功,执行继续。 +如果为 false,断言失败,并抛出异常([`AssertionError`][])。 + When exactly do assertions work? That depends on the tools and framework you're using: +断言究竟何时起作用? +这取决于你使用的工具和框架: + * Flutter enables assertions in [debug mode.][Flutter debug mode] * Development-only tools such as [`webdev serve`][] typically enable assertions by default. * Some tools, such as [`dart run`][] and [`dart compile js`][] support assertions through a command-line flag: `--enable-asserts`. +* Flutter 在[调试模式][Flutter debug mode]下启用断言。 +* 仅用于开发的工具如 [`webdev serve`][] 通常默认启用断言。 +* 某些工具,如 [`dart run`][] 和 [`dart compile js`][], + 通过命令行标志支持断言:`--enable-asserts`。 + In production code, assertions are ignored, and the arguments to `assert` aren't evaluated. +在生产代码中,断言会被忽略, +`assert` 的参数不会被求值。 + [trailing comma]: /language/collections#trailing-comma [`AssertionError`]: {{site.dart-api}}/dart-core/AssertionError-class.html [Flutter debug mode]: {{site.flutter-docs}}/testing/debugging#debug-mode-assertions From 226c418a54f90fe1344a16c2caec86f81e824827 Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:33:20 +0000 Subject: [PATCH 12/15] docs(cn): translate generics.md --- src/content/language/generics.md | 114 +++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 4 deletions(-) diff --git a/src/content/language/generics.md b/src/content/language/generics.md index bf7dde66f..46e7fae9f 100644 --- a/src/content/language/generics.md +++ b/src/content/language/generics.md @@ -1,12 +1,16 @@ --- -title: Generics -description: Learn about generic types in Dart. +# title: Generics +title: 泛型 +# description: Learn about generic types in Dart. +description: 了解 Dart 中的泛型类型。 prevpage: url: /language/collections - title: Collections + # title: Collections + title: 集合 nextpage: url: /language/typedefs - title: Typedefs + # title: Typedefs + title: 类型别名 --- @@ -18,19 +22,38 @@ type is actually `List`. The \<...\> notation marks List as a parameters. [By convention][], most type variables have single-letter names, such as E, T, S, K, and V. +如果你查看基本数组类型 [`List`][] 的 API 文档, +你会看到该类型实际上是 `List`。 +\<...\> 标记将 List 标记为*泛型*(或*参数化*)类型—— +具有形式类型参数的类型。 +[按照约定][By convention],大多数类型变量使用单字母名称, +如 E、T、S、K 和 V。 + ## Why use generics? +## 为什么使用泛型? + Generics are often required for type safety, but they have more benefits than just allowing your code to run: +泛型通常是类型安全所必需的,但它们的好处不仅仅是让你的代码运行: + * Properly specifying generic types results in better generated code. * You can use generics to reduce code duplication. +* 正确指定泛型类型可以生成更好的代码。 +* 你可以使用泛型来减少代码重复。 + If you intend for a list to contain only strings, you can declare it as `List` (read that as "list of string"). That way you, your fellow programmers, and your tools can detect that assigning a non-string to the list is probably a mistake. Here's an example: +如果你打算让一个列表只包含字符串, +你可以将它声明为 `List`(读作"字符串列表")。 +这样你、你的同事程序员和你的工具可以检测到 +将非字符串赋值给列表可能是一个错误。下面是一个例子: + ```dart tag=fails-sa var names = []; names.addAll(['Seth', 'Kathy', 'Lars']); @@ -43,6 +66,11 @@ many types, while still taking advantage of static analysis. For example, say you create an interface for caching an object: +使用泛型的另一个原因是减少代码重复。 +泛型让你可以在多种类型之间共享单个接口和实现, +同时仍然利用静态分析的优势。 +例如,假设你创建一个用于缓存对象的接口: + ```dart abstract class ObjectCache { @@ -54,6 +82,9 @@ abstract class ObjectCache { You discover that you want a string-specific version of this interface, so you create another interface: +你发现你想要这个接口的字符串特定版本, +所以你创建另一个接口: + ```dart abstract class StringCache { @@ -65,9 +96,14 @@ abstract class StringCache { Later, you decide you want a number-specific version of this interface... You get the idea. +后来,你决定要一个数字特定版本的接口……你明白了。 + Generic types can save you the trouble of creating all these interfaces. Instead, you can create a single interface that takes a type parameter: +泛型类型可以省去创建所有这些接口的麻烦。 +相反,你可以创建一个带有类型参数的单一接口: + ```dart abstract class Cache { @@ -79,15 +115,26 @@ abstract class Cache { In this code, T is the stand-in type. It's a placeholder that you can think of as a type that a developer will define later. +在这段代码中,T 是替代类型。 +它是一个占位符,你可以将其视为开发者稍后将定义的类型。 + ## Using collection literals +## 使用集合字面量 + List, set, and map literals can be parameterized. Parameterized literals are just like the literals you've already seen, except that you add <type> (for lists and sets) or <keyType, valueType> (for maps) before the opening bracket. Here is an example of using typed literals: +List、set 和 map 字面量可以参数化。参数化字面量 +与你已经看到的字面量一样,只是你在开括号之前添加了 +<type>(对于 list 和 set)或 +<keyType, valueType>(对于 map)。 +下面是使用类型化字面量的示例: + ```dart var names = ['Seth', 'Kathy', 'Lars']; @@ -102,9 +149,14 @@ var pages = { ## Using parameterized types with constructors +## 在构造函数中使用参数化类型 + To specify one or more types when using a constructor, put the types in angle brackets (`<...>`) just after the class name. For example: +要在使用构造函数时指定一个或多个类型, +请将类型放在类名后面的尖括号(`<...>`)中。例如: + ```dart var nameSet = Set.of(names); @@ -113,6 +165,8 @@ var nameSet = Set.of(names); The following code creates a `SplayTreeMap` that has integer keys and values of type `View`: +以下代码创建一个具有整数键和 `View` 类型值的 `SplayTreeMap`: + ```dart var views = SplayTreeMap(); @@ -121,10 +175,15 @@ var views = SplayTreeMap(); ## Generic collections and the types they contain +## 泛型集合及其包含的类型 + Dart generic types are *reified*, which means that they carry their type information around at runtime. For example, you can test the type of a collection: +Dart 泛型类型是*具体化的*,这意味着它们在运行时 +携带其类型信息。例如,你可以测试集合的类型: + ```dart var names = []; @@ -136,21 +195,38 @@ print(names is List); // true In contrast, generics in Java use *erasure*, which means that generic type parameters are removed at runtime. In Java, you can test whether an object is a List, but you can't test whether it's a `List`. + +相比之下,Java 中的泛型使用*擦除*, +这意味着泛型类型参数在运行时被移除。 +在 Java 中,你可以测试一个对象是否是 List, +但你不能测试它是否是 `List`。 ::: ## Restricting the parameterized type +## 限制参数化类型 + When implementing a generic type, you might want to limit the types that can be provided as arguments, so that the argument must be a subtype of a particular type. This restriction is called a bound. You can do this using `extends`. +在实现泛型类型时, +你可能想要限制可以作为参数提供的类型, +以便参数必须是特定类型的子类型。 +这种限制称为边界。 +你可以使用 `extends` 来实现这一点。 + A common use case is ensuring that a type is non-nullable by making it a subtype of `Object` (instead of the default, [`Object?`][top-and-bottom]). +一个常见的用例是通过使类型成为 `Object` 的子类型 +(而不是默认的 [`Object?`][top-and-bottom]) +来确保类型是非空的。 + ```dart class Foo { @@ -162,6 +238,10 @@ You can use `extends` with other types besides `Object`. Here's an example of extending `SomeBaseClass`, so that members of `SomeBaseClass` can be called on objects of type `T`: +你可以对 `Object` 以外的其他类型使用 `extends`。 +下面是扩展 `SomeBaseClass` 的示例, +这样就可以在类型为 `T` 的对象上调用 `SomeBaseClass` 的成员: + ```dart class Foo { @@ -176,6 +256,8 @@ class Extender extends SomeBaseClass { It's OK to use `SomeBaseClass` or any of its subtypes as the generic argument: +可以使用 `SomeBaseClass` 或其任何子类型作为泛型参数: + ```dart var someBaseClassFoo = [!Foo!](); @@ -184,6 +266,8 @@ var extenderFoo = [!Foo!](); It's also OK to specify no generic argument: +也可以不指定泛型参数: + ```dart var foo = Foo(); @@ -192,16 +276,24 @@ print(foo); // Instance of 'Foo' Specifying any non-`SomeBaseClass` type results in an error: +指定任何非 `SomeBaseClass` 类型会导致错误: + ```dart tag=fails-sa var foo = [!Foo!](); ``` ### Self-referential type parameter restrictions (F-bounds) {:#f-bounds} +### 自引用类型参数限制(F-边界){:#f-bounds} + When using bounds to restrict parameter types, you can refer the bound back to the type parameter itself. This creates a self-referential constraint, or F-bound. For example: +当使用边界来限制参数类型时,你可以将边界 +引用回类型参数本身。这创建了一个自引用约束, +或 F-边界。例如: + ```dart abstract interface class Comparable { @@ -222,10 +314,17 @@ int useIt = compareAndOffset(A(), A()); The F-bound `T extends Comparable` means `T` must be comparable to itself. So, `A` can only be compared to other instances of the same type. +F-边界 `T extends Comparable` 表示 `T` 必须与自身可比较。 +因此,`A` 只能与相同类型的其他实例进行比较。 + ## Using generic methods +## 使用泛型方法 + Methods and functions also allow type arguments: +方法和函数也允许类型参数: + @@ -241,10 +340,17 @@ Methods and functions also allow type arguments: Here the generic type parameter on `first` (``) allows you to use the type argument `T` in several places: +这里 `first` 上的泛型类型参数(``) +允许你在多个地方使用类型参数 `T`: + * In the function's return type (`T`). * In the type of an argument (`List`). * In the type of a local variable (`T tmp`). +* 在函数的返回类型中(`T`)。 +* 在参数的类型中(`List`)。 +* 在局部变量的类型中(`T tmp`)。 + [`List`]: {{site.dart-api}}/dart-core/List-class.html [By convention]: /effective-dart/design#do-follow-existing-mnemonic-conventions-when-naming-type-parameters [top-and-bottom]: /null-safety/understanding-null-safety#top-and-bottom From 45c0518ed76d8a2981bf229c6157f760db77a31a Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:34:13 +0000 Subject: [PATCH 13/15] docs(cn): translate modifier-reference.md --- src/content/language/modifier-reference.md | 33 +++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/content/language/modifier-reference.md b/src/content/language/modifier-reference.md index 208c25579..ee287b00a 100644 --- a/src/content/language/modifier-reference.md +++ b/src/content/language/modifier-reference.md @@ -1,22 +1,33 @@ --- -title: Class modifiers reference +# title: Class modifiers reference +title: 类修饰符参考 +# description: >- +# The allowed and disallowed combinations of class modifiers. description: >- - The allowed and disallowed combinations of class modifiers. + 类修饰符的允许和禁止组合。 prevpage: url: /language/class-modifiers - title: Class modifiers + # title: Class modifiers + title: 类修饰符 nextpage: url: /language/concurrency - title: Concurrency in Dart + # title: Concurrency in Dart + title: Dart 中的并发 --- This page contains reference information for [class modifiers](/language/class-modifiers). +本页面包含[类修饰符](/language/class-modifiers)的参考信息。 + ## Valid combinations +## 有效组合 + The valid combinations of class modifiers and their resulting capabilities are: +类修饰符的有效组合及其产生的功能如下: + | Declaration | [Construct][]? | [Extend][]? | [Implement][]? | [Mix in][]? | [Exhaustive][]? | |-----------------------------|----------------|-------------|----------------|-------------|-----------------| | `class` | **Yes** | **Yes** | **Yes** | No | No | @@ -45,8 +56,12 @@ The valid combinations of class modifiers and their resulting capabilities are: ## Invalid combinations +## 无效组合 + Certain [combinations][] of modifiers aren't allowed: +某些修饰符[组合][combinations]是不允许的: + | Combination | Reasoning | |-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| | `base`, `interface`, and `final` | All control the same two capabilities (`extend` and `implement`), so are mutually exclusive. | @@ -57,6 +72,16 @@ Certain [combinations][] of modifiers aren't allowed: | `enum` and any modifiers | `enum` declarations can't be extended, implemented, mixed in, and can always be instantiated, so no modifiers apply to `enum` declarations. | | `extension type` and any modifiers | `extension type` declarations can't be extended or mixed in, and can only be implemented by other `extension type` declarations. | +| 组合 | 原因 | +|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| +| `base`、`interface` 和 `final` | 都控制相同的两种功能(`extend` 和 `implement`),因此是互斥的。 | +| `sealed` 和 `abstract` | 两者都不能被构造,因此放在一起是多余的。 | +| `sealed` 与 `base`、`interface` 或 `final` | `sealed` 类型已经不能从另一个库中被混入、扩展或实现,因此与列出的修饰符组合是多余的。 | +| `mixin` 和 `abstract` | 两者都不能被构造,因此放在一起是多余的。 | +| `mixin` 与 `interface`、`final` 或 `sealed` | `mixin` 或 `mixin class` 声明旨在被混入,而列出的修饰符会阻止这一点。 | +| `enum` 和任何修饰符 | `enum` 声明不能被扩展、实现或混入,且总是可以被实例化,因此没有修饰符适用于 `enum` 声明。 | +| `extension type` 和任何修饰符 | `extension type` 声明不能被扩展或混入,且只能被其他 `extension type` 声明实现。 | + {: .table .table-striped .nowrap} [combinations]: /language/class-modifiers#combining-modifiers From d84621e69e03110815921ff511a1eb68c1034e4c Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 01:36:04 +0000 Subject: [PATCH 14/15] docs(cn): translate loops.md --- src/content/language/loops.md | 136 ++++++++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 5 deletions(-) diff --git a/src/content/language/loops.md b/src/content/language/loops.md index 55cc14089..fb14f6a6e 100644 --- a/src/content/language/loops.md +++ b/src/content/language/loops.md @@ -1,30 +1,49 @@ --- -title: Loops -description: Learn how to use loops to control the flow of your Dart code. +# title: Loops +title: 循环 +# description: Learn how to use loops to control the flow of your Dart code. +description: 了解如何使用循环来控制 Dart 代码的流程。 prevpage: url: /language/pattern-types - title: Pattern types + # title: Pattern types + title: 模式类型 nextpage: url: /language/branches - title: Branches + # title: Branches + title: 分支 --- This page shows how you can control the flow of your Dart code using loops and supporting statements: +本页面展示如何使用循环和辅助语句来控制 Dart 代码的流程: + - `for` loops - `while` and `do while` loops - `break` and `continue` +- `for` 循环 +- `while` 和 `do while` 循环 +- `break` 和 `continue` + You can also manipulate control flow in Dart using: +你还可以使用以下方式在 Dart 中控制流程: + - [Branching][], like `if` and `switch` - [Exceptions][], like `try`, `catch`, and `throw` +- [分支][Branching],如 `if` 和 `switch` +- [异常][Exceptions],如 `try`、`catch` 和 `throw` + ## For loops +## For 循环 + You can iterate with the standard `for` loop. For example: +你可以使用标准的 `for` 循环进行迭代。例如: + ```dart var message = StringBuffer('Dart is fun'); @@ -36,6 +55,9 @@ for (var i = 0; i < 5; i++) { Closures inside of Dart's `for` loops capture the _value_ of the index. This avoids a common pitfall found in JavaScript. For example, consider: +Dart `for` 循环内的闭包会捕获索引的_值_。 +这避免了 JavaScript 中常见的陷阱。例如,考虑: + ```dart var callbacks = []; @@ -51,10 +73,17 @@ for (final c in callbacks) { The output is `0` and then `1`, as expected. In contrast, the example would print `2` and then `2` in JavaScript. +输出如预期的那样是 `0` 然后是 `1`。 +相比之下,该示例在 JavaScript 中会打印 `2` 然后是 `2`。 + Sometimes you might not need to know the current iteration counter when iterating over an [`Iterable`][] type, like `List` or `Set`. In that case, use the `for-in` loop for cleaner code: +有时在遍历 [`Iterable`][] 类型(如 `List` 或 `Set`)时, +你可能不需要知道当前的迭代计数器。 +在这种情况下,使用 `for-in` 循环可以使代码更简洁: + ```dart for (var candidate in candidates) { @@ -70,9 +99,18 @@ Reassigning `candidate` inside the loop body only changes the local variable for that iteration and doesn't modify the original `candidates` iterable. -To process the values obtained from the iterable, +在前面的示例循环中,`candidate` 在循环体内定义, +并设置为每次引用 `candidates` 中的一个值。 +`candidate` 是一个局部[变量][variable]。 +在循环体内重新赋值 `candidate` 只会更改该次迭代的局部变量, +不会修改原始的 `candidates` 可迭代对象。 + +To process the values obtained from the iterable, you can also use a [pattern][] in a `for-in` loop: +要处理从可迭代对象获取的值, +你也可以在 `for-in` 循环中使用[模式][pattern]: + ```dart for (final Candidate(:name, :yearsExperience) in candidates) { @@ -83,10 +121,15 @@ for (final Candidate(:name, :yearsExperience) in candidates) { :::tip To practice using `for-in`, follow the [Iterable collections tutorial](/libraries/collections/iterables). + +要练习使用 `for-in`,请参阅 +[可迭代集合教程](/libraries/collections/iterables)。 ::: Iterable classes also have a [forEach()][] method as another option: +可迭代类还有一个 [forEach()][] 方法作为另一种选择: + ```dart var collection = [1, 2, 3]; @@ -97,8 +140,12 @@ collection.forEach(print); // 1 2 3 ## While and do-while +## While 和 do-while + A `while` loop evaluates the condition before the loop: +`while` 循环在循环之前评估条件: + ```dart while (!isDone()) { @@ -108,6 +155,8 @@ while (!isDone()) { A `do`-`while` loop evaluates the condition *after* the loop: +`do`-`while` 循环在循环*之后*评估条件: + ```dart do { @@ -118,8 +167,12 @@ do { ## Break and continue +## Break 和 continue + Use `break` to stop looping: +使用 `break` 停止循环: + ```dart while (true) { @@ -130,6 +183,8 @@ while (true) { Use `continue` to skip to the next loop iteration: +使用 `continue` 跳到下一次循环迭代: + ```dart for (int i = 0; i < candidates.length; i++) { @@ -144,6 +199,9 @@ for (int i = 0; i < candidates.length; i++) { If you're using an [`Iterable`][] such as a list or set, how you write the previous example might differ: +如果你使用的是 [`Iterable`][](如列表或集合), +编写前面示例的方式可能会有所不同: + ```dart candidates @@ -153,31 +211,55 @@ candidates ## Labels +## 标签 + A label is an identifier followed by a colon (`labelName:`) that you can place before a statement to create a _labeled statement_. Loops and switch cases are often used as labeled statements. A labeled statement can be referenced later in a `break` or `continue` statement as follows: +标签是一个后跟冒号(`labelName:`)的标识符, +你可以将其放在语句之前以创建_带标签的语句_。 +循环和 switch case 通常用作带标签的语句。 +带标签的语句可以稍后在 `break` 或 `continue` 语句中引用,如下所示: + * `break labelName;` Terminates the execution of the labeled statement. This is useful for breaking out of a specific outer loop when you're within a nested loop. +* `break labelName;` + 终止带标签语句的执行。 + 当你在嵌套循环中时,这对于跳出特定的外部循环很有用。 + * `continue labelName;` Skips the rest of the current iteration of the labeled statement loop and continues with the next iteration. +* `continue labelName;` + 跳过带标签语句循环当前迭代的剩余部分, + 并继续下一次迭代。 + Labels are used to manage control flow. They are often used with loops and switch cases and allow you to specify which statement to break out of or continue, rather than affecting the innermost loop by default. +标签用于管理控制流。它们通常与循环和 switch case 一起使用, +允许你指定要跳出或继续的语句, +而不是默认影响最内层的循环。 + ### Labels in for loop using `break` {:.no_toc} +### 在 for 循环中使用 `break` 的标签 {:.no_toc} + The following code demonstrates the usage of a label called `outerLoop` in a `for` loop with a `break` statement: +以下代码演示了在带有 `break` 语句的 `for` 循环中 +使用名为 `outerLoop` 的标签: + ```dart outerLoop: @@ -195,6 +277,9 @@ print('outerLoop exited'); In the previous example, when `i == 2` and `j == 2`, the `break outerLoop;` statement stops both inner and outer loops. As a result, the output is: +在前面的示例中,当 `i == 2` 且 `j == 2` 时, +`break outerLoop;` 语句会停止内部和外部循环。因此,输出是: + ```plaintext i = 1, j = 1 i = 1, j = 2 @@ -206,9 +291,14 @@ outerLoop exited ### Labels in for loop using `continue` {:.no_toc} +### 在 for 循环中使用 `continue` 的标签 {:.no_toc} + The following code demonstrates the use of a label called `outerLoop` in a `for` loop with a `continue` statement: +以下代码演示了在带有 `continue` 语句的 `for` 循环中 +使用名为 `outerLoop` 的标签: + ```dart outerLoop: @@ -225,6 +315,10 @@ for (var i = 1; i <= 3; i++) { In the previous example, when `i == 2` and `j == 2`, `continue outerLoop;` skips the rest of the iterations for `i = 2` and moves to `i = 3`. As a result, the output is: +在前面的示例中,当 `i == 2` 且 `j == 2` 时, +`continue outerLoop;` 跳过 `i = 2` 的剩余迭代并移动到 `i = 3`。 +因此,输出是: + ```plaintext i = 1, j = 1 i = 1, j = 2 @@ -237,9 +331,14 @@ i = 3, j = 3 ### Labels in while loop using `break` {:.no_toc} +### 在 while 循环中使用 `break` 的标签 {:.no_toc} + The following code demonstrates the use of a label called `outerLoop` in a `while` loop with a `break` statement: +以下代码演示了在带有 `break` 语句的 `while` 循环中 +使用名为 `outerLoop` 的标签: + ```dart var i = 1; @@ -262,6 +361,9 @@ print('outerLoop exited'); In the previous example, the program breaks out of both inner and outer `while` loops when `i == 2` and `j == 2`. As a result, the output is: +在前面的示例中,当 `i == 2` 且 `j == 2` 时, +程序跳出内部和外部的 `while` 循环。因此,输出是: + ```plaintext i = 1, j = 1 i = 1, j = 2 @@ -273,9 +375,14 @@ outerLoop exited ### Labels in while loop using `continue` {:.no_toc} +### 在 while 循环中使用 `continue` 的标签 {:.no_toc} + The following code demonstrates the use of a label called `outerLoop` in a `while` loop with a `continue` statement: +以下代码演示了在带有 `continue` 语句的 `while` 循环中 +使用名为 `outerLoop` 的标签: + ```dart var i = 1; @@ -298,6 +405,9 @@ while (i <= 3) { In the previous example, the iteration for `i = 2` and `j = 2` is skipped and the loop moves directly to `i = 3`. As a result, the output is: +在前面的示例中,`i = 2` 且 `j = 2` 的迭代被跳过, +循环直接移动到 `i = 3`。因此,输出是: + ```plaintext i = 1, j = 1 i = 1, j = 2 @@ -310,9 +420,14 @@ i = 3, j = 3 ### Labels in do-while loop using `break` {:.no_toc} +### 在 do-while 循环中使用 `break` 的标签 {:.no_toc} + The following code demonstrates the use of a label called `outerLoop` in a `do while` loop with a `break` statement: +以下代码演示了在带有 `break` 语句的 `do while` 循环中 +使用名为 `outerLoop` 的标签: + ```dart var i = 1; @@ -336,6 +451,9 @@ print('outerLoop exited'); In the previous example, the program breaks out of both inner and outer loops when `i == 2` and `j == 2`. As a result, the output is: +在前面的示例中,当 `i == 2` 且 `j == 2` 时, +程序跳出内部和外部循环。因此,输出是: + ```plaintext i = 1, j = 1 i = 1, j = 2 @@ -347,9 +465,14 @@ outerLoop exited ### Labels in do-while loop using `continue` {:.no_toc} +### 在 do-while 循环中使用 `continue` 的标签 {:.no_toc} + The following code demonstrates the use of a label called `outerLoop` in a `do while` loop with a `continue` statement: +以下代码演示了在带有 `continue` 语句的 `do while` 循环中 +使用名为 `outerLoop` 的标签: + ```dart var i = 1; @@ -372,6 +495,9 @@ do { In the previous example, the loop skips `i = 2` and `j = 2` and moves directly to `i = 3`. As a result, the output is: +在前面的示例中,循环跳过 `i = 2` 且 `j = 2`, +并直接移动到 `i = 3`。因此,输出是: + ```plaintext i = 1, j = 1 i = 1, j = 2 From 142e66fa30d860ceacd5e1c389248f5cbe909f44 Mon Sep 17 00:00:00 2001 From: Vadaski Date: Tue, 2 Dec 2025 08:26:07 +0000 Subject: [PATCH 15/15] =?UTF-8?q?fix:=20=E6=81=A2=E5=A4=8D=E8=8B=B1?= =?UTF-8?q?=E6=96=87=E5=8E=9F=E6=96=87=EF=BC=8C=E6=94=B9=E4=B8=BA=E8=8B=B1?= =?UTF-8?q?=E6=96=87+=E4=B8=AD=E6=96=87=E5=8F=8C=E8=AF=AD=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复翻译格式: - frontmatter: 英文注释 + 中文值 - body: 英文原文 + 中文翻译交替 共修复 14 个文件 --- fix_translation_final.py | 183 ++++++++++++++++++++ src/content/language/async.md | 188 +++++++++++++-------- src/content/language/callable-objects.md | 16 +- src/content/language/enums.md | 157 ++++++++++------- src/content/language/error-handling.md | 147 ++++++++++------ src/content/language/extend.md | 115 ++++++++----- src/content/language/generics.md | 133 +++++++++++---- src/content/language/keywords.md | 12 +- src/content/language/libraries.md | 171 ++++++++++++------- src/content/language/loops.md | 172 ++++++++++++++----- src/content/language/metadata.md | 129 +++++++++----- src/content/language/methods.md | 131 ++++++++------ src/content/language/mixins.md | 173 ++++++++++++------- src/content/language/modifier-reference.md | 44 +++-- src/content/language/typedefs.md | 31 ++-- 15 files changed, 1240 insertions(+), 562 deletions(-) create mode 100644 fix_translation_final.py diff --git a/fix_translation_final.py b/fix_translation_final.py new file mode 100644 index 000000000..609d64c29 --- /dev/null +++ b/fix_translation_final.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 +""" +修复翻译文件 - 最终版 +将纯中文翻译改为英文+中文双语格式 +""" + +import subprocess +import re +import sys +from pathlib import Path + +def get_content(repo_path, file_path, ref=None): + """获取文件内容""" + if ref: + result = subprocess.run( + ['git', 'show', f'{ref}:{file_path}'], + cwd=repo_path, + capture_output=True, + text=True + ) + return result.stdout if result.returncode == 0 else None + else: + full_path = Path(repo_path) / file_path + return full_path.read_text(encoding='utf-8') if full_path.exists() else None + +def split_content(content): + """分离 frontmatter 和 body""" + if not content.startswith('---'): + return '', content + + lines = content.split('\n') + for i, line in enumerate(lines[1:], 1): + if line.strip() == '---': + fm = '\n'.join(lines[1:i]) + body = '\n'.join(lines[i+1:]) + return fm, body.strip() + return '', content + +def merge_frontmatter(en_fm, cn_fm): + """合并 frontmatter - 保留英文结构,仅对 title/description 添加中文""" + translatable = {'title', 'description', 'short-title', 'shortTitle'} + + # 解析中文 frontmatter + cn_dict = {} + for line in cn_fm.split('\n'): + if line.startswith('#') or not ':' in line: + continue + if not line.startswith(' ') and not line.startswith('\t'): + parts = line.split(':', 1) + key = parts[0].strip() + val = parts[1].strip() if len(parts) > 1 else '' + if val and val != '>': + cn_dict[key] = val + + # 处理英文 frontmatter + result = ['---'] + en_lines = en_fm.split('\n') + i = 0 + + while i < len(en_lines): + line = en_lines[i] + + if not line.strip(): + result.append(line) + i += 1 + continue + + # 检查是否是键值对 + if ':' in line and not line.startswith(' ') and not line.startswith('\t'): + key = line.split(':')[0].strip() + + # 收集完整的多行值 + full_lines = [line] + j = i + 1 + while j < len(en_lines) and (en_lines[j].startswith(' ') or en_lines[j].startswith('\t')): + full_lines.append(en_lines[j]) + j += 1 + + # 可翻译字段特殊处理 + if key in translatable: + # 添加英文注释 + for fl in full_lines: + result.append(f'# {fl}') + # 添加翻译值(目前保持英文,因为原翻译没有这些) + for fl in full_lines: + result.append(fl) + else: + # 非翻译字段直接保留 + for fl in full_lines: + result.append(fl) + + i = j + else: + result.append(line) + i += 1 + + result.append('---') + return '\n'.join(result) + +def merge_body(en_body, cn_body): + """合并正文 - 英文原文 + 中文翻译""" + # 按段落分割 + en_paras = [p.strip() for p in re.split(r'\n\n+', en_body) if p.strip()] + cn_paras = [p.strip() for p in re.split(r'\n\n+', cn_body) if p.strip()] + + # 筛选中文段落(包含中文字符) + cn_text_paras = [] + for p in cn_paras: + if re.search(r'[\u4e00-\u9fff]', p): + # 排除代码块等特殊内容 + if not (p.startswith('```') or p.startswith(' [file2] ...") + sys.exit(1) + + repo_path = sys.argv[1] + files = sys.argv[2:] + + print(f"Fixing {len(files)} files in {repo_path}...") + fixed = sum(1 for f in files if fix_file(repo_path, f)) + print(f"\nDone: {fixed}/{len(files)} files fixed") + +if __name__ == '__main__': + main() diff --git a/src/content/language/async.md b/src/content/language/async.md index d1dd19404..ae5eeebfb 100644 --- a/src/content/language/async.md +++ b/src/content/language/async.md @@ -1,18 +1,16 @@ --- # title: Asynchronous programming -title: 异步编程 +title: Asynchronous programming # description: Information on writing asynchronous code in Dart. -description: 关于在 Dart 中编写异步代码的信息。 +description: Information on writing asynchronous code in Dart. # shortTitle: Async programming -shortTitle: 异步编程 +shortTitle: Async programming prevpage: url: /language/concurrency - # title: Concurrency - title: 并发 + title: Concurrency nextpage: url: /language/isolates - # title: Isolates - title: Isolate + title: Isolates --- @@ -25,6 +23,8 @@ a possibly time-consuming operation (such as I/O), without waiting for that operation to complete. + + Dart 库中充满了返回 [`Future`][] 或 [`Stream`][] 对象的函数。 这些函数是 _异步的_: 它们在设置可能耗时的操作(如 I/O)后返回, @@ -34,17 +34,22 @@ The `async` and `await` keywords support asynchronous programming, letting you write asynchronous code that looks similar to synchronous code. + + `async` 和 `await` 关键字支持异步编程, 让你可以编写看起来类似于同步代码的异步代码。 - ## Handling Futures + + ## 处理 Future When you need the result of a completed Future, you have two options: + + 当你需要已完成 Future 的结果时,你有两个选择: * Use `async` and `await`, as described here and in the @@ -52,6 +57,8 @@ you have two options: * Use the Future API, as described in the [`dart:async` documentation](/libraries/dart-async#future). + + * 使用 `async` 和 `await`,如此处和 [异步编程教程](/libraries/async/async-await)中所述。 * 使用 Future API,如 @@ -62,6 +69,8 @@ but it looks a lot like synchronous code. For example, here's some code that uses `await` to wait for the result of an asynchronous function: + + 使用 `async` 和 `await` 的代码是异步的, 但它看起来很像同步代码。 例如,下面是一些使用 `await` 等待异步函数结果的代码: @@ -74,6 +83,8 @@ await lookUpVersion(); To use `await`, code must be in an `async` function—a function marked as `async`: + + 要使用 `await`,代码必须在 `async` 函数中—— 即标记为 `async` 的函数: @@ -86,12 +97,18 @@ Future checkVersion() [!async!] { ``` :::note -Although an `async` function might perform time-consuming operations, -it doesn't wait for those operations. +Although an `async` function might perform time-consuming operations, +it doesn't wait for those operations. Instead, the `async` function executes only until it encounters its first `await` expression. Then it returns a `Future` object, resuming execution only after the `await` expression completes. +::: + +Use `try`, `catch`, and `finally` to handle errors and cleanup +in code that uses `await`: + + 尽管 `async` 函数可能执行耗时的操作, 但它不会等待这些操作。 @@ -100,12 +117,6 @@ resuming execution only after the `await` expression completes. 仅在 `await` 表达式完成后才恢复执行。 ::: -Use `try`, `catch`, and `finally` to handle errors and cleanup -in code that uses `await`: - -使用 `try`、`catch` 和 `finally` 来处理使用 `await` 的代码中的 -错误和清理工作: - ```dart try { @@ -119,8 +130,10 @@ You can use `await` multiple times in an `async` function. For example, the following code waits three times for the results of functions: -你可以在 `async` 函数中多次使用 `await`。 -例如,以下代码等待三次函数的结果: + + +使用 `try`、`catch` 和 `finally` 来处理使用 `await` 的代码中的 +错误和清理工作: ```dart @@ -136,22 +149,24 @@ This Future object indicates a promise to return an object. The value of await expression is that returned object. The await expression makes execution pause until that object is available. -在 await expression 中, -expression 的值通常是一个 Future; -如果不是,那么该值会自动包装在一个 Future 中。 -这个 Future 对象表示承诺返回一个对象。 -await expression 的值就是返回的对象。 -await 表达式使执行暂停,直到该对象可用。 + + +你可以在 `async` 函数中多次使用 `await`。 +例如,以下代码等待三次函数的结果: **If you get a compile-time error when using `await`, make sure `await` is in an `async` function.** For example, to use `await` in your app's `main()` function, the body of `main()` must be marked as `async`: -**如果在使用 `await` 时遇到编译时错误, -请确保 `await` 在 `async` 函数中。** -例如,要在应用的 `main()` 函数中使用 `await`, -`main()` 的函数体必须标记为 `async`: + + +在 await expression 中, +expression 的值通常是一个 Future; +如果不是,那么该值会自动包装在一个 Future 中。 +这个 Future 对象表示承诺返回一个对象。 +await expression 的值就是返回的对象。 +await 表达式使执行暂停,直到该对象可用。 ```dart @@ -167,36 +182,44 @@ without waiting for a result—a practice that can cause problems if the code assumes that the function has finished executing. To avoid this problem, use the [unawaited_futures linter rule][]. - -前面的示例使用了 `async` 函数(`checkVersion()`) -而没有等待结果——如果代码假设该函数已完成执行, -这种做法可能会导致问题。 -为避免此问题, -请使用 [unawaited_futures linter 规则][unawaited_futures linter rule]。 ::: For an interactive introduction to using futures, `async`, and `await`, see the [asynchronous programming tutorial](/libraries/async/async-await). -有关使用 Future、`async` 和 `await` 的交互式介绍, -请参阅[异步编程教程](/libraries/async/async-await)。 +**如果在使用 `await` 时遇到编译时错误, +请确保 `await` 在 `async` 函数中。** +例如,要在应用的 `main()` 函数中使用 `await`, +`main()` 的函数体必须标记为 `async`: + ## Declaring async functions -## 声明 async 函数 + + +前面的示例使用了 `async` 函数(`checkVersion()`) +而没有等待结果——如果代码假设该函数已完成执行, +这种做法可能会导致问题。 +为避免此问题, +请使用 [unawaited_futures linter 规则][unawaited_futures linter rule]。 +::: An `async` function is a function whose body is marked with the `async` modifier. -`async` 函数是其函数体标记有 `async` 修饰符的函数。 + + +有关使用 Future、`async` 和 `await` 的交互式介绍, +请参阅[异步编程教程](/libraries/async/async-await)。 Adding the `async` keyword to a function makes it return a Future. For example, consider this synchronous function, which returns a String: -将 `async` 关键字添加到函数会使其返回一个 Future。 -例如,考虑这个返回 String 的同步函数: + + +## 声明 async 函数 ```dart @@ -207,8 +230,9 @@ If you change it to be an `async` function—for example, because a future implementation will be time consuming—the returned value is a Future: -如果你将它改为 `async` 函数——例如, -因为未来的实现将是耗时的——返回值就是一个 Future: + + +`async` 函数是其函数体标记有 `async` 修饰符的函数。 ```dart @@ -220,54 +244,60 @@ Dart creates the Future object if necessary. If your function doesn't return a useful value, make its return type `Future`. -请注意,函数体不需要使用 Future API。 -Dart 会在必要时创建 Future 对象。 -如果你的函数不返回有用的值, -请将其返回类型设为 `Future`。 + + +将 `async` 关键字添加到函数会使其返回一个 Future。 +例如,考虑这个返回 String 的同步函数: For an interactive introduction to using futures, `async`, and `await`, see the [asynchronous programming tutorial](/libraries/async/async-await). -有关使用 Future、`async` 和 `await` 的交互式介绍, -请参阅[异步编程教程](/libraries/async/async-await)。 + + +如果你将它改为 `async` 函数——例如, +因为未来的实现将是耗时的——返回值就是一个 Future: {% comment %} TODO #1117: Where else should we cover generalized void? {% endcomment %} - ## Handling Streams -## 处理 Stream + + +请注意,函数体不需要使用 Future API。 +Dart 会在必要时创建 Future 对象。 +如果你的函数不返回有用的值, +请将其返回类型设为 `Future`。 When you need to get values from a Stream, you have two options: -当你需要从 Stream 获取值时,你有两个选择: + + +有关使用 Future、`async` 和 `await` 的交互式介绍, +请参阅[异步编程教程](/libraries/async/async-await)。 * Use `async` and an _asynchronous for loop_ (`await for`). * Use the Stream API, as described in the [`dart:async` documentation](/libraries/dart-async#stream). -* 使用 `async` 和 _异步 for 循环_(`await for`)。 -* 使用 Stream API,如 - [`dart:async` 文档](/libraries/dart-async#stream)中所述。 + + +## 处理 Stream :::note Before using `await for`, be sure that it makes the code clearer and that you really do want to wait for all of the stream's results. For example, you usually should **not** use `await for` for UI event listeners, because UI frameworks send endless streams of events. - -在使用 `await for` 之前,请确保它使代码更清晰, -并且你确实想要等待 stream 的所有结果。 -例如,你通常**不应该**对 UI 事件监听器使用 `await for`, -因为 UI 框架会发送无尽的事件流。 ::: An asynchronous for loop has the following form: -异步 for 循环具有以下形式: + + +当你需要从 Stream 获取值时,你有两个选择: ```dart @@ -279,36 +309,43 @@ await for (varOrType identifier in expression) { The value of expression must have type Stream. Execution proceeds as follows: -expression 的值必须是 Stream 类型。 -执行过程如下: + + +* 使用 `async` 和 _异步 for 循环_(`await for`)。 +* 使用 Stream API,如 + [`dart:async` 文档](/libraries/dart-async#stream)中所述。 1. Wait until the stream emits a value. 2. Execute the body of the for loop, with the variable set to that emitted value. 3. Repeat 1 and 2 until the stream is closed. -1. 等待 stream 发出一个值。 -2. 执行 for 循环的主体,将变量设置为发出的值。 -3. 重复 1 和 2,直到 stream 关闭。 + + +在使用 `await for` 之前,请确保它使代码更清晰, +并且你确实想要等待 stream 的所有结果。 +例如,你通常**不应该**对 UI 事件监听器使用 `await for`, +因为 UI 框架会发送无尽的事件流。 +::: To stop listening to the stream, you can use a `break` or `return` statement, which breaks out of the for loop and unsubscribes from the stream. -要停止监听 stream, -你可以使用 `break` 或 `return` 语句, -这将跳出 for 循环并取消订阅 stream。 + + +异步 for 循环具有以下形式: **If you get a compile-time error when implementing an asynchronous for loop, make sure the `await for` is in an `async` function.** For example, to use an asynchronous for loop in your app's `main()` function, the body of `main()` must be marked as `async`: -**如果在实现异步 for 循环时遇到编译时错误, -请确保 `await for` 在 `async` 函数中。** -例如,要在应用的 `main()` 函数中使用异步 for 循环, -`main()` 的函数体必须标记为 `async`: + + +expression 的值必须是 Stream 类型。 +执行过程如下: ```dart @@ -324,8 +361,11 @@ void main() [!async!] { For more information about Dart's asynchronous programming support, check out the [`dart:async`](/libraries/dart-async) library documentation. -有关 Dart 异步编程支持的更多信息, -请查看 [`dart:async`](/libraries/dart-async) 库文档。 + + +1. 等待 stream 发出一个值。 +2. 执行 for 循环的主体,将变量设置为发出的值。 +3. 重复 1 和 2,直到 stream 关闭。 [`Future`]: {{site.dart-api}}/dart-async/Future-class.html [`Stream`]: {{site.dart-api}}/dart-async/Stream-class.html diff --git a/src/content/language/callable-objects.md b/src/content/language/callable-objects.md index f5a04aab1..dfdd45495 100644 --- a/src/content/language/callable-objects.md +++ b/src/content/language/callable-objects.md @@ -1,17 +1,15 @@ --- # title: Callable objects -title: 可调用对象 +title: Callable objects # description: Learn how to create and use callable objects in Dart. -description: 了解如何在 Dart 中创建和使用可调用对象。 +description: Learn how to create and use callable objects in Dart. showToc: false prevpage: url: /language/extension-types - # title: Extension types - title: 扩展类型 + title: Extension types nextpage: url: /language/class-modifiers - # title: Class modifiers - title: 类修饰符 + title: Class modifiers --- @@ -19,6 +17,8 @@ nextpage: To allow an instance of your Dart class to be called like a function, implement the `call()` method. + + 要让 Dart 类的实例能够像函数一样被调用, 请实现 `call()` 方法。 @@ -26,6 +26,8 @@ The `call()` method allows an instance of any class that defines it to emulate a This method supports the same functionality as normal [functions][] such as parameters and return types. + + `call()` 方法允许任何定义了它的类的实例模拟函数。 此方法支持与普通[函数][functions]相同的功能, 如参数和返回类型。 @@ -34,6 +36,8 @@ In the following example, the `WannabeFunction` class defines a `call()` functio that takes three strings and concatenates them, separating each with a space, and appending an exclamation. Click **Run** to execute the code. + + 在下面的示例中,`WannabeFunction` 类定义了一个 `call()` 函数, 该函数接受三个字符串并将它们连接起来,用空格分隔, 并在末尾添加感叹号。点击 **Run** 执行代码。 diff --git a/src/content/language/enums.md b/src/content/language/enums.md index 48e4c9fd1..6d2a14c85 100644 --- a/src/content/language/enums.md +++ b/src/content/language/enums.md @@ -1,24 +1,24 @@ --- # title: Enumerated types -title: 枚举类型 +title: Enumerated types # description: Learn about the enum type in Dart. -description: 了解 Dart 中的枚举类型。 +description: Learn about the enum type in Dart. # shortTitle: Enums -shortTitle: 枚举 +shortTitle: Enums prevpage: url: /language/mixins - # title: Mixins - title: Mixin + title: Mixins nextpage: url: /language/dot-shorthands - # title: Dot shorthands - title: 点简写 + title: Dot shorthands --- Enumerated types, often called _enumerations_ or _enums_, are a special kind of class used to represent a fixed number of constant values. + + 枚举类型,通常称为 _enumerations_ 或 _enums_, 是一种特殊的类,用于表示固定数量的常量值。 @@ -28,30 +28,34 @@ They are also sealed, meaning they cannot be subclassed, implemented, mixed in, or otherwise explicitly instantiated. +Abstract classes and mixins can explicitly implement or extend `Enum`, +but unless they are then implemented by or mixed into an enum declaration, +no objects can actually implement the type of that class or mixin. +::: + + + 所有枚举都自动扩展 [`Enum`][] 类。 它们也是密封的, 这意味着它们不能被子类化、实现、混入, 或以其他方式显式实例化。 -Abstract classes and mixins can explicitly implement or extend `Enum`, -but unless they are then implemented by or mixed into an enum declaration, -no objects can actually implement the type of that class or mixin. +## Declaring simple enums + + 抽象类和 mixin 可以显式实现或扩展 `Enum`, 但除非它们随后被枚举声明实现或混入, 否则没有对象可以真正实现该类或 mixin 的类型。 ::: -## Declaring simple enums - -## 声明简单枚举 - To declare a simple enumerated type, use the `enum` keyword and list the values you want to be enumerated: -要声明一个简单的枚举类型, -使用 `enum` 关键字并列出你想要枚举的值: + + +## 声明简单枚举 ```dart @@ -61,29 +65,32 @@ enum Color { red, green, blue } :::tip You can also use [trailing commas][] when declaring an enumerated type to help prevent copy-paste errors. - -在声明枚举类型时,你也可以使用[尾随逗号][trailing commas] -来帮助防止复制粘贴错误。 ::: ## Declaring enhanced enums -## 声明增强枚举 + + +要声明一个简单的枚举类型, +使用 `enum` 关键字并列出你想要枚举的值: Dart also allows enum declarations to declare classes with fields, methods, and const constructors which are limited to a fixed number of known constant instances. -Dart 还允许枚举声明来声明具有字段、方法和 const 构造函数的类, -这些类被限制为固定数量的已知常量实例。 + + +在声明枚举类型时,你也可以使用[尾随逗号][trailing commas] +来帮助防止复制粘贴错误。 +::: To declare an enhanced enum, follow a syntax similar to normal [classes][], but with a few extra requirements: -要声明一个增强枚举, -遵循与普通[类][classes]类似的语法, -但有一些额外的要求: + + +## 声明增强枚举 * Instance variables must be `final`, including those added by [mixins][]. @@ -98,6 +105,26 @@ but with a few extra requirements: in the beginning of the declaration, and there must be at least one instance declared. + + +Dart 还允许枚举声明来声明具有字段、方法和 const 构造函数的类, +这些类被限制为固定数量的已知常量实例。 + +Instance methods in an enhanced enum can use `this` to +reference the current enum value. + + + +要声明一个增强枚举, +遵循与普通[类][classes]类似的语法, +但有一些额外的要求: + +Here is an example that declares an enhanced enum +with multiple instances, instance variables, +getters, and an implemented interface: + + + * 实例变量必须是 `final` 的, 包括由 [mixin][mixins] 添加的变量。 * 所有[生成式构造函数][generative constructors]必须是常量。 @@ -110,18 +137,6 @@ but with a few extra requirements: * 枚举的所有实例必须在声明的开头声明, 并且必须至少声明一个实例。 -Instance methods in an enhanced enum can use `this` to -reference the current enum value. - -增强枚举中的实例方法可以使用 `this` 来引用当前的枚举值。 - -Here is an example that declares an enhanced enum -with multiple instances, instance variables, -getters, and an implemented interface: - -下面是一个声明增强枚举的示例, -包含多个实例、实例变量、getter 和实现的接口: - ```dart enum Vehicle implements Comparable { @@ -129,39 +144,65 @@ enum Vehicle implements Comparable { bus(tires: 6, passengers: 50, carbonPerKilometer: 800), bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0); - const Vehicle({ +const Vehicle({ required this.tires, required this.passengers, required this.carbonPerKilometer, }); - final int tires; + + +增强枚举中的实例方法可以使用 `this` 来引用当前的枚举值。 + +final int tires; final int passengers; final int carbonPerKilometer; - int get carbonFootprint => (carbonPerKilometer / passengers).round(); - bool get isTwoWheeled => this == Vehicle.bicycle; - @override +下面是一个声明增强枚举的示例, +包含多个实例、实例变量、getter 和实现的接口: + +int get carbonFootprint => (carbonPerKilometer / passengers).round(); + + + +增强枚举需要至少 2.17 的[语言版本][language version]。 +::: + +bool get isTwoWheeled => this == Vehicle.bicycle; + + + +## 使用枚举 + +@override int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint; } ``` + + +像访问任何其他[静态变量][static variable]一样访问枚举值: + :::version-note Enhanced enums require a [language version][] of at least 2.17. - -增强枚举需要至少 2.17 的[语言版本][language version]。 ::: ## Using enums -## 使用枚举 + + +枚举中的每个值都有一个 `index` getter, +它返回该值在枚举声明中从零开始的位置。 +例如,第一个值的索引是 0,第二个值的索引是 1。 Access the enumerated values like any other [static variable][]: -像访问任何其他[静态变量][static variable]一样访问枚举值: + + +要获取所有枚举值的列表,请使用枚举的 `values` 常量。 ```dart @@ -176,9 +217,10 @@ which returns the zero-based position of the value in the enum declaration. For example, the first value has index 0, and the second value has index 1. -枚举中的每个值都有一个 `index` getter, -它返回该值在枚举声明中从零开始的位置。 -例如,第一个值的索引是 0,第二个值的索引是 1。 + + +你可以在 [switch 语句][switch statements]中使用枚举, +如果你没有处理所有枚举值,你会收到警告: ```dart @@ -190,7 +232,11 @@ assert(Color.blue.index == 2); To get a list of all the enumerated values, use the enum's `values` constant. -要获取所有枚举值的列表,请使用枚举的 `values` 常量。 + + +如果你需要访问枚举值的名称, +例如从 `Color.blue` 获取 `'blue'`, +请使用 `.name` 属性: ```dart @@ -201,8 +247,9 @@ assert(colors[2] == Color.blue); You can use enums in [switch statements][], and you'll get a warning if you don't handle all of the enum's values: -你可以在 [switch 语句][switch statements]中使用枚举, -如果你没有处理所有枚举值,你会收到警告: + + +你可以像访问普通对象一样访问枚举值的成员: ```dart @@ -222,10 +269,6 @@ If you need to access the name of an enumerated value, such as `'blue'` from `Color.blue`, use the `.name` property: -如果你需要访问枚举值的名称, -例如从 `Color.blue` 获取 `'blue'`, -请使用 `.name` 属性: - ```dart print(Color.blue.name); // 'blue' @@ -234,8 +277,6 @@ print(Color.blue.name); // 'blue' You can access a member of an enum value like you would on a normal object: -你可以像访问普通对象一样访问枚举值的成员: - ```dart print(Vehicle.car.carbonFootprint); diff --git a/src/content/language/error-handling.md b/src/content/language/error-handling.md index 964c8c232..bfffa8454 100644 --- a/src/content/language/error-handling.md +++ b/src/content/language/error-handling.md @@ -1,20 +1,20 @@ --- # title: Error handling -title: 错误处理 +title: Error handling # description: Learn about handling errors and exceptions in Dart. -description: 了解如何在 Dart 中处理错误和异常。 +description: Learn about handling errors and exceptions in Dart. prevpage: url: /language/branches - # title: Branches - title: 分支 + title: Branches nextpage: url: /language/functions - # title: Functions - title: 函数 + title: Functions --- ## Exceptions + + ## 异常 Your Dart code can throw and catch exceptions. Exceptions are errors @@ -22,6 +22,8 @@ indicating that something unexpected happened. If the exception isn't caught, the [isolate][] that raised the exception is suspended, and typically the isolate and its program are terminated. + + 你的 Dart 代码可以抛出和捕获异常。异常是表示发生了意外情况的错误。 如果异常没有被捕获,引发异常的 [isolate][] 将被挂起, 通常 isolate 及其程序将被终止。 @@ -30,6 +32,8 @@ In contrast to Java, all of Dart's exceptions are unchecked exceptions. Methods don't declare which exceptions they might throw, and you aren't required to catch any exceptions. + + 与 Java 不同,Dart 的所有异常都是非检查异常。 方法不会声明它们可能抛出哪些异常, 你也不需要捕获任何异常。 @@ -39,6 +43,8 @@ types, as well as numerous predefined subtypes. You can, of course, define your own exceptions. However, Dart programs can throw any non-null object—not just Exception and Error objects—as an exception. + + Dart 提供了 [`Exception`][] 和 [`Error`][] 类型, 以及许多预定义的子类型。当然,你也可以定义自己的异常。 但是,Dart 程序可以将任何非空对象作为异常抛出—— @@ -46,10 +52,14 @@ Dart 提供了 [`Exception`][] 和 [`Error`][] 类型, ### Throw + + ### 抛出 Here's an example of throwing, or *raising*, an exception: + + 下面是抛出或*引发*异常的示例: @@ -59,6 +69,8 @@ throw FormatException('Expected at least 1 section'); You can also throw arbitrary objects: + + 你也可以抛出任意对象: @@ -69,32 +81,35 @@ throw 'Out of llamas!'; :::note Production-quality code usually throws types that implement [`Error`][] or [`Exception`][]. - -生产质量的代码通常会抛出实现了 [`Error`][] 或 [`Exception`][] 的类型。 ::: Because throwing an exception is an expression, you can throw exceptions in =\> statements, as well as anywhere else that allows expressions: -因为抛出异常是一个表达式,所以你可以在 =\> 语句中抛出异常, -也可以在任何其他允许表达式的地方抛出异常: + + +生产质量的代码通常会抛出实现了 [`Error`][] 或 [`Exception`][] 的类型。 +::: ```dart void distanceTo(Point other) => throw UnimplementedError(); ``` - ### Catch -### 捕获 + + +因为抛出异常是一个表达式,所以你可以在 =\> 语句中抛出异常, +也可以在任何其他允许表达式的地方抛出异常: Catching, or capturing, an exception stops the exception from propagating (unless you rethrow the exception). Catching an exception gives you a chance to handle it: -捕获异常可以阻止异常继续传播(除非你重新抛出异常)。 -捕获异常让你有机会处理它: + + +### 捕获 ```dart @@ -110,9 +125,10 @@ specify multiple catch clauses. The first catch clause that matches the thrown object's type handles the exception. If the catch clause does not specify a type, that clause can handle any type of thrown object: -要处理可能抛出多种类型异常的代码,你可以指定多个 catch 子句。 -第一个与抛出对象类型匹配的 catch 子句将处理该异常。 -如果 catch 子句没有指定类型,则该子句可以处理任何类型的抛出对象: + + +捕获异常可以阻止异常继续传播(除非你重新抛出异常)。 +捕获异常让你有机会处理它: ```dart @@ -134,16 +150,21 @@ As the preceding code shows, you can use either `on` or `catch` or both. Use `on` when you need to specify the exception type. Use `catch` when your exception handler needs the exception object. -如上面的代码所示,你可以使用 `on` 或 `catch`,或两者都用。 -当你需要指定异常类型时使用 `on`。 -当你的异常处理程序需要异常对象时使用 `catch`。 + + +要处理可能抛出多种类型异常的代码,你可以指定多个 catch 子句。 +第一个与抛出对象类型匹配的 catch 子句将处理该异常。 +如果 catch 子句没有指定类型,则该子句可以处理任何类型的抛出对象: You can specify one or two parameters to `catch()`. The first is the exception that was thrown, and the second is the stack trace (a [`StackTrace`][] object). -你可以为 `catch()` 指定一个或两个参数。 -第一个是抛出的异常,第二个是堆栈跟踪([`StackTrace`][] 对象)。 + + +如上面的代码所示,你可以使用 `on` 或 `catch`,或两者都用。 +当你需要指定异常类型时使用 `on`。 +当你的异常处理程序需要异常对象时使用 `catch`。 ```dart @@ -161,8 +182,10 @@ To partially handle an exception, while allowing it to propagate, use the `rethrow` keyword. -要部分处理异常,同时允许它继续传播, -请使用 `rethrow` 关键字。 + + +你可以为 `catch()` 指定一个或两个参数。 +第一个是抛出的异常,第二个是堆栈跟踪([`StackTrace`][] 对象)。 ```dart @@ -186,17 +209,27 @@ void main() { ``` + +要部分处理异常,同时允许它继续传播, +请使用 `rethrow` 关键字。 + ### Finally -To ensure that some code runs whether or not an exception is thrown, use -a `finally` clause. If no `catch` clause matches the exception, the -exception is propagated after the `finally` clause runs: + 为了确保无论是否抛出异常某些代码都会运行, 请使用 `finally` 子句。 如果没有 `catch` 子句匹配该异常, 异常将在 `finally` 子句运行后传播: +To ensure that some code runs whether or not an exception is thrown, use +a `finally` clause. If no `catch` clause matches the exception, the +exception is propagated after the `finally` clause runs: + + + +`finally` 子句在任何匹配的 `catch` 子句之后运行: + ```dart try { @@ -209,7 +242,9 @@ try { The `finally` clause runs after any matching `catch` clauses: -`finally` 子句在任何匹配的 `catch` 子句之后运行: + + +要了解更多信息,请查看[核心库异常文档](/libraries/dart-core#exceptions)。 ```dart @@ -225,20 +260,28 @@ try { To learn more, check out the [core library exception docs](/libraries/dart-core#exceptions). -要了解更多信息,请查看[核心库异常文档](/libraries/dart-core#exceptions)。 -## Assert ## 断言 -During development, use an assert -statement— `assert(, );` —to -disrupt normal execution if a boolean condition is false. +## Assert + + 在开发过程中,使用 assert 语句—— `assert(, );`—— 如果布尔条件为 false,则中断正常执行。 +During development, use an assert +statement— `assert(, );` —to +disrupt normal execution if a boolean condition is false. + + + +要为断言附加一条消息, +请将字符串作为 `assert` 的第二个参数添加 +(可选择带有[尾随逗号][trailing comma]): + ```dart // Make sure the variable has a non-null value. @@ -247,17 +290,31 @@ assert(text != null); // Make sure the value is less than 100. assert(number < 100); + + +`assert` 的第一个参数可以是任何解析为布尔值的表达式。 +如果表达式的值为 true,断言成功,执行继续。 +如果为 false,断言失败,并抛出异常([`AssertionError`][])。 + // Make sure this is an https URL. assert(urlString.startsWith('https')); ``` + + +断言究竟何时起作用? +这取决于你使用的工具和框架: + To attach a message to an assertion, add a string as the second argument to `assert` (optionally with a [trailing comma][]): -要为断言附加一条消息, -请将字符串作为 `assert` 的第二个参数添加 -(可选择带有[尾随逗号][trailing comma]): + + +* Flutter 在[调试模式][Flutter debug mode]下启用断言。 +* 仅用于开发的工具如 [`webdev serve`][] 通常默认启用断言。 +* 某些工具,如 [`dart run`][] 和 [`dart compile js`][], + 通过命令行标志支持断言:`--enable-asserts`。 ```dart @@ -273,33 +330,23 @@ is true, the assertion succeeds and execution continues. If it's false, the assertion fails and an exception (an [`AssertionError`][]) is thrown. -`assert` 的第一个参数可以是任何解析为布尔值的表达式。 -如果表达式的值为 true,断言成功,执行继续。 -如果为 false,断言失败,并抛出异常([`AssertionError`][])。 + + +在生产代码中,断言会被忽略, +`assert` 的参数不会被求值。 When exactly do assertions work? That depends on the tools and framework you're using: -断言究竟何时起作用? -这取决于你使用的工具和框架: - * Flutter enables assertions in [debug mode.][Flutter debug mode] * Development-only tools such as [`webdev serve`][] typically enable assertions by default. * Some tools, such as [`dart run`][] and [`dart compile js`][] support assertions through a command-line flag: `--enable-asserts`. -* Flutter 在[调试模式][Flutter debug mode]下启用断言。 -* 仅用于开发的工具如 [`webdev serve`][] 通常默认启用断言。 -* 某些工具,如 [`dart run`][] 和 [`dart compile js`][], - 通过命令行标志支持断言:`--enable-asserts`。 - In production code, assertions are ignored, and the arguments to `assert` aren't evaluated. -在生产代码中,断言会被忽略, -`assert` 的参数不会被求值。 - [trailing comma]: /language/collections#trailing-comma [`AssertionError`]: {{site.dart-api}}/dart-core/AssertionError-class.html [Flutter debug mode]: {{site.flutter-docs}}/testing/debugging#debug-mode-assertions diff --git a/src/content/language/extend.md b/src/content/language/extend.md index 001ca1d1b..8ae39deb5 100644 --- a/src/content/language/extend.md +++ b/src/content/language/extend.md @@ -1,21 +1,21 @@ --- # title: Extend a class -title: 扩展一个类 +title: Extend a class # description: Learn how to create subclasses from a superclass. -description: 了解如何从超类创建子类。 +description: Learn how to create subclasses from a superclass. prevpage: url: /language/methods - # title: Methods - title: 方法 + title: Methods nextpage: url: /language/mixins - # title: Mixins - title: Mixin + title: Mixins --- Use `extends` to create a subclass, and `super` to refer to the superclass: + + 使用 `extends` 来创建子类,使用 `super` 来引用超类: @@ -39,24 +39,34 @@ class SmartTelevision [!extends!] Television { } ``` -For another usage of `extends`, see the discussion of -[parameterized types][] on the Generics page. + 关于 `extends` 的另一种用法,请参阅泛型页面中 [参数化类型][parameterized types]的讨论。 -## Overriding members +For another usage of `extends`, see the discussion of +[parameterized types][] on the Generics page. + + ## 重写成员 +## Overriding members + + + +子类可以重写实例方法(包括[运算符][operators])、 +getter 和 setter。 +你可以使用 `@override` 注解来表明你是有意重写一个成员: + Subclasses can override instance methods (including [operators][]), getters, and setters. You can use the `@override` annotation to indicate that you are intentionally overriding a member: -子类可以重写实例方法(包括[运算符][operators])、 -getter 和 setter。 -你可以使用 `@override` 注解来表明你是有意重写一个成员: + + +重写方法的声明必须在以下几个方面与其重写的方法(或多个方法)匹配: ```dart @@ -76,10 +86,31 @@ class SmartTelevision extends Television { } ``` + + +* 返回类型必须与被重写方法的返回类型相同(或是其子类型)。 +* 参数类型必须与被重写方法的参数类型相同(或是其超类型)。 + 在前面的示例中,`SmartTelevision` 的 `contrast` setter + 将参数类型从 `int` 更改为其超类型 `num`。 +* 如果被重写的方法接受 _n_ 个位置参数, + 那么重写方法也必须接受 _n_ 个位置参数。 +* [泛型方法][generic method]不能重写非泛型方法, + 非泛型方法也不能重写泛型方法。 + An overriding method declaration must match the method (or methods) that it overrides in several ways: -重写方法的声明必须在以下几个方面与其重写的方法(或多个方法)匹配: + + +有时你可能想缩小方法参数或实例变量的类型范围。 +这违反了正常规则, +类似于向下转型,可能在运行时导致类型错误。 +不过,如果代码能保证不会发生类型错误, +缩小类型范围仍然是可行的。 +在这种情况下,你可以在参数声明中使用 +[`covariant` 关键字](/language/type-system#covariant-keyword)。 +有关详细信息,请参阅 +[Dart 语言规范][Dart language specification]。 * The return type must be the same type as (or a subtype of) the overridden method's return type. @@ -92,14 +123,12 @@ the method (or methods) that it overrides in several ways: * A [generic method][] can't override a non-generic one, and a non-generic method can't override a generic one. -* 返回类型必须与被重写方法的返回类型相同(或是其子类型)。 -* 参数类型必须与被重写方法的参数类型相同(或是其超类型)。 - 在前面的示例中,`SmartTelevision` 的 `contrast` setter - 将参数类型从 `int` 更改为其超类型 `num`。 -* 如果被重写的方法接受 _n_ 个位置参数, - 那么重写方法也必须接受 _n_ 个位置参数。 -* [泛型方法][generic method]不能重写非泛型方法, - 非泛型方法也不能重写泛型方法。 + + +如果你重写了 `==`,你也应该重写 Object 的 `hashCode` getter。 +有关重写 `==` 和 `hashCode` 的示例,请查看 +[实现 map 键](/libraries/dart-core#implementing-map-keys)。 +::: Sometimes you might want to narrow the type of a method parameter or an instance variable. @@ -113,33 +142,29 @@ in a parameter declaration. For details, see the [Dart language specification][]. -有时你可能想缩小方法参数或实例变量的类型范围。 -这违反了正常规则, -类似于向下转型,可能在运行时导致类型错误。 -不过,如果代码能保证不会发生类型错误, -缩小类型范围仍然是可行的。 -在这种情况下,你可以在参数声明中使用 -[`covariant` 关键字](/language/type-system#covariant-keyword)。 -有关详细信息,请参阅 -[Dart 语言规范][Dart language specification]。 + + +要在代码尝试使用不存在的方法或实例变量时进行检测或做出反应, +你可以重写 `noSuchMethod()`: :::warning If you override `==`, you should also override Object's `hashCode` getter. For an example of overriding `==` and `hashCode`, check out [Implementing map keys](/libraries/dart-core#implementing-map-keys). - -如果你重写了 `==`,你也应该重写 Object 的 `hashCode` getter。 -有关重写 `==` 和 `hashCode` 的示例,请查看 -[实现 map 键](/libraries/dart-core#implementing-map-keys)。 ::: ## noSuchMethod() + + +除非满足以下条件**之一**,否则你**无法调用**未实现的方法: + To detect or react whenever code attempts to use a non-existent method or instance variable, you can override `noSuchMethod()`: -要在代码尝试使用不存在的方法或实例变量时进行检测或做出反应, -你可以重写 `noSuchMethod()`: + + +* 接收者的静态类型为 `dynamic`。 ```dart @@ -159,27 +184,27 @@ class A { You **can't invoke** an unimplemented method unless **one** of the following is true: -除非满足以下条件**之一**,否则你**无法调用**未实现的方法: + + +* 接收者的静态类型定义了该未实现的方法(抽象方法也可以), +并且接收者的动态类型有一个与 `Object` 类中不同的 +`noSuchMethod()` 实现。 * The receiver has the static type `dynamic`. -* 接收者的静态类型为 `dynamic`。 + + +有关更多信息,请参阅非正式的 +[noSuchMethod 转发规范]({{site.repo.dart.lang}}/blob/main/archive/feature-specifications/nosuchmethod-forwarding.md)。 * The receiver has a static type that defines the unimplemented method (abstract is OK), and the dynamic type of the receiver has an implementation of `noSuchMethod()` that's different from the one in class `Object`. -* 接收者的静态类型定义了该未实现的方法(抽象方法也可以), -并且接收者的动态类型有一个与 `Object` 类中不同的 -`noSuchMethod()` 实现。 - For more information, see the informal [noSuchMethod forwarding specification.]({{site.repo.dart.lang}}/blob/main/archive/feature-specifications/nosuchmethod-forwarding.md) -有关更多信息,请参阅非正式的 -[noSuchMethod 转发规范]({{site.repo.dart.lang}}/blob/main/archive/feature-specifications/nosuchmethod-forwarding.md)。 - [parameterized types]: /language/generics#restricting-the-parameterized-type [operators]: /language/methods#operators [generic method]: /language/generics#using-generic-methods diff --git a/src/content/language/generics.md b/src/content/language/generics.md index 46e7fae9f..66686e496 100644 --- a/src/content/language/generics.md +++ b/src/content/language/generics.md @@ -1,16 +1,14 @@ --- # title: Generics -title: 泛型 +title: Generics # description: Learn about generic types in Dart. -description: 了解 Dart 中的泛型类型。 +description: Learn about generic types in Dart. prevpage: url: /language/collections - # title: Collections - title: 集合 + title: Collections nextpage: url: /language/typedefs - # title: Typedefs - title: 类型别名 + title: Typedefs --- @@ -22,6 +20,8 @@ type is actually `List`. The \<...\> notation marks List as a parameters. [By convention][], most type variables have single-letter names, such as E, T, S, K, and V. + + 如果你查看基本数组类型 [`List`][] 的 API 文档, 你会看到该类型实际上是 `List`。 \<...\> 标记将 List 标记为*泛型*(或*参数化*)类型—— @@ -31,16 +31,22 @@ such as E, T, S, K, and V. ## Why use generics? + + ## 为什么使用泛型? Generics are often required for type safety, but they have more benefits than just allowing your code to run: + + 泛型通常是类型安全所必需的,但它们的好处不仅仅是让你的代码运行: * Properly specifying generic types results in better generated code. * You can use generics to reduce code duplication. + + * 正确指定泛型类型可以生成更好的代码。 * 你可以使用泛型来减少代码重复。 @@ -49,6 +55,8 @@ declare it as `List` (read that as "list of string"). That way you, your fellow programmers, and your tools can detect that assigning a non-string to the list is probably a mistake. Here's an example: + + 如果你打算让一个列表只包含字符串, 你可以将它声明为 `List`(读作"字符串列表")。 这样你、你的同事程序员和你的工具可以检测到 @@ -66,6 +74,8 @@ many types, while still taking advantage of static analysis. For example, say you create an interface for caching an object: + + 使用泛型的另一个原因是减少代码重复。 泛型让你可以在多种类型之间共享单个接口和实现, 同时仍然利用静态分析的优势。 @@ -82,6 +92,8 @@ abstract class ObjectCache { You discover that you want a string-specific version of this interface, so you create another interface: + + 你发现你想要这个接口的字符串特定版本, 所以你创建另一个接口: @@ -96,11 +108,15 @@ abstract class StringCache { Later, you decide you want a number-specific version of this interface... You get the idea. + + 后来,你决定要一个数字特定版本的接口……你明白了。 Generic types can save you the trouble of creating all these interfaces. Instead, you can create a single interface that takes a type parameter: + + 泛型类型可以省去创建所有这些接口的麻烦。 相反,你可以创建一个带有类型参数的单一接口: @@ -115,12 +131,15 @@ abstract class Cache { In this code, T is the stand-in type. It's a placeholder that you can think of as a type that a developer will define later. + + 在这段代码中,T 是替代类型。 它是一个占位符,你可以将其视为开发者稍后将定义的类型。 - ## Using collection literals + + ## 使用集合字面量 List, set, and map literals can be parameterized. Parameterized literals are @@ -129,6 +148,8 @@ just like the literals you've already seen, except that you add <keyType, valueType> (for maps) before the opening bracket. Here is an example of using typed literals: + + List、set 和 map 字面量可以参数化。参数化字面量 与你已经看到的字面量一样,只是你在开括号之前添加了 <type>(对于 list 和 set)或 @@ -146,14 +167,17 @@ var pages = { }; ``` - ## Using parameterized types with constructors + + ## 在构造函数中使用参数化类型 To specify one or more types when using a constructor, put the types in angle brackets (`<...>`) just after the class name. For example: + + 要在使用构造函数时指定一个或多个类型, 请将类型放在类名后面的尖括号(`<...>`)中。例如: @@ -165,6 +189,8 @@ var nameSet = Set.of(names); The following code creates a `SplayTreeMap` that has integer keys and values of type `View`: + + 以下代码创建一个具有整数键和 `View` 类型值的 `SplayTreeMap`: @@ -172,15 +198,18 @@ integer keys and values of type `View`: var views = SplayTreeMap(); ``` - ## Generic collections and the types they contain + + ## 泛型集合及其包含的类型 Dart generic types are *reified*, which means that they carry their type information around at runtime. For example, you can test the type of a collection: + + Dart 泛型类型是*具体化的*,这意味着它们在运行时 携带其类型信息。例如,你可以测试集合的类型: @@ -195,6 +224,11 @@ print(names is List); // true In contrast, generics in Java use *erasure*, which means that generic type parameters are removed at runtime. In Java, you can test whether an object is a List, but you can't test whether it's a `List`. +::: + +## Restricting the parameterized type + + 相比之下,Java 中的泛型使用*擦除*, 这意味着泛型类型参数在运行时被移除。 @@ -202,30 +236,27 @@ an object is a List, but you can't test whether it's a `List`. 但你不能测试它是否是 `List`。 ::: - -## Restricting the parameterized type - -## 限制参数化类型 - When implementing a generic type, you might want to limit the types that can be provided as arguments, so that the argument must be a subtype of a particular type. This restriction is called a bound. You can do this using `extends`. -在实现泛型类型时, -你可能想要限制可以作为参数提供的类型, -以便参数必须是特定类型的子类型。 -这种限制称为边界。 -你可以使用 `extends` 来实现这一点。 + + +## 限制参数化类型 A common use case is ensuring that a type is non-nullable by making it a subtype of `Object` (instead of the default, [`Object?`][top-and-bottom]). -一个常见的用例是通过使类型成为 `Object` 的子类型 -(而不是默认的 [`Object?`][top-and-bottom]) -来确保类型是非空的。 + + +在实现泛型类型时, +你可能想要限制可以作为参数提供的类型, +以便参数必须是特定类型的子类型。 +这种限制称为边界。 +你可以使用 `extends` 来实现这一点。 ```dart @@ -238,9 +269,11 @@ You can use `extends` with other types besides `Object`. Here's an example of extending `SomeBaseClass`, so that members of `SomeBaseClass` can be called on objects of type `T`: -你可以对 `Object` 以外的其他类型使用 `extends`。 -下面是扩展 `SomeBaseClass` 的示例, -这样就可以在类型为 `T` 的对象上调用 `SomeBaseClass` 的成员: + + +一个常见的用例是通过使类型成为 `Object` 的子类型 +(而不是默认的 [`Object?`][top-and-bottom]) +来确保类型是非空的。 ```dart @@ -254,8 +287,16 @@ class Extender extends SomeBaseClass { } ``` + + +你可以对 `Object` 以外的其他类型使用 `extends`。 +下面是扩展 `SomeBaseClass` 的示例, +这样就可以在类型为 `T` 的对象上调用 `SomeBaseClass` 的成员: + It's OK to use `SomeBaseClass` or any of its subtypes as the generic argument: + + 可以使用 `SomeBaseClass` 或其任何子类型作为泛型参数: @@ -266,6 +307,8 @@ var extenderFoo = [!Foo!](); It's also OK to specify no generic argument: + + 也可以不指定泛型参数: @@ -276,6 +319,8 @@ print(foo); // Instance of 'Foo' Specifying any non-`SomeBaseClass` type results in an error: + + 指定任何非 `SomeBaseClass` 类型会导致错误: ```dart tag=fails-sa @@ -284,12 +329,16 @@ var foo = [!Foo!](); ### Self-referential type parameter restrictions (F-bounds) {:#f-bounds} + + ### 自引用类型参数限制(F-边界){:#f-bounds} When using bounds to restrict parameter types, you can refer the bound back to the type parameter itself. This creates a self-referential constraint, or F-bound. For example: + + 当使用边界来限制参数类型时,你可以将边界 引用回类型参数本身。这创建了一个自引用约束, 或 F-边界。例如: @@ -303,27 +352,44 @@ abstract interface class Comparable { int compareAndOffset>(T t1, T t2) => t1.compareTo(t2) + 1; + + +F-边界 `T extends Comparable` 表示 `T` 必须与自身可比较。 +因此,`A` 只能与相同类型的其他实例进行比较。 + class A implements Comparable { @override int compareTo(A other) => /*...implementation...*/ 0; } + + +## 使用泛型方法 + int useIt = compareAndOffset(A(), A()); ``` + + +方法和函数也允许类型参数: + The F-bound `T extends Comparable` means `T` must be comparable to itself. So, `A` can only be compared to other instances of the same type. -F-边界 `T extends Comparable` 表示 `T` 必须与自身可比较。 -因此,`A` 只能与相同类型的其他实例进行比较。 + + +这里 `first` 上的泛型类型参数(``) +允许你在多个地方使用类型参数 `T`: ## Using generic methods -## 使用泛型方法 -Methods and functions also allow type arguments: -方法和函数也允许类型参数: +* 在函数的返回类型中(`T`)。 +* 在参数的类型中(`List`)。 +* 在局部变量的类型中(`T tmp`)。 + +Methods and functions also allow type arguments: @@ -340,17 +406,10 @@ Methods and functions also allow type arguments: Here the generic type parameter on `first` (``) allows you to use the type argument `T` in several places: -这里 `first` 上的泛型类型参数(``) -允许你在多个地方使用类型参数 `T`: - * In the function's return type (`T`). * In the type of an argument (`List`). * In the type of a local variable (`T tmp`). -* 在函数的返回类型中(`T`)。 -* 在参数的类型中(`List`)。 -* 在局部变量的类型中(`T tmp`)。 - [`List`]: {{site.dart-api}}/dart-core/List-class.html [By convention]: /effective-dart/design#do-follow-existing-mnemonic-conventions-when-naming-type-parameters [top-and-bottom]: /null-safety/understanding-null-safety#top-and-bottom diff --git a/src/content/language/keywords.md b/src/content/language/keywords.md index e7934019e..c26f4b0ae 100644 --- a/src/content/language/keywords.md +++ b/src/content/language/keywords.md @@ -1,8 +1,8 @@ --- # title: Keywords -title: 关键字 +title: Keywords # description: Keywords in Dart. -description: Dart 中的关键字。 +description: Keywords in Dart. showToc: false --- @@ -17,6 +17,8 @@ Even when allowed, using keywords as identifiers can confuse other developers reading your code and should be avoided. To learn more about identifier usage, click on the term. + + 下表列出了 Dart 语言保留的单词。 这些单词不能用作标识符,除非另有说明。 即使在允许的情况下,使用关键字作为标识符也会让其他 @@ -38,6 +40,8 @@ To learn more about identifier usage, click on the term. {{ckw}} This keyword can be used as an identifier depending on **context**. + + {{ckw}} 此关键字可以根据**上下文**用作标识符。 {{bii}} This keyword can't be used as the name of a type @@ -45,6 +49,8 @@ To learn more about identifier usage, click on the term. the name of an extension, or as an import prefix. It can be used as an identifier in all other circumstances. + + {{bii}} 此关键字不能用作类型的名称 (类、mixin、枚举、扩展类型或类型别名), 扩展的名称,或作为导入前缀。 @@ -52,4 +58,6 @@ To learn more about identifier usage, click on the term. {{unr}} This keyword can be used as an identifier without restriction. + + {{unr}} 此关键字可以无限制地用作标识符。 diff --git a/src/content/language/libraries.md b/src/content/language/libraries.md index 1b8ca5af2..930f2ae01 100644 --- a/src/content/language/libraries.md +++ b/src/content/language/libraries.md @@ -1,18 +1,16 @@ --- # title: Libraries & imports -title: 库和导入 +title: Libraries & imports # shortTitle: Libraries -shortTitle: 库 +shortTitle: Libraries # description: Guidance on importing and implementing libraries. -description: 关于导入和实现库的指导。 +description: Guidance on importing and implementing libraries. prevpage: url: /language/metadata - # title: Metadata - title: 元数据 + title: Metadata nextpage: url: /language/classes - # title: Classes - title: 类 + title: Classes --- The `import` and `library` directives can help you create a @@ -21,6 +19,8 @@ are a unit of privacy: identifiers that start with an underscore (`_`) are visible only inside the library. *Every Dart file (plus its parts) is a [library][]*, even if it doesn't use a [`library`](#library-directive) directive. + + `import` 和 `library` 指令可以帮助你创建一个模块化和可共享的代码库。 库不仅提供 API,还是一个隐私单元: 以下划线(`_`)开头的标识符只在库内部可见。 @@ -29,6 +29,8 @@ are visible only inside the library. *Every Dart file (plus its parts) is a Libraries can be distributed using [packages](/tools/pub/packages). + + 库可以使用 [package](/tools/pub/packages) 来分发。 Dart uses underscores instead of access modifier keywords @@ -40,6 +42,8 @@ provides a straightforward configuration mechanism, helps enable an efficient implementation of [dynamic access][], and improves tree shaking (dead code elimination). + + Dart 使用下划线而不是像 `public`、`protected` 或 `private` 这样的访问修饰符关键字。 虽然其他语言的访问修饰符关键字提供更细粒度的控制, @@ -52,16 +56,22 @@ Dart 使用下划线而不是像 `public`、`protected` 或 `private` ## Using libraries + + ## 使用库 Use `import` to specify how a namespace from one library is used in the scope of another library. + + 使用 `import` 来指定如何在另一个库的作用域中使用一个库的命名空间。 For example, Dart web apps generally use the [`dart:js_interop`][] library, which they can import like this: + + 例如,Dart Web 应用通常使用 [`dart:js_interop`][] 库, 可以像这样导入它: @@ -77,6 +87,8 @@ For other libraries, you can use a file system path or the `package:` scheme. The `package:` scheme specifies libraries provided by a package manager such as the pub tool. For example: + + `import` 唯一必需的参数是指定库的 URI。 对于内置库,URI 具有特殊的 `dart:` 方案。 对于其他库,你可以使用文件系统路径或 `package:` 方案。 @@ -90,24 +102,24 @@ import 'package:test/test.dart'; :::note *URI* stands for uniform resource identifier. *URLs* (uniform resource locators) are a common kind of URI. - -*URI* 代表统一资源标识符。 -*URL*(统一资源定位符)是一种常见的 URI。 ::: ### Specifying a library prefix -### 指定库前缀 + + +*URI* 代表统一资源标识符。 +*URL*(统一资源定位符)是一种常见的 URI。 +::: If you import two libraries that have conflicting identifiers, then you can specify a prefix for one or both libraries. For example, if library1 and library2 both have an Element class, then you might have code like this: -如果你导入两个具有冲突标识符的库, -那么你可以为一个或两个库指定前缀。 -例如,如果 library1 和 library2 都有一个 Element 类, -那么你可能会有这样的代码: + + +### 指定库前缀 ```dart @@ -117,26 +129,43 @@ import 'package:lib2/lib2.dart' as lib2; // Uses Element from lib1. Element element1 = Element(); + + +如果你导入两个具有冲突标识符的库, +那么你可以为一个或两个库指定前缀。 +例如,如果 library1 和 library2 都有一个 Element 类, +那么你可能会有这样的代码: + // Uses Element from lib2. lib2.Element element2 = lib2.Element(); ``` -Import prefixes with the [wildcard][] name `_` are non-binding, -but will provide access to the non-private extensions in that library. + 使用[通配符][wildcard]名称 `_` 的导入前缀是非绑定的, 但将提供对该库中非私有扩展的访问。 +Import prefixes with the [wildcard][] name `_` are non-binding, +but will provide access to the non-private extensions in that library. + + + +### 只导入库的一部分 + [wildcard]: /language/variables#wildcard-variables ### Importing only part of a library -### 只导入库的一部分 + + +如果你只想使用库的一部分,可以选择性地导入库。例如: If you want to use only part of a library, you can selectively import the library. For example: -如果你只想使用库的一部分,可以选择性地导入库。例如: + + +#### 延迟加载库 {:#lazily-loading-a-library} ```dart @@ -147,47 +176,65 @@ import 'package:lib1/lib1.dart' show foo; import 'package:lib2/lib2.dart' hide foo; ``` + + +*延迟加载*(也称为*懒加载*)允许 Web 应用在需要时按需加载库。 +当你想要满足以下一个或多个需求时,请使用延迟加载。 + #### Lazily loading a library {:#lazily-loading-a-library} -#### 延迟加载库 {:#lazily-loading-a-library} + + +* 减少 Web 应用的初始启动时间。 +* 执行 A/B 测试——例如,尝试算法的替代实现。 +* 加载很少使用的功能,例如可选的屏幕和对话框。 *Deferred loading* (also called *lazy loading*) allows a web app to load a library on demand, if and when the library is needed. Use deferred loading when you want to meet one or more of the following needs. -*延迟加载*(也称为*懒加载*)允许 Web 应用在需要时按需加载库。 -当你想要满足以下一个或多个需求时,请使用延迟加载。 + + +这并不意味着 Dart 在启动时加载所有延迟组件。 +Web 应用可以在需要时通过网络下载延迟组件。 * Reduce a web app's initial startup time. * Perform A/B testing—trying out alternative implementations of an algorithm, for example. * Load rarely used functionality, such as optional screens and dialogs. -* 减少 Web 应用的初始启动时间。 -* 执行 A/B 测试——例如,尝试算法的替代实现。 -* 加载很少使用的功能,例如可选的屏幕和对话框。 + + +`dart` 工具不支持 Web 以外的目标的延迟加载。 +如果你正在构建 Flutter 应用, +请参阅 Flutter 指南中关于[延迟组件][flutter-deferred]的延迟加载实现。 That doesn't mean Dart loads all the deferred components at start time. The web app can download deferred components via the web when needed. -这并不意味着 Dart 在启动时加载所有延迟组件。 -Web 应用可以在需要时通过网络下载延迟组件。 + + +要延迟加载库,首先使用 `deferred as` 导入它。 The `dart` tool doesn't support deferred loading for targets other than web. If you're building a Flutter app, consult its implementation of deferred loading in the Flutter guide on [deferred components][flutter-deferred]. -`dart` 工具不支持 Web 以外的目标的延迟加载。 -如果你正在构建 Flutter 应用, -请参阅 Flutter 指南中关于[延迟组件][flutter-deferred]的延迟加载实现。 + + +当你需要该库时,使用库的标识符调用 `loadLibrary()`。 [flutter-deferred]: {{site.flutter-docs}}/perf/deferred-components To lazily load a library, first import it using `deferred as`. -要延迟加载库,首先使用 `deferred as` 导入它。 + + +在前面的代码中,`await` 关键字暂停执行,直到库加载完成。 +有关 `async` 和 `await` 的更多信息, +请查看[异步编程](/language/async)。 ```dart @@ -197,7 +244,10 @@ import 'package:greetings/hello.dart' deferred as hello; When you need the library, invoke `loadLibrary()` using the library's identifier. -当你需要该库时,使用库的标识符调用 `loadLibrary()`。 + + +你可以在一个库上多次调用 `loadLibrary()` 而不会出现问题。 +该库只会加载一次。 ```dart @@ -212,19 +262,28 @@ the `await` keyword pauses execution until the library is loaded. For more information about `async` and `await`, check out [asynchronous programming](/language/async). -在前面的代码中,`await` 关键字暂停执行,直到库加载完成。 -有关 `async` 和 `await` 的更多信息, -请查看[异步编程](/language/async)。 + + +使用延迟加载时,请记住以下几点: You can invoke `loadLibrary()` multiple times on a library without problems. The library is loaded only once. -你可以在一个库上多次调用 `loadLibrary()` 而不会出现问题。 -该库只会加载一次。 + + +* 延迟库的常量在导入文件中不是常量。 + 请记住,这些常量在延迟库加载之前不存在。 +* 你不能在导入文件中使用延迟库中的类型。 + 相反,考虑将接口类型移动到延迟库和导入文件都导入的库中。 +* Dart 会隐式地将 `loadLibrary()` 插入到你使用 + deferred as namespace 定义的命名空间中。 + `loadLibrary()` 函数返回一个 [`Future`](/libraries/dart-async#future)。 Keep in mind the following when you use deferred loading: -使用延迟加载时,请记住以下几点: + + +### `library` 指令 {:#library-directive} * A deferred library's constants aren't constants in the importing file. Remember, these constants don't exist until the deferred library is loaded. @@ -236,23 +295,24 @@ Keep in mind the following when you use deferred loading: The `loadLibrary()` function returns a [`Future`](/libraries/dart-async#future). -* 延迟库的常量在导入文件中不是常量。 - 请记住,这些常量在延迟库加载之前不存在。 -* 你不能在导入文件中使用延迟库中的类型。 - 相反,考虑将接口类型移动到延迟库和导入文件都导入的库中。 -* Dart 会隐式地将 `loadLibrary()` 插入到你使用 - deferred as namespace 定义的命名空间中。 - `loadLibrary()` 函数返回一个 [`Future`](/libraries/dart-async#future)。 + + +要指定库级别的[文档注释][doc comments]或[元数据注解][metadata annotations], +请将它们附加到文件开头的 `library` 声明上。 ### The `library` directive {:#library-directive} -### `library` 指令 {:#library-directive} + + +## 实现库 To specify library-level [doc comments][] or [metadata annotations][], attach them to a `library` declaration at the start of the file. -要指定库级别的[文档注释][doc comments]或[元数据注解][metadata annotations], -请将它们附加到文件开头的 `library` 声明上。 + + +有关如何实现包的建议,请参阅 +[创建包](/tools/pub/create-packages),包括: ```dart @@ -263,26 +323,23 @@ library; ## Implementing libraries -## 实现库 + + +* 如何组织库源代码。 +* 如何使用 `export` 指令。 +* 何时使用 `part` 指令。 +* 如何使用条件导入和导出来实现支持多平台的库。 See [Create Packages](/tools/pub/create-packages) for advice on how to implement a package, including: -有关如何实现包的建议,请参阅 -[创建包](/tools/pub/create-packages),包括: - * How to organize library source code. * How to use the `export` directive. * When to use the `part` directive. * How to use conditional imports and exports to implement a library that supports multiple platforms. -* 如何组织库源代码。 -* 如何使用 `export` 指令。 -* 何时使用 `part` 指令。 -* 如何使用条件导入和导出来实现支持多平台的库。 - [`dart:js_interop`]: {{site.dart-api}}/dart-js_interop/dart-js_interop-library.html [doc comments]: /effective-dart/documentation#consider-writing-a-library-level-doc-comment [metadata annotations]: /language/metadata diff --git a/src/content/language/loops.md b/src/content/language/loops.md index fb14f6a6e..3dbb19f1e 100644 --- a/src/content/language/loops.md +++ b/src/content/language/loops.md @@ -1,47 +1,57 @@ --- -# title: Loops -title: 循环 +# title: Loops +title: Loops # description: Learn how to use loops to control the flow of your Dart code. -description: 了解如何使用循环来控制 Dart 代码的流程。 +description: Learn how to use loops to control the flow of your Dart code. prevpage: url: /language/pattern-types - # title: Pattern types - title: 模式类型 + title: Pattern types nextpage: url: /language/branches - # title: Branches - title: 分支 + title: Branches --- This page shows how you can control the flow of your Dart code using loops and supporting statements: + + 本页面展示如何使用循环和辅助语句来控制 Dart 代码的流程: - `for` loops - `while` and `do while` loops - `break` and `continue` + + - `for` 循环 - `while` 和 `do while` 循环 - `break` 和 `continue` You can also manipulate control flow in Dart using: + + 你还可以使用以下方式在 Dart 中控制流程: - [Branching][], like `if` and `switch` - [Exceptions][], like `try`, `catch`, and `throw` + + - [分支][Branching],如 `if` 和 `switch` - [异常][Exceptions],如 `try`、`catch` 和 `throw` ## For loops + + ## For 循环 You can iterate with the standard `for` loop. For example: + + 你可以使用标准的 `for` 循环进行迭代。例如: @@ -55,6 +65,8 @@ for (var i = 0; i < 5; i++) { Closures inside of Dart's `for` loops capture the _value_ of the index. This avoids a common pitfall found in JavaScript. For example, consider: + + Dart `for` 循环内的闭包会捕获索引的_值_。 这避免了 JavaScript 中常见的陷阱。例如,考虑: @@ -70,20 +82,32 @@ for (final c in callbacks) { } ``` -The output is `0` and then `1`, as expected. In contrast, the example -would print `2` and then `2` in JavaScript. + 输出如预期的那样是 `0` 然后是 `1`。 相比之下,该示例在 JavaScript 中会打印 `2` 然后是 `2`。 -Sometimes you might not need to know the current iteration counter -when iterating over an [`Iterable`][] type, like `List` or `Set`. -In that case, use the `for-in` loop for cleaner code: +The output is `0` and then `1`, as expected. In contrast, the example +would print `2` and then `2` in JavaScript. + + 有时在遍历 [`Iterable`][] 类型(如 `List` 或 `Set`)时, 你可能不需要知道当前的迭代计数器。 在这种情况下,使用 `for-in` 循环可以使代码更简洁: +Sometimes you might not need to know the current iteration counter +when iterating over an [`Iterable`][] type, like `List` or `Set`. +In that case, use the `for-in` loop for cleaner code: + + + +在前面的示例循环中,`candidate` 在循环体内定义, +并设置为每次引用 `candidates` 中的一个值。 +`candidate` 是一个局部[变量][variable]。 +在循环体内重新赋值 `candidate` 只会更改该次迭代的局部变量, +不会修改原始的 `candidates` 可迭代对象。 + ```dart for (var candidate in candidates) { @@ -99,18 +123,20 @@ Reassigning `candidate` inside the loop body only changes the local variable for that iteration and doesn't modify the original `candidates` iterable. -在前面的示例循环中,`candidate` 在循环体内定义, -并设置为每次引用 `candidates` 中的一个值。 -`candidate` 是一个局部[变量][variable]。 -在循环体内重新赋值 `candidate` 只会更改该次迭代的局部变量, -不会修改原始的 `candidates` 可迭代对象。 -To process the values obtained from the iterable, -you can also use a [pattern][] in a `for-in` loop: 要处理从可迭代对象获取的值, 你也可以在 `for-in` 循环中使用[模式][pattern]: +To process the values obtained from the iterable, +you can also use a [pattern][] in a `for-in` loop: + + + +要练习使用 `for-in`,请参阅 +[可迭代集合教程](/libraries/collections/iterables)。 +::: + ```dart for (final Candidate(:name, :yearsExperience) in candidates) { @@ -121,13 +147,12 @@ for (final Candidate(:name, :yearsExperience) in candidates) { :::tip To practice using `for-in`, follow the [Iterable collections tutorial](/libraries/collections/iterables). - -要练习使用 `for-in`,请参阅 -[可迭代集合教程](/libraries/collections/iterables)。 ::: Iterable classes also have a [forEach()][] method as another option: + + 可迭代类还有一个 [forEach()][] 方法作为另一种选择: @@ -140,10 +165,14 @@ collection.forEach(print); // 1 2 3 ## While and do-while + + ## While 和 do-while A `while` loop evaluates the condition before the loop: + + `while` 循环在循环之前评估条件: @@ -155,6 +184,8 @@ while (!isDone()) { A `do`-`while` loop evaluates the condition *after* the loop: + + `do`-`while` 循环在循环*之后*评估条件: @@ -164,13 +195,16 @@ do { } while (!atEndOfPage()); ``` - ## Break and continue + + ## Break 和 continue Use `break` to stop looping: + + 使用 `break` 停止循环: @@ -183,6 +217,8 @@ while (true) { Use `continue` to skip to the next loop iteration: + + 使用 `continue` 跳到下一次循环迭代: @@ -199,6 +235,8 @@ for (int i = 0; i < candidates.length; i++) { If you're using an [`Iterable`][] such as a list or set, how you write the previous example might differ: + + 如果你使用的是 [`Iterable`][](如列表或集合), 编写前面示例的方式可能会有所不同: @@ -211,6 +249,8 @@ candidates ## Labels + + ## 标签 A label is an identifier followed by a colon (`labelName:`) @@ -219,6 +259,8 @@ _labeled statement_. Loops and switch cases are often used as labeled statements. A labeled statement can be referenced later in a `break` or `continue` statement as follows: + + 标签是一个后跟冒号(`labelName:`)的标识符, 你可以将其放在语句之前以创建_带标签的语句_。 循环和 switch case 通常用作带标签的语句。 @@ -229,6 +271,8 @@ in a `break` or `continue` statement as follows: This is useful for breaking out of a specific outer loop when you're within a nested loop. + + * `break labelName;` 终止带标签语句的执行。 当你在嵌套循环中时,这对于跳出特定的外部循环很有用。 @@ -237,6 +281,8 @@ in a `break` or `continue` statement as follows: Skips the rest of the current iteration of the labeled statement loop and continues with the next iteration. + + * `continue labelName;` 跳过带标签语句循环当前迭代的剩余部分, 并继续下一次迭代。 @@ -246,17 +292,23 @@ loops and switch cases and allow you to specify which statement to break out of or continue, rather than affecting the innermost loop by default. + + 标签用于管理控制流。它们通常与循环和 switch case 一起使用, 允许你指定要跳出或继续的语句, 而不是默认影响最内层的循环。 ### Labels in for loop using `break` {:.no_toc} + + ### 在 for 循环中使用 `break` 的标签 {:.no_toc} The following code demonstrates the usage of a label called `outerLoop` in a `for` loop with a `break` statement: + + 以下代码演示了在带有 `break` 语句的 `for` 循环中 使用名为 `outerLoop` 的标签: @@ -277,6 +329,8 @@ print('outerLoop exited'); In the previous example, when `i == 2` and `j == 2`, the `break outerLoop;` statement stops both inner and outer loops. As a result, the output is: + + 在前面的示例中,当 `i == 2` 且 `j == 2` 时, `break outerLoop;` 语句会停止内部和外部循环。因此,输出是: @@ -291,11 +345,15 @@ outerLoop exited ### Labels in for loop using `continue` {:.no_toc} + + ### 在 for 循环中使用 `continue` 的标签 {:.no_toc} The following code demonstrates the use of a label called `outerLoop` in a `for` loop with a `continue` statement: + + 以下代码演示了在带有 `continue` 语句的 `for` 循环中 使用名为 `outerLoop` 的标签: @@ -315,6 +373,8 @@ for (var i = 1; i <= 3; i++) { In the previous example, when `i == 2` and `j == 2`, `continue outerLoop;` skips the rest of the iterations for `i = 2` and moves to `i = 3`. As a result, the output is: + + 在前面的示例中,当 `i == 2` 且 `j == 2` 时, `continue outerLoop;` 跳过 `i = 2` 的剩余迭代并移动到 `i = 3`。 因此,输出是: @@ -331,11 +391,15 @@ i = 3, j = 3 ### Labels in while loop using `break` {:.no_toc} + + ### 在 while 循环中使用 `break` 的标签 {:.no_toc} The following code demonstrates the use of a label called `outerLoop` in a `while` loop with a `break` statement: + + 以下代码演示了在带有 `break` 语句的 `while` 循环中 使用名为 `outerLoop` 的标签: @@ -358,12 +422,18 @@ while (i <= 3) { print('outerLoop exited'); ``` -In the previous example, the program breaks out of both inner and outer `while` loops -when `i == 2` and `j == 2`. As a result, the output is: + 在前面的示例中,当 `i == 2` 且 `j == 2` 时, 程序跳出内部和外部的 `while` 循环。因此,输出是: +In the previous example, the program breaks out of both inner and outer `while` loops +when `i == 2` and `j == 2`. As a result, the output is: + + + +### 在 while 循环中使用 `continue` 的标签 {:.no_toc} + ```plaintext i = 1, j = 1 i = 1, j = 2 @@ -375,14 +445,19 @@ outerLoop exited ### Labels in while loop using `continue` {:.no_toc} -### 在 while 循环中使用 `continue` 的标签 {:.no_toc} -The following code demonstrates the use of a label called `outerLoop` in -a `while` loop with a `continue` statement: 以下代码演示了在带有 `continue` 语句的 `while` 循环中 使用名为 `outerLoop` 的标签: +The following code demonstrates the use of a label called `outerLoop` in +a `while` loop with a `continue` statement: + + + +在前面的示例中,`i = 2` 且 `j = 2` 的迭代被跳过, +循环直接移动到 `i = 3`。因此,输出是: + ```dart var i = 1; @@ -402,11 +477,17 @@ while (i <= 3) { } ``` + + +### 在 do-while 循环中使用 `break` 的标签 {:.no_toc} + In the previous example, the iteration for `i = 2` and `j = 2` is skipped and the loop moves directly to `i = 3`. As a result, the output is: -在前面的示例中,`i = 2` 且 `j = 2` 的迭代被跳过, -循环直接移动到 `i = 3`。因此,输出是: + + +以下代码演示了在带有 `break` 语句的 `do while` 循环中 +使用名为 `outerLoop` 的标签: ```plaintext i = 1, j = 1 @@ -420,13 +501,17 @@ i = 3, j = 3 ### Labels in do-while loop using `break` {:.no_toc} -### 在 do-while 循环中使用 `break` 的标签 {:.no_toc} + + +在前面的示例中,当 `i == 2` 且 `j == 2` 时, +程序跳出内部和外部循环。因此,输出是: The following code demonstrates the use of a label called `outerLoop` in a `do while` loop with a `break` statement: -以下代码演示了在带有 `break` 语句的 `do while` 循环中 -使用名为 `outerLoop` 的标签: + + +### 在 do-while 循环中使用 `continue` 的标签 {:.no_toc} ```dart @@ -445,15 +530,22 @@ do { i++; } while (i <= 3); + + +以下代码演示了在带有 `continue` 语句的 `do while` 循环中 +使用名为 `outerLoop` 的标签: + print('outerLoop exited'); ``` + + +在前面的示例中,循环跳过 `i = 2` 且 `j = 2`, +并直接移动到 `i = 3`。因此,输出是: + In the previous example, the program breaks out of both inner and outer loops when `i == 2` and `j == 2`. As a result, the output is: -在前面的示例中,当 `i == 2` 且 `j == 2` 时, -程序跳出内部和外部循环。因此,输出是: - ```plaintext i = 1, j = 1 i = 1, j = 2 @@ -465,14 +557,9 @@ outerLoop exited ### Labels in do-while loop using `continue` {:.no_toc} -### 在 do-while 循环中使用 `continue` 的标签 {:.no_toc} - The following code demonstrates the use of a label called `outerLoop` in a `do while` loop with a `continue` statement: -以下代码演示了在带有 `continue` 语句的 `do while` 循环中 -使用名为 `outerLoop` 的标签: - ```dart var i = 1; @@ -495,9 +582,6 @@ do { In the previous example, the loop skips `i = 2` and `j = 2` and moves directly to `i = 3`. As a result, the output is: -在前面的示例中,循环跳过 `i = 2` 且 `j = 2`, -并直接移动到 `i = 3`。因此,输出是: - ```plaintext i = 1, j = 1 i = 1, j = 2 diff --git a/src/content/language/metadata.md b/src/content/language/metadata.md index d18b12ebd..5ec6d78b9 100644 --- a/src/content/language/metadata.md +++ b/src/content/language/metadata.md @@ -1,24 +1,23 @@ --- # title: Metadata -title: 元数据 +title: Metadata # description: Metadata and annotations in Dart. -description: Dart 中的元数据和注解。 +description: Metadata and annotations in Dart. prevpage: url: /language/functions - # title: Functions - title: 函数 + title: Functions nextpage: url: /language/libraries - # title: Libraries & imports - title: 库和导入 + title: Libraries & imports --- - Use metadata to provide additional static information about your code. A metadata annotation begins with the character `@`, followed by either a reference to a compile-time constant (such as `deprecated`) or a call to a constant constructor. + + 使用元数据为代码提供额外的静态信息。 元数据注解以字符 `@` 开头, 后跟对编译时常量的引用(如 `deprecated`) @@ -27,15 +26,21 @@ a call to a constant constructor. Metadata can be attached to most Dart program constructs by adding annotations before the construct's declaration or directive. + + 通过在声明或指令之前添加注解, 可以将元数据附加到大多数 Dart 程序结构上。 ## Built-in annotations + + ## 内置注解 The following annotations are available to all Dart code: + + 以下注解可用于所有 Dart 代码: [`@Deprecated`][] @@ -43,6 +48,8 @@ The following annotations are available to all Dart code: indicating it should be migrated away from, with a message explaining the replacement and potential removal date. + + [`@Deprecated`][] : 将声明标记为已弃用, 表示应该迁移到其他方案, @@ -52,6 +59,8 @@ The following annotations are available to all Dart code: : Marks a declaration as deprecated until an unspecified future release. Prefer using `@Deprecated` and [providing a deprecation message][]. + + [`@deprecated`][] : 将声明标记为已弃用,直到未来某个未指定的版本。 建议使用 `@Deprecated` 并[提供弃用消息][providing a deprecation message]。 @@ -61,6 +70,8 @@ The following annotations are available to all Dart code: a member with the same name from a parent class or interface. For examples of using `@override`, check out [Extend a class][]. + + [`@override`][] : 将实例成员标记为对父类或接口中同名成员的重写或实现。 有关使用 `@override` 的示例,请查看[扩展一个类][Extend a class]。 @@ -69,12 +80,16 @@ The following annotations are available to all Dart code: : Provides specific instructions or hints about a declaration to Dart tools, such as the compiler or analyzer. + + [`@pragma`][] : 向 Dart 工具(如编译器或分析器)提供 关于声明的特定指令或提示。 Here's an example of using the `@Deprecated` annotation: + + 下面是使用 `@Deprecated` 注解的示例: @@ -86,7 +101,7 @@ class Television { turnOn(); } - /// Turns the TV's power on. +/// Turns the TV's power on. void turnOn() { // ··· } @@ -94,14 +109,20 @@ class Television { } ``` -The [Dart analyzer][] provides feedback as diagnostics if -the `@override` annotation is needed and when using -members annotated with `@deprecated` or `@Deprecated`. + [Dart 分析器][Dart analyzer]会在需要 `@override` 注解时 以及使用带有 `@deprecated` 或 `@Deprecated` 注解的成员时 提供诊断反馈。 +The [Dart analyzer][] provides feedback as diagnostics if +the `@override` annotation is needed and when using +members annotated with `@deprecated` or `@Deprecated`. + + + +## 分析器支持的注解 + [`@Deprecated`]: {{site.dart-api}}/dart-core/Deprecated-class.html [`@deprecated`]: {{site.dart-api}}/dart-core/deprecated-constant.html [`@override`]: {{site.dart-api}}/dart-core/override-constant.html @@ -112,23 +133,19 @@ members annotated with `@deprecated` or `@Deprecated`. ## Analyzer-supported annotations -## 分析器支持的注解 -Beyond providing support and analysis for the [built-in annotations][], -the [Dart analyzer][] provides additional support and diagnostics for -a variety of annotations from [`package:meta`][]. -Some commonly used annotations the package provides include: 除了为[内置注解][built-in annotations]提供支持和分析外, [Dart 分析器][Dart analyzer]还为来自 [`package:meta`][] 的 各种注解提供额外的支持和诊断。 该包提供的一些常用注解包括: -[`@visibleForTesting`][] -: Marks a member of a package as only public so that - the member can be accessed from the package's tests. - The analyzer hides the member from autocompletion suggestions - and warns if it's used from another package. +Beyond providing support and analysis for the [built-in annotations][], +the [Dart analyzer][] provides additional support and diagnostics for +a variety of annotations from [`package:meta`][]. +Some commonly used annotations the package provides include: + + [`@visibleForTesting`][] : 将包的成员标记为仅为公开状态, @@ -136,11 +153,13 @@ Some commonly used annotations the package provides include: 分析器会在自动完成建议中隐藏该成员, 并在其他包使用时发出警告。 -[`@awaitNotRequired`][] -: Marks variables that have a `Future` type or functions that return a `Future` - as not requiring the caller to await the `Future`. - This stops the analyzer from warning callers that don't await the `Future` - due to the [`discarded_futures`][] or [`unawaited_futures`][] lints. +[`@visibleForTesting`][] +: Marks a member of a package as only public so that + the member can be accessed from the package's tests. + The analyzer hides the member from autocompletion suggestions + and warns if it's used from another package. + + [`@awaitNotRequired`][] : 将具有 `Future` 类型的变量或返回 `Future` 的函数 @@ -148,14 +167,26 @@ Some commonly used annotations the package provides include: 这会阻止分析器因 [`discarded_futures`][] 或 [`unawaited_futures`][] 规则 而警告未 await `Future` 的调用者。 -To learn more about these and the other annotations the package provides, -what they indicate, what functionality they enable, and how to use them, -check out the [`package:meta/meta.dart` API docs][meta-api]. +[`@awaitNotRequired`][] +: Marks variables that have a `Future` type or functions that return a `Future` + as not requiring the caller to await the `Future`. + This stops the analyzer from warning callers that don't await the `Future` + due to the [`discarded_futures`][] or [`unawaited_futures`][] lints. + + 要了解更多关于这些注解和该包提供的其他注解、 它们的含义、它们启用的功能以及如何使用它们, 请查看 [`package:meta/meta.dart` API 文档][meta-api]。 +To learn more about these and the other annotations the package provides, +what they indicate, what functionality they enable, and how to use them, +check out the [`package:meta/meta.dart` API docs][meta-api]. + + + +## 自定义注解 + [built-in annotations]: #built-in-annotations [Dart analyzer]: /tools/analysis [`@visibleForTesting`]: {{site.pub-api}}/meta/latest/meta/visibleForTesting-constant.html @@ -166,27 +197,38 @@ check out the [`package:meta/meta.dart` API docs][meta-api]. ## Custom annotations -## 自定义注解 -You can define your own metadata annotations. Here's an example of -defining a `@Todo` annotation that takes two arguments: 你可以定义自己的元数据注解。下面是一个定义接受两个参数的 `@Todo` 注解的示例: +You can define your own metadata annotations. Here's an example of +defining a `@Todo` annotation that takes two arguments: + + + +下面是使用 `@Todo` 注解的示例: + ```dart class Todo { final String who; final String what; - const Todo(this.who, this.what); +const Todo(this.who, this.what); } ``` + + +### 指定支持的目标 {:.no_toc} + And here's an example of using that `@Todo` annotation: -下面是使用 `@Todo` 注解的示例: + + +要指示应该使用你的注解标注的语言结构类型, +请使用 [`package:meta`][] 中的 [`@Target`][] 注解。 ```dart highlightLines=1 @@ -198,23 +240,25 @@ void doSomething() { ### Specifying supported targets {:.no_toc} -### 指定支持的目标 {:.no_toc} + + +例如,如果你希望前面的 `@Todo` 注解 +只能用于函数和方法, +你可以添加以下注解: To indicate the type of language constructs that should be annotated with your annotation, use the [`@Target`][] annotation from [`package:meta`][]. -要指示应该使用你的注解标注的语言结构类型, -请使用 [`package:meta`][] 中的 [`@Target`][] 注解。 + + +使用此配置,如果 `Todo` 被用作顶层函数或方法以外的 +任何声明的注解,分析器将发出警告。 For example, if you wanted the earlier `@Todo` annotation to only be allowed on functions and methods, you'd add the following annotation: -例如,如果你希望前面的 `@Todo` 注解 -只能用于函数和方法, -你可以添加以下注解: - ```dart highlightLines=3 import 'package:meta/meta_meta.dart'; @@ -228,8 +272,5 @@ class Todo { With this configuration, the analyzer will warn if `Todo` is used as an annotation on any declaration besides a top-level function or method. -使用此配置,如果 `Todo` 被用作顶层函数或方法以外的 -任何声明的注解,分析器将发出警告。 - [`@Target`]: {{site.pub-api}}/meta/latest/meta_meta/Target-class.html [`package:meta`]: {{site.pub-pkg}}/meta diff --git a/src/content/language/methods.md b/src/content/language/methods.md index 94f931944..9383354a7 100644 --- a/src/content/language/methods.md +++ b/src/content/language/methods.md @@ -1,32 +1,36 @@ --- # title: Methods -title: 方法 +title: Methods # description: Learn about methods in Dart. -description: 了解 Dart 中的方法。 +description: Learn about methods in Dart. prevpage: url: /language/constructors - # title: Constructors - title: 构造函数 + title: Constructors nextpage: url: /language/extend - # title: Extend a class - title: 扩展一个类 + title: Extend a class --- Methods are functions that provide behavior for an object. + + 方法是为对象提供行为的函数。 ## Instance methods + + ## 实例方法 Instance methods on objects can access instance variables and `this`. The `distanceTo()` method in the following sample is an example of an instance method: + + 对象的实例方法可以访问实例变量和 `this`。 下面示例中的 `distanceTo()` 方法就是一个实例方法的例子: @@ -38,28 +42,58 @@ class Point { final double x; final double y; - // Sets the x and y instance variables + + +## 运算符 + +// Sets the x and y instance variables // before the constructor body runs. Point(this.x, this.y); - double distanceTo(Point other) { + + +大多数运算符是具有特殊名称的实例方法。 +Dart 允许你使用以下名称定义运算符: + +double distanceTo(Point other) { var dx = x - other.x; var dy = y - other.y; return sqrt(dx * dx + dy * dy); } + + +你可能已经注意到,一些[运算符][operators],如 `!=`, +不在名称列表中。这些运算符不是实例方法。 +它们的行为是 Dart 内置的。 +::: + } ``` + + +要声明一个运算符,请使用内置标识符 `operator`, +然后是你要定义的运算符。 +下面的示例定义了向量加法(`+`)、减法(`-`) +和相等(`==`)运算符: + ## Operators -## 运算符 + + +## Getter 和 Setter Most operators are instance methods with special names. Dart allows you to define operators with the following names: -大多数运算符是具有特殊名称的实例方法。 -Dart 允许你使用以下名称定义运算符: + + +Getter 和 setter 是提供对象属性读写访问的特殊方法。 +回想一下,每个实例变量都有一个隐式的 getter, +如果合适的话还有一个 setter。 +你可以使用 `get` 和 `set` 关键字来实现 getter 和 setter, +从而创建额外的属性: | | | | | | | |-------|------|------|------|-------|------| @@ -70,14 +104,15 @@ Dart 允许你使用以下名称定义运算符: {:.table} + + +使用 getter 和 setter,你可以从实例变量开始, +之后用方法包装它们,而无需更改客户端代码。 + :::note You may have noticed that some [operators][], like `!=`, aren't in the list of names. These operators aren't instance methods. Their behavior is built in to Dart. - -你可能已经注意到,一些[运算符][operators],如 `!=`, -不在名称列表中。这些运算符不是实例方法。 -它们的行为是 Dart 内置的。 ::: {%- comment %} @@ -91,26 +126,43 @@ To declare an operator, use the built-in identifier The following example defines vector addition (`+`), subtraction (`-`), and equality (`==`): -要声明一个运算符,请使用内置标识符 `operator`, -然后是你要定义的运算符。 -下面的示例定义了向量加法(`+`)、减法(`-`) -和相等(`==`)运算符: + + +无论是否显式定义了 getter, +像自增(`++`)这样的运算符都会按预期方式工作。 +为了避免任何意外的副作用, +运算符只调用一次 getter,并将其值保存在临时变量中。 +::: ```dart class Vector { final int x, y; - Vector(this.x, this.y); +Vector(this.x, this.y); + + - Vector operator +(Vector v) => Vector(x + v.x, y + v.y); +## 抽象方法 + +Vector operator +(Vector v) => Vector(x + v.x, y + v.y); Vector operator -(Vector v) => Vector(x - v.x, y - v.y); - @override + + +实例方法、getter 和 setter 方法可以是抽象的, +定义一个接口但将其实现留给其他类。 +抽象方法只能存在于[抽象类][abstract classes]或 [mixin][mixins] 中。 + +@override bool operator ==(Object other) => other is Vector && x == other.x && y == other.y; - @override + + +要使方法成为抽象方法,请使用分号(`;`)代替方法体: + +@override int get hashCode => Object.hash(x, y); } @@ -118,28 +170,19 @@ void main() { final v = Vector(2, 3); final w = Vector(2, 2); - assert(v + w == Vector(4, 5)); +assert(v + w == Vector(4, 5)); assert(v - w == Vector(0, 1)); } ``` - ## Getters and setters -## Getter 和 Setter - Getters and setters are special methods that provide read and write access to an object's properties. Recall that each instance variable has an implicit getter, plus a setter if appropriate. You can create additional properties by implementing getters and setters, using the `get` and `set` keywords: -Getter 和 setter 是提供对象属性读写访问的特殊方法。 -回想一下,每个实例变量都有一个隐式的 getter, -如果合适的话还有一个 setter。 -你可以使用 `get` 和 `set` 关键字来实现 getter 和 setter, -从而创建额外的属性: - ```dart highlightLines=8-12 /// A rectangle in a screen coordinate system, @@ -147,9 +190,9 @@ Getter 和 setter 是提供对象属性读写访问的特殊方法。 class Rectangle { double left, top, width, height; - Rectangle(this.left, this.top, this.width, this.height); +Rectangle(this.left, this.top, this.width, this.height); - // Define two calculated properties: right and bottom. +// Define two calculated properties: right and bottom. double get right => left + width; set right(double value) => left = value - width; double get bottom => top + height; @@ -167,43 +210,27 @@ void main() { With getters and setters, you can start with instance variables, later wrapping them with methods, all without changing client code. -使用 getter 和 setter,你可以从实例变量开始, -之后用方法包装它们,而无需更改客户端代码。 - :::note Operators such as increment (`++`) work in the expected way, whether or not a getter is explicitly defined. To avoid any unexpected side effects, the operator calls the getter exactly once, saving its value in a temporary variable. - -无论是否显式定义了 getter, -像自增(`++`)这样的运算符都会按预期方式工作。 -为了避免任何意外的副作用, -运算符只调用一次 getter,并将其值保存在临时变量中。 ::: ## Abstract methods -## 抽象方法 - Instance, getter, and setter methods can be abstract, defining an interface but leaving its implementation up to other classes. Abstract methods can only exist in [abstract classes][] or [mixins][]. -实例方法、getter 和 setter 方法可以是抽象的, -定义一个接口但将其实现留给其他类。 -抽象方法只能存在于[抽象类][abstract classes]或 [mixin][mixins] 中。 - To make a method abstract, use a semicolon (`;`) instead of a method body: -要使方法成为抽象方法,请使用分号(`;`)代替方法体: - ```dart abstract class Doer { // Define instance variables and methods... - void doSomething(); // Define an abstract method. +void doSomething(); // Define an abstract method. } class EffectiveDoer extends Doer { diff --git a/src/content/language/mixins.md b/src/content/language/mixins.md index 7a42a24b0..ffeea37e4 100644 --- a/src/content/language/mixins.md +++ b/src/content/language/mixins.md @@ -1,16 +1,14 @@ --- # title: Mixins -title: Mixin +title: Mixins # description: Learn how to add to features to a class in Dart. -description: 了解如何在 Dart 中为类添加功能。 +description: Learn how to add to features to a class in Dart. prevpage: url: /language/extend - # title: Extend a class - title: 扩展一个类 + title: Extend a class nextpage: url: /language/enums - # title: Enums - title: 枚举 + title: Enums --- @@ -18,6 +16,8 @@ nextpage: Mixins are a way of defining code that can be reused in multiple class hierarchies. They are intended to provide member implementations en masse. + + Mixin 是一种在多个类层次结构中重用代码的方式。 它们旨在批量提供成员实现。 @@ -25,6 +25,8 @@ To use a mixin, use the `with` keyword followed by one or more mixin names. The following example shows two classes that use (or, are subclasses of) mixins: + + 要使用 mixin,请使用 `with` 关键字后跟一个或多个 mixin 名称。 下面的示例展示了两个使用(或者说是子类化)mixin 的类: @@ -42,24 +44,34 @@ class Maestro extends Person [!with Musical, Aggressive, Demented!] { } ``` -To define a mixin, use the `mixin` declaration. -In the rare case where you need to define both a mixin _and_ a class, you can use -the [`mixin class` declaration](#class-mixin-or-mixin-class). + 要定义 mixin,请使用 `mixin` 声明。 在需要同时定义 mixin _和_ 类的罕见情况下, 你可以使用 [`mixin class` 声明](#class-mixin-or-mixin-class)。 -Mixins and mixin classes cannot have an `extends` clause, -and must not declare any generative constructors. +To define a mixin, use the `mixin` declaration. +In the rare case where you need to define both a mixin _and_ a class, you can use +the [`mixin class` declaration](#class-mixin-or-mixin-class). + + Mixin 和 mixin 类不能有 `extends` 子句, 并且不能声明任何生成式构造函数。 -For example: +Mixins and mixin classes cannot have an `extends` clause, +and must not declare any generative constructors. + + 例如: +For example: + + + +## 指定 mixin 可以调用自身的成员 + ```dart mixin Musical { @@ -67,7 +79,7 @@ mixin Musical { bool canCompose = false; bool canConduct = false; - void entertainMe() { +void entertainMe() { if (canPlayPiano) { print('Playing piano'); } else if (canConduct) { @@ -79,39 +91,54 @@ mixin Musical { } ``` + + +有时 mixin 依赖于能够调用方法或访问字段, +但不能自己定义这些成员(因为 mixin 不能使用构造函数参数 +来实例化自己的字段)。 + ## Specify members a mixin can call on itself -## 指定 mixin 可以调用自身的成员 + + +以下部分介绍了确保 mixin 的任何子类定义 mixin 行为所依赖的 +任何成员的不同策略。 Sometimes a mixin depends on being able to invoke a method or access fields, but can't define those members itself (because mixins can't use constructor parameters to instantiate their own fields). -有时 mixin 依赖于能够调用方法或访问字段, -但不能自己定义这些成员(因为 mixin 不能使用构造函数参数 -来实例化自己的字段)。 + + +### 在 mixin 中定义抽象成员 The following sections cover different strategies for ensuring any subclass of a mixin defines any members the mixin's behavior depends on. -以下部分介绍了确保 mixin 的任何子类定义 mixin 行为所依赖的 -任何成员的不同策略。 + + +在 mixin 中声明抽象方法会强制任何使用该 mixin 的类型 +定义其行为所依赖的抽象方法。 ### Define abstract members in the mixin -### 在 mixin 中定义抽象成员 + + +#### 访问 mixin 子类中的状态 Declaring an abstract method in a mixin forces any type that uses the mixin to define the abstract method upon which its behavior depends. -在 mixin 中声明抽象方法会强制任何使用该 mixin 的类型 -定义其行为所依赖的抽象方法。 + + +声明抽象成员还允许你通过调用在 mixin 上定义为抽象的 getter +来访问 mixin 子类上的状态: ```dart mixin Musician { void playInstrument(String instrumentName); // Abstract method. - void playPiano() { +void playPiano() { playInstrument('Piano'); } void playFlute() { @@ -119,24 +146,43 @@ mixin Musician { } } + + +### 实现接口 + class Virtuoso with Musician { - @override + + +与将 mixin 声明为抽象类似,在 mixin 上放置 `implements` 子句 +但不实际实现接口,也将确保为 mixin 定义任何成员依赖项。 + +@override void playInstrument(String instrumentName) { // Subclass must define. print('Plays the $instrumentName beautifully'); - } -} + } +} ``` + + +### 使用 `on` 子句声明超类 + #### Access state in the mixin's subclass -#### 访问 mixin 子类中的状态 + + +`on` 子句用于定义 `super` 调用所针对的类型。 +因此,只有在需要在 mixin 中使用 `super` 调用时才应该使用它。 Declaring abstract members also allows you to access state on the subclass of a mixin, by calling getters which are defined as abstract on the mixin: -声明抽象成员还允许你通过调用在 mixin 上定义为抽象的 getter -来访问 mixin 子类上的状态: + + +`on` 子句强制任何使用 mixin 的类也必须是 `on` 子句中类型的子类。 +如果 mixin 依赖于超类中的成员, +这可以确保在使用 mixin 的地方这些成员是可用的: ```dart /// Can be applied to any type with a [name] property and provides an @@ -144,30 +190,56 @@ of a mixin, by calling getters which are defined as abstract on the mixin: mixin NameIdentity { String get name; - @override +@override int get hashCode => name.hashCode; - @override + + +在这个示例中,只有扩展或实现 `Musician` 类的类 +才能使用 `MusicalPerformer` mixin。 +因为 `SingerDancer` 扩展了 `Musician`, +所以 `SingerDancer` 可以混入 `MusicalPerformer`。 + +@override bool operator ==(other) => other is NameIdentity && name == other.name; } + + +## `class`、`mixin` 还是 `mixin class`? + class Person with NameIdentity { final String name; - Person(this.name); + + +`mixin class` 声明需要至少 3.0 的[语言版本][language version]。 +::: + +Person(this.name); } ``` + + +`mixin` 声明定义了一个 mixin。`class` 声明定义了一个[类][class]。 +`mixin class` 声明定义了一个既可以用作普通类又可以用作 mixin 的类, +具有相同的名称和相同的类型。 + ### Implement an interface -### 实现接口 + + +适用于类或 mixin 的任何限制也适用于 mixin 类: Similar to declaring the mixin abstract, putting an `implements` clause on the mixin while not actually implementing the interface will also ensure any member dependencies are defined for the mixin. -与将 mixin 声明为抽象类似,在 mixin 上放置 `implements` 子句 -但不实际实现接口,也将确保为 mixin 定义任何成员依赖项。 + + +- Mixin 不能有 `extends` 或 `with` 子句,因此 `mixin class` 也不能有。 +- 类不能有 `on` 子句,因此 `mixin class` 也不能有。 ```dart abstract interface class Tuner { @@ -178,13 +250,13 @@ mixin Guitarist implements Tuner { void playSong() { tuneInstrument(); - print('Strums guitar majestically.'); +print('Strums guitar majestically.'); } } class PunkRocker with Guitarist { - @override +@override void tuneInstrument() { print("Don't bother, being out of tune is punk rock."); } @@ -193,23 +265,14 @@ class PunkRocker with Guitarist { ### Use the `on` clause to declare a superclass -### 使用 `on` 子句声明超类 - The `on` clause exists to define the type that `super` calls are resolved against. So, you should only use it if you need to have a `super` call inside a mixin. -`on` 子句用于定义 `super` 调用所针对的类型。 -因此,只有在需要在 mixin 中使用 `super` 调用时才应该使用它。 - The `on` clause forces any class that uses a mixin to also be a subclass of the type in the `on` clause. If the mixin depends on members in the superclass, this ensures those members are available where the mixin is used: -`on` 子句强制任何使用 mixin 的类也必须是 `on` 子句中类型的子类。 -如果 mixin 依赖于超类中的成员, -这可以确保在使用 mixin 的地方这些成员是可用的: - ```dart class Musician { musicianMethod() { @@ -235,29 +298,16 @@ In this example, only classes that extend or implement the `Musician` class can use the mixin `MusicalPerformer`. Because `SingerDancer` extends `Musician`, `SingerDancer` can mix in `MusicalPerformer`. -在这个示例中,只有扩展或实现 `Musician` 类的类 -才能使用 `MusicalPerformer` mixin。 -因为 `SingerDancer` 扩展了 `Musician`, -所以 `SingerDancer` 可以混入 `MusicalPerformer`。 - ## `class`, `mixin`, or `mixin class`? -## `class`、`mixin` 还是 `mixin class`? - :::version-note The `mixin class` declaration requires a [language version][] of at least 3.0. - -`mixin class` 声明需要至少 3.0 的[语言版本][language version]。 ::: A `mixin` declaration defines a mixin. A `class` declaration defines a [class][]. A `mixin class` declaration defines a class that is usable as both a regular class and a mixin, with the same name and the same type. -`mixin` 声明定义了一个 mixin。`class` 声明定义了一个[类][class]。 -`mixin class` 声明定义了一个既可以用作普通类又可以用作 mixin 的类, -具有相同的名称和相同的类型。 - ```dart mixin class Musician { // ... @@ -274,14 +324,9 @@ class Novice extends Musician { // Use Musician as a class Any restrictions that apply to classes or mixins also apply to mixin classes: -适用于类或 mixin 的任何限制也适用于 mixin 类: - - Mixins can't have `extends` or `with` clauses, so neither can a `mixin class`. - Classes can't have an `on` clause, so neither can a `mixin class`. -- Mixin 不能有 `extends` 或 `with` 子句,因此 `mixin class` 也不能有。 -- 类不能有 `on` 子句,因此 `mixin class` 也不能有。 - [language version]: /resources/language/evolution#language-versioning [class]: /language/classes [class modifiers]: /language/class-modifiers diff --git a/src/content/language/modifier-reference.md b/src/content/language/modifier-reference.md index ee287b00a..01e423ce1 100644 --- a/src/content/language/modifier-reference.md +++ b/src/content/language/modifier-reference.md @@ -1,31 +1,35 @@ --- # title: Class modifiers reference -title: 类修饰符参考 +title: Class modifiers reference # description: >- # The allowed and disallowed combinations of class modifiers. description: >- - 类修饰符的允许和禁止组合。 + The allowed and disallowed combinations of class modifiers. prevpage: url: /language/class-modifiers - # title: Class modifiers - title: 类修饰符 + title: Class modifiers nextpage: url: /language/concurrency - # title: Concurrency in Dart - title: Dart 中的并发 + title: Concurrency in Dart --- This page contains reference information for [class modifiers](/language/class-modifiers). + + 本页面包含[类修饰符](/language/class-modifiers)的参考信息。 ## Valid combinations + + ## 有效组合 The valid combinations of class modifiers and their resulting capabilities are: + + 类修饰符的有效组合及其产生的功能如下: | Declaration | [Construct][]? | [Extend][]? | [Implement][]? | [Mix in][]? | [Exhaustive][]? | @@ -48,6 +52,10 @@ The valid combinations of class modifiers and their resulting capabilities are: {: .table .table-striped .nowrap} + + +## 无效组合 + [Construct]: /language/classes#using-constructors [Extend]: /language/extend [Implement]: /language/classes#implicit-interfaces @@ -56,21 +64,13 @@ The valid combinations of class modifiers and their resulting capabilities are: ## Invalid combinations -## 无效组合 -Certain [combinations][] of modifiers aren't allowed: 某些修饰符[组合][combinations]是不允许的: -| Combination | Reasoning | -|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| -| `base`, `interface`, and `final` | All control the same two capabilities (`extend` and `implement`), so are mutually exclusive. | -| `sealed` and `abstract` | Neither can be constructed, so are redundant together. | -| `sealed` with `base`, `interface`, or `final` | `sealed` types already cannot be mixed in, extended or implemented from another library, so are redundant to combine with the listed modifiers. | -| `mixin` and `abstract` | Neither can be constructed, so are redundant together. | -| `mixin` and `interface`, `final`, or `sealed` | A `mixin` or `mixin class` declaration is intended to be mixed in, which the listed modifiers prevent. | -| `enum` and any modifiers | `enum` declarations can't be extended, implemented, mixed in, and can always be instantiated, so no modifiers apply to `enum` declarations. | -| `extension type` and any modifiers | `extension type` declarations can't be extended or mixed in, and can only be implemented by other `extension type` declarations. | +Certain [combinations][] of modifiers aren't allowed: + + | 组合 | 原因 | |-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| @@ -82,6 +82,16 @@ Certain [combinations][] of modifiers aren't allowed: | `enum` 和任何修饰符 | `enum` 声明不能被扩展、实现或混入,且总是可以被实例化,因此没有修饰符适用于 `enum` 声明。 | | `extension type` 和任何修饰符 | `extension type` 声明不能被扩展或混入,且只能被其他 `extension type` 声明实现。 | +| Combination | Reasoning | +|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| +| `base`, `interface`, and `final` | All control the same two capabilities (`extend` and `implement`), so are mutually exclusive. | +| `sealed` and `abstract` | Neither can be constructed, so are redundant together. | +| `sealed` with `base`, `interface`, or `final` | `sealed` types already cannot be mixed in, extended or implemented from another library, so are redundant to combine with the listed modifiers. | +| `mixin` and `abstract` | Neither can be constructed, so are redundant together. | +| `mixin` and `interface`, `final`, or `sealed` | A `mixin` or `mixin class` declaration is intended to be mixed in, which the listed modifiers prevent. | +| `enum` and any modifiers | `enum` declarations can't be extended, implemented, mixed in, and can always be instantiated, so no modifiers apply to `enum` declarations. | +| `extension type` and any modifiers | `extension type` declarations can't be extended or mixed in, and can only be implemented by other `extension type` declarations. | + {: .table .table-striped .nowrap} [combinations]: /language/class-modifiers#combining-modifiers diff --git a/src/content/language/typedefs.md b/src/content/language/typedefs.md index 0bf73f022..9d9ea029c 100644 --- a/src/content/language/typedefs.md +++ b/src/content/language/typedefs.md @@ -1,17 +1,15 @@ --- # title: Typedefs -title: 类型别名 +title: Typedefs # description: Learn about type aliases in Dart. -description: 了解 Dart 中的类型别名。 +description: Learn about type aliases in Dart. showToc: false prevpage: url: /language/generics - # title: Generics - title: 泛型 + title: Generics nextpage: url: /language/type-system - # title: Type system - title: 类型系统 + title: Type system --- @@ -21,6 +19,8 @@ it's declared with the keyword `typedef`—is a concise way to refer to a type. Here's an example of declaring and using a type alias named `IntList`: + + 类型别名——通常被称为 _typedef_, 因为它是用关键字 `typedef` 声明的——是 一种简洁地引用类型的方式。 @@ -34,6 +34,8 @@ IntList il = [1, 2, 3]; A type alias can have type parameters: + + 类型别名可以有类型参数: @@ -46,18 +48,17 @@ ListMapper m2 = {}; // Same thing but shorter and clearer. :::version-note Before 2.13, typedefs were restricted to function types. Using the new typedefs requires a [language version][] of at least 2.13. - -在 2.13 之前,typedef 仅限于函数类型。 -使用新的 typedef 需要[语言版本][language version]至少为 2.13。 ::: We recommend using [inline function types][] instead of typedefs for functions, in most situations. However, function typedefs can still be useful: -在大多数情况下,我们建议使用[内联函数类型][inline function types] -而不是函数的 typedef。 -但是,函数 typedef 仍然很有用: + + +在 2.13 之前,typedef 仅限于函数类型。 +使用新的 typedef 需要[语言版本][language version]至少为 2.13。 +::: ```dart @@ -65,6 +66,12 @@ typedef Compare = int Function(T a, T b); int sort(int a, int b) => a - b; + + +在大多数情况下,我们建议使用[内联函数类型][inline function types] +而不是函数的 typedef。 +但是,函数 typedef 仍然很有用: + void main() { assert(sort is Compare); // True! }