Learn Swift--constructors (bottom)

Source: Internet
Author: User

Constructor (bottom)constructor that can fail

If an object of a class, struct, or enum type is likely to fail in the process of constructing itself, it is necessary to define a failed constructor for it. The "failure" referred to here means, for example, passing an invalid parameter value to the constructor, or missing some required external resources, or not satisfying some of the necessary conditions.

In order to properly handle situations in which the construction process may fail. You can add one or more failed constructors in the definition of a class, struct, or enumeration type. its syntax is to add a init question mark after the keyword (init?) .

You can fail the constructor to create an object of its own type as an optional type during the construction of the object. You pass the return nil statement to indicate the circumstances under which the failed constructor failed.

struct Animal {let    species:string    init? ( species:string) {        If Species.isempty {return nil}        self.species = species    }}//generation Someanimal This instance, It is important to note that the type of this instance is an optional type (Animal?). Let Someanimal = Animal (species: "giraffe") if let Giraffe = someanimal {    print (giraffe.species)}//generates an instance of the construction process that will fail let anonymouscreature = Animal (species: "") if anonymouscreature = = Nil {    print ("Anonymouscreature is Empty")}

a failed constructor for an enumeration type

You can get a specific enumeration member in an enumeration type by constructing a failed constructor with one or more parameters. It can also cause the construction to fail if the parameter does not meet the conditions you expect.

Enum Temperatureunit {case    Kelvin, Celsius, Fahrenheit    init? (Symbol:character) {        //If the parameter cannot be matched in any case, the construction fails        switch symbol {case        "K": Self            =. Kelvin case        ' C ': self            =. Celsius case        ' F ': self            =. Fahrenheit        default:            return nil        }    }}let kelvinunit = temperatureunit (symbol: "K")   // Kelvinlet unknowunit = temperatureunit (symbol: "X")   //Nil

a failed constructor for an enumeration type with raw values

An enumeration type with the original value comes with a failed constructor, which init?(rawValue:) has a default parameter named with the rawValue same type as the original value type of the enumeration type, and if the value of the parameter can match the original value of the enumeration type member, The constructor constructs an enumeration member with this original value, or the construct fails.

Enum Temperatureunit:character {case    Kelvin = "K", Celsius = "C", Fahrenheit = "F"}let kelvinunit = Temperatureunit ( RawValue: "K")   //Kelvinlet Unknowunit = Temperatureunit (rawValue: "X")   //Nil

class can fail constructors

A failed constructor for a value type, such as a struct or enumeration type, has no limitations on when and where to trigger the construction failure. For example, in the previous example, the struct Animal 's failed constructor triggers the failed behavior, even species before the value of the property is initialized. And for classes, it's not that lucky. A failed constructor for a class can trigger failure behavior only after all class properties have been initialized and when proxy calls between all classes have occurred.

Class Product {let    name:string!    Init? (name:string) {        Self.name = name        //class can fail the constructor before the failure condition is triggered, it must be determined that all properties are initialized        if Name.isempty {return nil}}    

construct failed delivery

The failed constructor also satisfies the construction rules described in the constructor chain . It allows the other failed constructors to be represented horizontally in the same class, struct, and enumeration. Similarly, a failed constructor for a subclass can also be used to proxy the base class's failed constructor.

Whether it is an up-to-agent or a horizontal proxy, if you are acting as a failed constructor, triggering a construction failure during the construction process, the entire construction process will be terminated immediately , and Any subsequent construction code will not be executed.

A failed constructor can also invoke other non-failed constructors. With this method, you can add conditions to the construction failure for the existing construction process.

Class Product {let    name:string!    Init? (name:string) {        Self.name = name        if Name.isempty {return nil}    }}class cartitem:product {let    quantity:int!    Init? (Name:string, Quantity:int) {        self.quantity = quantity        super.init (name:name)        If quantity < 1 {return nil}    }}if let item = Ca Rtitem (Name: "Shirt", quantity:0) {    print ("Item: \ (item.name), quantity: \ (item.quantity)")} else {    print (" Zero shirt ")//print out this sentence}

overriding a failed constructor

As with other constructors, you can override the failed constructors of the base class with the subclass's failed constructor. Or you can also write a failed constructor of a base class with the non-writable constructor of a subclass . The advantage of this is that even if the constructor of the base class is a failed constructor, we can modify it when the constructor of the subclass is not likely to fail in the construction process.

Note that when you rename a failed constructor of a parent class with a non-writable constructor for a subclass, the constructor of the subclass will no longer be able to proxy the failed constructors of the parent class. A non-failed constructor can never be called by a proxy to a failed constructor.

Note: You can use a non-fail constructor to write a failed constructor, but the reverse is not feasible.

Class Document {    var name:string?    This constructor constructs a null instance of the Name property,    init () {}        ///Instead this constructor constructs an instance of name not NULL,    init? ( name:string) {        If Name.isempty {return nil}        self.name = name    }}class automaticallynameddocument:document {    //Rewrite the constructor of the parent class to ensure that the Name property always has the value    override init () {        super.init ()        name = "[Not named]"    }        // Overrides the failed constructor of the parent class as a normal custom constructor, guaranteeing that the Name property always has the value of    override Init (name:string) {        ///due to overriding the failed constructor as a normal custom constructor, So this constructor cannot be proxied up to fail the constructor        Super.init ()        if name.isempty {            self.name = "[No naming]"        } else {            self.name = Name        }}    }

can fail the constructor init!

In general, we init define a failed constructor by adding a question mark after the keyword, but you can also init define a failed constructor by adding an exclamation point in the following way. (init!) The failed constructor constructs an object of a specific type that implicitly resolves an optional type.

You can call the constructor in the init? constructor init! , and vice versa. You can also use init? overrides init! , and vice versa. You can also init invoke the proxy init! , but this triggers an assertion: Does the init! constructor trigger a build failure?

necessary Constructors

Adding a modifier before the constructor of the class required indicates that all subclasses of the class must implement the constructor

Note: If a subclass inherits a constructor that satisfies the requirements of the necessary constructor, you do not need to display an implementation that provides the necessary constructors in the subclass.

Class SomeClass {    required init () {        //Add the implementation code of the necessary constructors    }}class Subclass:someclass {    ///When subclasses override the necessary constructors of the base class , you must also add the required modifier before the constructor of the subclass to ensure that the constructor is the same as necessary when other classes inherit the subclass. When overriding the necessary constructors for the base class, you do not need to add the override modifier    required init () {        //Add subclass the implementation code of the necessary constructor    }}

setting default values for properties by closures and functions

If the default value of a stored-type property requires special customization or preparation, you can use closures or global functions to provide custom default values for their properties. whenever a new type instance of a property is created, the corresponding closure or function is called, and their return value is assigned to the property as a default value.

This type of closure or function typically creates a temporary variable that is the same as the property type, modifies its value to meet the expected initial state, and finally returns the value of the temporary variable as the default value for the property.

Class SomeClass {Let    list: [string:double] = {        var scorelist = ["ASK": 103.5,                         "Alice": 115.8,                         "Alisa" : 118.5]        return scorelist    } ()    //Note closing the curly brace at the end of the closure is followed by a pair of empty parentheses. This is used to tell Swift to execute this closure immediately. If you omit this pair of parentheses, it is equivalent to assigning the closure itself as a value to the property instead of assigning the return value of the closure to the property. }

Learn Swift--constructors (bottom)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.