Initialization构造函数(一)

Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.

初始化是准备要使用的类、结构或枚举的实例的过程。这个过程涉及为该实例上存储的每个属性设置一个初始值,并在新实例准备好使用之前执行任何其他设置或初始化。

You implement this initialization process by defining initializers, which are like special methods that can be called to create a new instance of a particular type. Unlike Objective-C initializers, Swift initializers do not return a value. Their primary role is to ensure that new instances of a type are correctly initialized before they are used for the first time.
通过定义初始化器来实现这个初始化过程,初始化器类似于可以调用的特殊方法来创建特定类型的新实例。与Objective-C初始化器不同,Swift初始化器不返回值。它们的主要作用是确保在首次使用类型的新实例之前正确初始化它们。

Instances of class types can also implement a deinitializer, which performs any custom cleanup just before an instance of that class is deallocated. For more information about deinitializers, see Deinitialization.
类类型的实例还可以实现deinitializer,它在释放该类的实例之前执行任何自定义清理。有关还原程序的更多信息,请参见还原。

Setting Initial Values for Stored Properties

为存储的属性设置初始值

Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.
在创建类或结构的实例之前,类和结构必须将其存储的所有属性设置为适当的初始值。存储的属性不能保持不确定状态。

You can set an initial value for a stored property within an initializer, or by assigning a default property value as part of the property’s definition. These actions are described in the following sections.
您可以在初始化器中为存储的属性设置初始值,或者通过将默认属性值指定为属性定义的一部分来设置。下面几节将描述这些操作。

NOTE
When you assign a default value to a stored property, or set its initial value within an initializer, the value of that property is set directly, without calling any property observers.
当您为存储的属性指定默认值,或在初始化器中设置其初始值时,将直接设置该属性的值,而不调用任何属性观察者。

Initializers

Initializers are called to create a new instance of a particular type. In its simplest form, an initializer is like an instance method with no parameters, written using the init keyword:

调用初始化器来创建特定类型的新实例。最简单的形式是,初始化器就像一个没有参数的实例方法,使用init关键字编写:

init() {
    // perform some initialization here
}

The example below defines a new structure called Fahrenheit to store temperatures expressed in the Fahrenheit scale. The Fahrenheit structure has one stored property, temperature, which is of type Double:
下面的示例定义了一个名为华氏温度的新结构来存储以华氏温标表示的温度。华氏结构有一个存储属性,温度,类型为Double:

struct Fahrenheit {
    var temperature: Double
    init() {
        temperature = 32.0
    }
}
var f = Fahrenheit()
print("The default temperature is \(f.temperature)° Fahrenheit")
// Prints "The default temperature is 32.0° Fahrenheit"

The structure defines a single initializer, init, with no parameters, which initializes the stored temperature with a value of 32.0 (the freezing point of water in degrees Fahrenheit).
该结构定义了一个没有参数的初始化器init,初始化存储的温度值为32.0(以华氏度为单位的水的冰点)。

Default Property Values

默认的属性值

You can set the initial value of a stored property from within an initializer, as shown above. Alternatively, specify a default property value as part of the property’s declaration. You specify a default property value by assigning an initial value to the property when it is defined.
您可以在初始化器中设置存储属性的初始值,如上所示。或者,指定默认属性值作为属性声明的一部分。通过在属性定义时为其分配初始值来指定默认属性值。

NOTE

If a property always takes the same initial value, provide a default value rather than setting a value within an initializer. The end result is the same, but the default value ties the property’s initialization more closely to its declaration. It makes for shorter, clearer initializers and enables you to infer the type of the property from its default value. The default value also makes it easier for you to take advantage of default initializers and initializer inheritance, as described later in this chapter.
请注意

如果属性总是采用相同的初始值,则提供默认值,而不是在初始化器中设置值。最终结果是相同的,但是默认值将属性的初始化更紧密地与其声明联系在一起。它使初始化器更短、更清晰,并允许您从属性的默认值推断属性的类型。默认值还使您更容易利用默认初始化器和初始化器继承,如本章后面所述。

You can write the Fahrenheit structure from above in a simpler form by providing a default value for its temperature property at the point that the property is declared:
您可以从上面以一种更简单的形式编写华氏温度结构,方法是在声明该属性时为其温度属性提供一个默认值:

struct Fahrenheit {
    var temperature = 32.0
}

Customizing Initialization

自定义初始化

You can customize the initialization process with input parameters and optional property types, or by assigning constant properties during initialization, as described in the following sections.
您可以使用输入参数和可选的属性类型来定制初始化过程,或者通过在初始化期间分配常量属性来定制初始化过程,如下面的部分所述。

Initialization Parameters

初始化参数
You can provide initialization parameters as part of an initializer’s definition, to define the types and names of values that customize the initialization process. Initialization parameters have the same capabilities and syntax as function and method parameters.
可以将初始化参数作为初始化器定义的一部分提供,以定义自定义初始化过程的值的类型和名称。初始化参数具有与函数和方法参数相同的功能和语法。

The following example defines a structure called Celsius, which stores temperatures expressed in degrees Celsius. The Celsius structure implements two custom initializers called init(fromFahrenheit:) and init(fromKelvin:), which initialize a new instance of the structure with a value from a different temperature scale:
下面的示例定义了一个名为摄氏度的结构,它存储以摄氏度表示的温度。摄氏度结构实现了两个自定义初始化器,分别名为init(fromFahrenheit:)和init(fromKelvin:),它们使用不同温度级别的值初始化结构的新实例:

struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius is 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius is 0.0

The first initializer has a single initialization parameter with an argument label of fromFahrenheit and a parameter name of fahrenheit. The second initializer has a single initialization parameter with an argument label of fromKelvin and a parameter name of kelvin. Both initializers convert their single argument into the corresponding Celsius value and store this value in a property called temperatureInCelsius.

第一个初始化器有一个初始化参数,参数标签为fromFahrenheit,参数名称为fahrenheit。第二个初始化器有一个初始化参数,参数标签为fromKelvin,参数名为kelvin。两个初始化器都将它们的单个参数转换为相应的摄氏度值,并将该值存储在一个名为temperatureInCelsius的属性中。

Parameter Names and Argument Labels

参数名称和参数标签

As with function and method parameters, initialization parameters can have both a parameter name for use within the initializer’s body and an argument label for use when calling the initializer.

与函数和方法参数一样,初始化参数可以有用于初始化器主体内的参数名称,也可以有用于调用初始化器时的参数标签。

However, initializers do not have an identifying function name before their parentheses in the way that functions and methods do. Therefore, the names and types of an initializer’s parameters play a particularly important role in identifying which initializer should be called. Because of this, Swift provides an automatic argument label for every parameter in an initializer if you don’t provide one.
但是,初始化器的圆括号前不像函数和方法那样有标识函数名。因此,初始化器参数的名称和类型在确定应该调用哪个初始化器时起着特别重要的作用。因此,如果不提供初始化器中的每个参数,Swift将为它们提供一个自动参数标签。

The following example defines a structure called Color, with three constant properties called red, green, and blue. These properties store a value between 0.0 and 1.0 to indicate the amount of red, green, and blue in the color.
下面的示例定义了一个名为Color的结构,该结构具有三个常量属性,即红色、绿色和蓝色。这些属性存储在0.0到1.0之间的值,以指示颜色中红色、绿色和蓝色的数量。

Color provides an initializer with three appropriately named parameters of type Double for its red, green, and blue components. Color also provides a second initializer with a single white parameter, which is used to provide the same value for all three color components.
Color为其红色、绿色和蓝色组件提供了一个具有三个适当命名的参数Double类型的初始化器。Color还提供了带有一个白色参数的第二个初始化器,该参数用于为所有三个颜色组件提供相同的值。

struct Color {
    let red, green, blue: Double
    init(red: Double, green: Double, blue: Double) {
        self.red   = red
        self.green = green
        self.blue  = blue
    }
    init(white: Double) {
        red   = white
        green = white
        blue  = white
    }
}

Both initializers can be used to create a new Color instance, by providing named values for each initializer parameter:
两个初始化器都可以用来创建一个新的颜色实例,方法是为每个初始化器参数提供命名值:

let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
let halfGray = Color(white: 0.5)

Note that it is not possible to call these initializers without using argument labels. Argument labels must always be used in an initializer if they are defined, and omitting them is a compile-time error:
注意,不使用参数标签是不可能调用这些初始化器的。如果定义了参数标签,则必须始终在初始化器中使用它们,省略它们是编译时错误:

let veryGreen = Color(0.0, 1.0, 0.0)
// this reports a compile-time error - argument labels are required

Initializer Parameters Without Argument Labels

没有参数标签的初始化器参数
If you do not want to use an argument label for an initializer parameter, write an underscore (_) instead of an explicit argument label for that parameter to override the default behavior.
如果您不想为初始化器参数使用参数标签,请为该参数编写下划线(_),而不是显式的参数标签,以覆盖默认行为。

Here’s an expanded version of the Celsius example from Initialization Parameters above, with an additional initializer to create a new Celsius instance from a Double value that is already in the Celsius scale:

下面是上面的初始化参数的摄氏度示例的扩展版本,其中有一个附加的初始化器,用于从摄氏度级别中的一个双值创建一个新的摄氏度实例:

struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
    init(_ celsius: Double) {
        temperatureInCelsius = celsius
    }
}
let bodyTemperature = Celsius(37.0)
// bodyTemperature.temperatureInCelsius is 37.0

The initializer call Celsius(37.0) is clear in its intent without the need for an argument label. It is therefore appropriate to write this initializer as init(_ celsius: Double) so that it can be called by providing an unnamed Double value.

初始化器调用摄氏度(37.0)的意图很清楚,不需要参数标签。因此,将这个初始化器编写为init(_ celsius:Double)是合适的,这样就可以通过提供一个未命名的Double值来调用它。

猜你喜欢

转载自blog.csdn.net/weixin_34122810/article/details/87039501