Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1338: referencemanual declarations⭐️⭐️⭐️⭐️⭐️ #1380

Conversation

Shinolr
Copy link
Collaborator

@Shinolr Shinolr commented Sep 4, 2024

close #1338

@Shinolr Shinolr linked an issue Sep 4, 2024 that may be closed by this pull request
@yongfrank yongfrank changed the title 1338 referencemanual declarations 1338: referencemanual declarations⭐️⭐️⭐️⭐️⭐️ Sep 22, 2024
@yongfrank yongfrank requested a review from saitjr October 5, 2024 00:47
and to define enumeration, structure, class, and protocol types.
You can also use a declaration to extend the behavior
of an existing named type and to import symbols into your program that are declared elsewhere.
一个*声明*将一个新名称或构造引入到你的程序中。例如,你使用声明来引入函数和方法,引入变量和常量,以及定义枚举、结构体、类和协议类型。你还可以使用声明来扩展现有具名类型的行为,并将其他地方声明的符号引入到你的程序中。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

声明将在程序中引入一个新的名称或构造。

implement their members, most protocol members are declarations only. For convenience
and because the distinction isn't that important in Swift,
the term *declaration* covers both declarations and definitions.
在 Swift 中,大多数声明也是定义,因为它们在声明的同时被实现或初始化。也就是说,由于协议不实现其成员,大多数协议成员仅仅是声明。为了方便起见,并且因为在 Swift 中这种区别并不是那么重要,术语*声明*涵盖了声明和定义。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的“也就是说”不太准确。前句在说,大多数声明同时是定义。后面在说,协议一般不实现,只是在定义,是一个特殊情况。所以是一个转折,而不是递进。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原句:也就是说,由于协议不实现其成员,大多数协议成员仅仅是声明。
  • 建议更改为:但由于协议不实现它的成员,所以协议成员在此仅仅是声明。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“并且因为在 Swift 中这种区别并不是那么重要” 不是很通顺,可以优化一下

  • 原句:为了方便起见,并且因为在 Swift 中这种区别并不是那么重要,术语声明涵盖了声明和定义。
  • 建议更改为:为了方便起见,而且这种区别在 Swift 中没那么重要,所以术语声明涵盖了声明和定义两种含义。

> Grammar of a top-level declaration:
## 顶级代码

Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他具名声明可以被同一模块中每个源文件的代码访问。你可以通过使用访问级别修饰符来覆盖此默认行为,具体说明见 <doc:Declarations#Access-Control-Levels>。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你可以通过使用访问级别修饰符来覆盖此默认行为。通过两字多余


有两种类型的顶级代码:顶级声明和可执行的顶级代码。顶级声明仅由声明组成,允许出现在所有 Swift 源文件中。可执行的顶级代码包含语句和表达式,而不仅仅是声明,仅允许作为程序的顶级入口点。

你编译的 Swift 代码可以包含最多以下一种方法来标记顶级入口点,无论代码如何组织成文件和模块:`main` 特性,`NSApplicationMain` 特性,`UIApplicationMain` 特性,`main.swift` 文件,或包含顶级可执行代码的文件。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

编译 Swift 代码生成可执行文件时,无论文件和模块中的代码如何组织,都只能通过以下方法之一来指定顶级入口点:main 特性、NSApplicationMain 特性、UIApplicationMain 特性、main.swift 文件,或包含顶级可执行代码的文件。

-->

# Declarations
# 声明
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

全文中的术语,在首次出现时,应该加上原文。常用英文,建议加上原文。如:

  • 一个*声明(declaration)*将一个新名称
  • 顶级代码(Top-Level Code)
  • 语句(statements)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

挺多内容相较于之前的 Swift 文档没有变化,可以参考以前已发布的翻译内容:声明 | SwiftGG

only the imported symbol
(and not the module that declares it)
is made available in the current scope.
提供更多细节可以限制导入哪些符号——你可以指定特定的子模块或模块或子模块内的特定声明。当使用这种详细形式时,只有被导入的符号(而非声明它的模块)在当前作用域中可用。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里直译会有两个或,“特定的子模块模块子模块内的特定声明”,不方便断句,难以理解。建议补充额外的语句。

  • 原文:提供更多细节可以限制导入哪些符号——你可以指定特定的子模块或模块或子模块内的特定声明

  • 建议更改为:提供更多细节可以限制导入哪些符号——可以指定特定的子模块,也可以指定模块或子模块中特定的声明。

  • 原文:当使用这种详细形式时,只有被导入的符号(而非声明它的模块)在当前作用域中可用。

  • 建议更改为:使用这种限制后,在当前作用域中,只有被导入的符号是可用的,而不是整个模块中的所有声明。

> or use a variable declaration instead.
常量声明定义了*常量名称*与构造器*表达式*的值之间的不可变绑定;一旦常量的被赋值,就无法更改。也就是说,如果常量是用类对象初始化的,对象本身可以改变,但常量名称与它所指向的对象之间的绑定不能改变。

当在全局范围内声明常量时,必须用一个值进行初始化。当在函数或方法的上下文中发生常量声明时,可以稍后初始化,只要保证在第一次读取其值之前已为其赋值。如果编译器能够证明常量的值从未被读取,则不要求该常量必须设置值。此分析称为*确定初始化*——编译器保证一个值在读取之前值已被赋值。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 当在全局范围内声明常量时,必须用一个值进行初始化
  • 建议改为:当常量声明在全局作用域时,常量必须赋值。
  • 或者:当常量声明在全局作用域时,常量必须有一个初始值。
  • 原因:这里的重点是全局常量在初始化的时候必须要赋值,而其他场景的常量可以稍后赋值。如果直译,比较生硬,而且语义不明
  1. 当在函数或方法的上下文中发生常量声明时
  • 建议改为:当常量声明在函数或者方法的上下文中时
  • 原因:“发生常量声明”是什么说法,不通顺
  1. 则不要求该常量必须设置值
  • 建议改为:则不要求该常量必须赋值
  • 原因:前后名词保持一致

当在全局范围内声明常量时,必须用一个值进行初始化。当在函数或方法的上下文中发生常量声明时,可以稍后初始化,只要保证在第一次读取其值之前已为其赋值。如果编译器能够证明常量的值从未被读取,则不要求该常量必须设置值。此分析称为*确定初始化*——编译器保证一个值在读取之前值已被赋值。

> 注意:
> 确定初始化无法构建需要领域知识的证明,并且它在条件语句中跟踪状态的能力是有限的。如果你可以确定常量始终有一个值,但编译器无法证明这一点,请尝试简化设置该值的代码路径,或改用变量声明。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:确定初始化无法构建需要领域知识的证明,并且它在条件语句中跟踪状态的能力是有限的。
  • 建议:确定初始化无法分析包含特定领域的内容,并且对条件语句中的状态跟踪能力也有限。

原因:对于前半句可能不太准确,但是直译更难理解。这里原文表达的应该是:在包含特定领域知识的情况下,definite initialization 是无法构建起相关的逻辑关系的。所以,这里的 construct proofs 个人理解,翻译成“分析”比较合适

If the *constant name* of a constant declaration is a tuple pattern,
the name of each item in the tuple is bound to the corresponding value
in the initializer *expression*.
如果常量声明的*常量名称*是一个元组模式,则元组中每个项的名称都绑定到构造器*表达式*中相应的值。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果常量名称是元组形式,元组中每一项的名称都会和初始化表达式中对应的值进行绑定。

The type annotation (`:` *type*) is optional in a constant declaration
when the type of the *constant name* can be inferred,
as described in <doc:Types#Type-Inference>.
在常量声明中,当可以推断出*常量名称*的类型时,类型注释(`:` *type*)是可选的,祥见 <doc:Types#Type-Inference>。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo:详见。而不是“祥见”

you can't mark it with the `class` or `final` declaration modifier
to allow or disallow overriding by subclasses.
Type properties are discussed in <doc:Properties#Type-Properties>.
要声明一个常量类型属性,请使用 `static` 声明修饰符标记该声明。类的常量类型属性总是隐式为 final;你不能使用 `class` 或 `final` 声明修饰符来允许或禁止子类重写。类型属性的讨论请参见 <doc:Properties#Type-Properties>。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:你不能使用 classfinal 声明修饰符来允许或禁止子类重写。
  • 建议:你无法用 classfinal 声明修饰符实现允许或禁止被子类重写的目的。

之前的文档对这里的翻译更合理。

@@ -250,69 +164,46 @@ Type properties are discussed in <doc:Properties#Type-Properties>.
```
-->

For more information about constants and for guidance about when to use them,
see <doc:TheBasics#Constants-and-Variables> and <doc:Properties#Stored-Properties>.
有关常量的更多信息以及何时使用它们的指导,请参见 <doc:TheBasics#Constants-and-Variables> 和 <doc:Properties#Stored-Properties>。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

更多关于常量的信息或使用指导,请参见:xxx。或者改为参考,参阅,也可以。

stored variable and property observers, and static variable properties.
The appropriate form to use depends on
the scope at which the variable is declared and the kind of variable you intend to declare.
变量声明有几种形式,用于声明不同类型的具名可变值,包括存储变量和计算变量及属性、存储变量和属性观察者,以及静态变量属性。使用何种适当的形式取决于变量声明的范围以及你打算声明的变量类型。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:变量声明有几种形式,用于声明不同类型的具名可变值

  • 建议:变量声明有多种形式,用于定义各种有名称的、可变的值

  • 原因:这里变量的描述是相较于常量来说的,常量说明了有名称,但值不可变。所以突出的点是不仅有名称,而且值可以变。

  • 原文:使用何种适当的形式取决于变量声明的范围以及你打算声明的变量类型。

  • 建议:使用哪种形式取决于变量声明的范围以及你打算声明的变量类型。

scope of a function, it's referred to as a *stored variable*.
When it's declared in the context of a class or structure declaration,
it's referred to as a *stored variable property*.
你可以在全局范围、函数的局部范围或类或结构体声明的上下文中定义这种形式的变量声明。当这种形式的变量声明在全局范围或函数的局部范围内声明时,它被称为*存储变量*。当它在类或结构体声明的上下文中声明时,它被称为*存储变量属性*。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scope 建议统一翻译为:作用域

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:你可以在全局范围、函数的局部范围或类或结构体声明的上下文中定义这种形式的变量声明。
  • 建议:你可以在全局作用域、函数的局部作用域,类或结构体声明的上下文中定义这种形式的变量声明。

同上,一句话里面的多个“或”,建议拆来翻译,便于阅读

but in all other contexts, the initializer *expression* is optional.
That said, if no initializer *expression* is present,
the variable declaration must include an explicit type annotation (`:` *type*).
构造器*表达式*不能出现在协议声明中,但在所有其他上下文中,构造器*表达式*是可选的。也就是说,如果没有构造器*表达式*,变量声明必须包含显式类型注释(`:` *type*)。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:但在所有其他上下文中
  • 建议:但在其他场景下。或:但在其他所有场景下

if the *variable name* is a tuple pattern,
the name of each item in the tuple is bound to the corresponding value
in the initializer *expression*.
与常量声明一样,如果变量声明省略了构造器*表达式*,则在第一次读取该变量之前必须为其设置一个值。同样,像常量声明一样,如果*变量名*是一个元组模式,则元组中每个项的名称都绑定到构造器*表达式*中的相应值。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:同样,像常量声明一样,
  • 建议:这里的“像常量声明一样,”有点冗余,直接“同样,如果变量名是一个元组模式” 就可以了

scope of a function, the observers are referred to as *stored variable observers*.
When it's declared in the context of a class or structure declaration,
the observers are referred to as *property observers*.
你可以在全局范围、函数的局部范围或类或结构体声明的上下文中定义这种变量声明形式。当这种形式的变量声明在全局范围或函数的局部范围内声明时,观察者被称为*存储变量观察者*。当它在类或结构体声明的上下文中声明时,观察者被称为*属性观察者*。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同理,scope 建议全局检查,翻译为“作用域”。多次的或,建议用 或拆为两个子句

You can add property observers to any stored property. You can also add property
observers to any inherited property (whether stored or computed) by overriding
the property within a subclass, as described in <doc:Inheritance#Overriding-Property-Observers>.
你可以为任何存储属性添加属性观察者。你还可以通过在子类中重写属性,为任何继承属性(无论是存储的还是计算的)添加属性观察者,参见 <doc:Inheritance#Overriding-Property-Observers>。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:继承属性
  • 建议:继承自父类的属性
  • 原因:前文在讲述存储属性、计算属性。突然来一个继承属性,还以为是一个新的类型。展开更便于理解

This expression is evaluated the first time you read the property's value.
If you overwrite the property's initial value without reading it,
this expression is evaluated before the first time you write to the property.
构造器*表达式*在类或结构体声明的上下文中是可选的,但在其他地方是必需的。当类型可以从构造器*表达式*中推断时,*类型*标注是可选的。该表达式在你第一次读取属性值时被评估。如果你在读取属性之前覆盖了属性的初始值,则在第一次写入属性之前会评估该表达式。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:必需
  • 建议:必须
  • 原因:required 是强制性的,应该用 必须

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:当类型可以从构造器表达式中推断时,类型标注是可选的。
  • 建议:如果能通过构造器表达式推断出类型,则类型标注是可选的。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:该表达式在你第一次读取属性值时被评估。如果你在读取属性之前覆盖了属性的初始值,则在第一次写入属性之前会评估该表达式。
  • 建议:通常,表达式的类型推断发生在首次读取属性时。如果在读取属性之前,初值已经被覆盖,则推断发生在首次写入属性时。

Otherwise, the new value is stored without calling the superclass's getter.
The example below shows a computed property that's defined by the superclass
and overridden by its subclasses to add an observer.
`willSet` 和 `didSet` 观察者提供了一种观察(并适当地响应)变量或属性值被设置时的方式。当变量或属性首次初始化时,观察者不会被调用。相反,它们仅在初始化上下文之外的情况下,值被设置时被调用。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:willSetdidSet 观察者提供了一种观察(并适当地响应)变量或属性值被设置时的方式
  • 建议:willSetdidSet 观察者提供了一种在变量或属性被赋值时的观察(和响应)方式
  • 原因:when 这里的语序,在中文当中应该提到前面来翻译。以及,中文中,很少有“是当地响应”这样的表达方式,可以不用过于逐字翻译

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:当变量或属性首次初始化时,观察者不会被调用。相反,它们仅在初始化上下文之外的情况下,值被设置时被调用。
  • 建议:变量或属性首次初始化时,不会触发观察者。除了初始化之外的其他赋值行为,均会触发观察者。

补充说明:调用/触发,均可

and overridden by its subclasses to add an observer.
`willSet` 和 `didSet` 观察者提供了一种观察(并适当地响应)变量或属性值被设置时的方式。当变量或属性首次初始化时,观察者不会被调用。相反,它们仅在初始化上下文之外的情况下,值被设置时被调用。

`willSet` 观察者在变量或属性的值被设置之前被调用。新值作为常量传递给 `willSet` 观察者,因此在 `willSet` 子句的实现中无法更改。`didSet` 观察者在新值被设置后立即被调用。与 `willSet` 观察者不同,变量或属性的旧值会传递给 `didSet` 观察者,以防你仍然需要访问它。也就是说,如果你在其自己的 `didSet` 观察者子句中给变量或属性赋值,那么你赋的这个新值将替代刚刚设置并传递给 `willSet` 观察者的值。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:新值作为常量传递给 willSet 观察者,因此在 willSet 子句的实现中无法更改。
  • 建议:新值作为常量传递给 willSet 观察者,因此新值在 willSet 子句的实现中无法更改。
  • 原因:英文中的 therefore it can't be changed 的 it,不建议省略。也就是后句中的 「因此”新值“在」的”新值“,不建议省略


`didSet` 子句在提供 `willSet` 子句时是可选的。同样,在提供 `didSet` 子句时,`willSet` 子句也是可选的。

如果 `didSet` 观察者的主体引用了旧值,则在调用观察者之前会调用 getter,以使旧值可用。否则,新的值会被存储,而不调用超类的 getter。下面的示例显示了一个由超类定义并被其子类重写以添加观察者的计算属性。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:如果 didSet 观察者的主体引用了旧值,则在调用观察者之前会调用 getter,以使旧值可用
  • 建议:如果在 didSet 主体中引用了旧值,为了使旧值可用,在调用 didSet 之前,会先调用 getter。


`didSet` 子句在提供 `willSet` 子句时是可选的。同样,在提供 `didSet` 子句时,`willSet` 子句也是可选的。

如果 `didSet` 观察者的主体引用了旧值,则在调用观察者之前会调用 getter,以使旧值可用。否则,新的值会被存储,而不调用超类的 getter。下面的示例显示了一个由超类定义并被其子类重写以添加观察者的计算属性。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:如果 didSet 观察者的主体引用了旧值,则在调用观察者之前会调用 getter,以使旧值可用
  • 建议:如果在 didSet 主体中引用了旧值,为了使旧值可用,在调用 didSet 之前,会先调用 getter。

// This subclass doesn't refer to oldValue in its observer, so the
// superclass's getter is called only once to print the value.
// 这个子类在它的观察器中没有引用 oldValue
// 因此父类的 getter 只会被调用一次来打印
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:因此父类的 getter 只会被调用一次来打印
  • 建议:因此,父类的 getter 方法中的打印语句只会执行一次

the parameter can be modified inside the scope of the function.
In-out parameters are discussed in detail
in <doc:Declarations#In-Out-Parameters>, below.
每个参数的类型必须明确指定,而不能被推断出来。如果在参数类型前写上 `inout`,则该参数可以在函数的作用域内被修改。关于 in-out 参数的详细讨论请参见下面的 <doc:Declarations#In-Out-Parameters>。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:每个参数的类型必须明确指定,而不能被推断出来。
  • 建议:因为参数类型无法被推断出来,所以函数的每个参数必须明确指定类型。


<!--
TODO: ^-- Add some more here.
-->

A function definition can appear inside another function declaration.
This kind of function is known as a *nested function*.
一个函数定义可以出现在另一个函数声明内部。这种函数被称为*嵌套函数*。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:一个函数定义可以出现在另一个函数声明内部。
  • 建议:在函数内部,可以定义另一个函数。这种定义在函数内部的函数,被称为“嵌套函数”。

The order of arguments in a function call
must match the order of parameters in the function's declaration.
The simplest entry in a parameter list has the following form:
函数参数是一个以逗号分隔的列表,其中每个参数都有几种形式之一。在函数调用中,参数的顺序必须与函数声明中的参数顺序匹配。参数列表中最简单的项具有以下形式:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:函数参数是一个以逗号分隔的列表,其中每个参数都有几种形式之一
  • 建议:函数的参数是一个以逗号分隔的列表,每个参数都可以是不同的类型。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:在函数调用中,参数的顺序必须与函数声明中的参数顺序匹配。参数列表中最简单的项具有以下形式:
  • 建议:函数调用时的参数顺序必须和函数声明时的参数顺序一致。最简单的参数列表有着如下的形式:

By default,
parameter names are also used as argument labels.
For example:
一个参数有一个名称,在函数体内使用,以及一个实参标签,在调用函数或方法时使用。默认情况下,参数名称也用作实参标签。例如:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议:参数有名称和标签,名称用于在函数内访问参数,标签用于在调用函数时指定参数。默认情况下,参数的名称也可以作为标签。例如:

@@ -825,27 +604,20 @@ f(x: 1, y: 2) // both x and y are labeled
Tracking bug is <rdar://problem/35301593>
-->

You can override the default behavior for argument labels
with one of the following forms:
你可以使用以下形式之一覆盖实数标签的默认行为:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:你可以使用以下形式之一覆盖实数标签的默认行为:
  • 建议:你可以使用以下形式(选其一),覆盖参数标签的默认行为:

which can be different from the parameter name.
The corresponding argument must use the given argument label
in function or method calls.
在参数名称之前添加一个名称为参数提供了一个显式的实参标签,该标签可以与参数名称不同。相应的参数在函数或方法调用中必须使用给定的实参标签。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:在参数名称之前添加一个名称为参数提供了一个显式的实参标签,该标签可以与参数名称不同。相应的参数在函数或方法调用中必须使用给定的实参标签。
  • 建议:在参数名称前的名称会作为这个参数的显式实参标签,它可以和参数名称不同。在函数或方法调用时,相对应的参数必须使用这个实参标签。

An underscore (`_`) before a parameter name
suppresses the argument label.
The corresponding argument must have no label in function or method calls.
在参数名称前加下划线(`_`)可以抑制实数标签。相应的参数在函数或方法调用中必须没有标签。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

参数名称前的下划线(_)可以去除参数的实参标签。在函数或方法调用时,相对应的参数必须去除标签。

2. 在函数体内,副本被修改。
3. 当函数返回时,副本的值被赋给原始参数。

这种行为被称为 *copy-in copy-out* 或*按值结果调用*。例如,当一个计算属性或一个带观察者的属性作为 in-out 参数传递时,它的 getter 在函数调用中被调用,而它的 setter 在函数返回时被调用。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:这种行为被称为 copy-in copy-out按值结果调用
  • 建议:这种行为被称为拷入拷出(copy-in copy-out) 或值结果调用(call by value result)。


这种行为被称为 *copy-in copy-out* 或*按值结果调用*。例如,当一个计算属性或一个带观察者的属性作为 in-out 参数传递时,它的 getter 在函数调用中被调用,而它的 setter 在函数返回时被调用。

作为一种优化,当参数是存储在内存物理地址中的值时,函数体内外使用相同的内存位置。优化后的行为被称为*按引用调用*; 它满足了 copy-in copy-out 模型的所有要求,同时消除了复制的开销。请使用 copy-in copy-out 给出的模型编写代码,而不依赖于引用传递优化,以便在有或没有优化的情况下都能正确运行。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:作为一种优化,当参数是存储在内存物理地址中的值时,函数体内外使用相同的内存位置。
  • 建议:作为一种优化手段,当参数值存储在内存中的物理地址时,在函数体内部和外部均会使用同一内存位置。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 原文:优化后的行为被称为按引用调用;
  • 建议:这种优化行为被称为引用调用(call by reference)

@yongfrank
Copy link

@saitjr 这篇已经改好了

@Shinolr Shinolr requested a review from saitjr October 16, 2024 05:26
and the responsibility for the object's lifetime.
Using `borrowing` minimizes overhead when the function
uses the object only transiently.
`borrowing` 修饰符表示函数不会保留参数的值。在这种情况下,调用者保持对对象的所有权,并负责对象的生命周期管理。使用 `borrowing` 可以在函数只临时使用对象时,最大限度地减少开销。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

borrowing 修饰函数参数时,函数不会保留参数的值。在这种情况下,调用者保留对象的所有权,并负责对象的生命周期管理。所以当函数只是临时使用对象时,用 borrowing 修饰可以最大限度地减少开销。


```swift
// As above, but this `isLessThan` also wants to record the smallest value
// 如上所述,但这个 `isLessThan` 还需要记录最小值
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// 同样是 isLessThan 函数,这个 isLessThan 可以将最小值记录下来


```swift
// Usually, this is the last thing you do with a value
// 通常,这是你对一个值执行的最后一件事
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// 通常,这就是最后一次使用 value 了

@@ -1066,22 +799,11 @@ see <doc:Functions#In-Out-Parameters>.
```
-->

#### Borrowing and Consuming Parameters
#### 借用和消耗参数
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

借用和消费参数

store(a: someValue) // This function consumes someValue
print(someValue) // This uses the copy of someValue
// 编译器会在这里插入一个隐式副本
store(a: someValue) // 此函数消耗 someValue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

store(a: someValue) // 此函数消费 someValue

take a variable number of values,
and provide default values
using the following forms:
参数可以通过以下形式被忽略、接受可变数量的值,以及提供默认值:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

参数可以被忽略,数量可以不固定,还可以为其提供默认值,使用形式如下:

see <doc:Types#Function-Type>.
For examples of working with errors that have explicit types,
see <doc:ErrorHandling#Specifying-the-Error-Type>.
函数的类型包括它是否会抛出错误以及它抛出的错误类型。这个子类型关系意味着,例如,你可以在需要抛出错误的上下文中使用不抛出错误的函数。有关抛出错误函数类型的更多信息,请参阅 <doc:Types#Function-Type>。有关处理具有显式类型的错误的示例,请参阅 <doc:ErrorHandling#Specifying-the-Error-Type>。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

函数的类型包括:它是否会抛出错误,以及它抛出的错误类型。非抛出函数是抛出函数的子类型。所以,可以在使用抛出函数的地方使用非抛出函数。有关抛出错误函数类型的更多信息,请参阅 doc:Types#Function-Type。有关处理具有显式类型的错误的示例,请参阅 doc:ErrorHandling#Specifying-the-Error-Type。

@saitjr
Copy link
Member

saitjr commented Oct 20, 2024

剩一个选择性修复的评论,已经 Approve 了

@yongfrank
Copy link

@Shinolr 可以再看一眼👀

@yongfrank yongfrank merged commit 20dd824 into SwiftGGTeam:swift-6-beta-translation Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Completed
Development

Successfully merging this pull request may close these issues.

ReferenceManual / declarations.md ⭐️⭐️⭐️⭐️⭐️
4 participants