Latest web development tutorials

processo di costruzione Swift

processo di costruzione è quello di utilizzare un'istanza di una classe, struttura o tipo di enumerazione effettuato il processo di preparazione. Questo processo comporta l'impostazione dei valori iniziali per ciascun attributo e l'istanza per la preparazione e l'attuazione delle attività di inizializzazione necessarie.

Metodo Swift costruttore init ().

E Objective-C nel costruttore diverso, il costruttore Swift non ha bisogno di restituire un valore, il loro compito principale è quello di garantire che la nuova istanza viene completato prima della corretta inizializzazione primo utilizzo.

istanze di classi possono essere definiti lavoro di pulizia distruttore (deinitializer) memoria prima istanza di una classe viene rilasciato.


L'assegnazione iniziale della proprietà di archiviazione di tipo

Le classi e le strutture in cui viene creata un'istanza, si deve impostare il valore iniziale appropriato per tutti gli attributi di storage di tipo.

Quando si ripone assegnazione di proprietà nel costruttore, i loro valori sono impostati direttamente e non provoca alcun osservatore proprietà.

Stoccaggio processo di assegnazione di proprietà nel costruttore:

  • Creazione del valore iniziale.

  • Nella definizione attributo specifica i valori delle proprietà di default.

  • Inizializza un'istanza, e chiama il metodo init ().


costruttore

Il costruttore viene chiamato quando si crea una nuova istanza di un tipo particolare. La sua forma più semplice è simile a un metodo di istanza senza alcun parametro, il nome di init parola chiave.

grammatica

init()
{
    // 实例化后执行的代码
}

Esempi

La seguente struttura definisce l'init un costruttore senza argomenti, e dentro il tipo di archiviazione attributo lunghezza e la larghezza del valore di inizializzazione di 6 e 12:

struct rectangle {
    var length: Double
    var breadth: Double
    init() {
        length = 6
        breadth = 12
    }
}
var area = rectangle()
print("矩形面积为 \(area.length*area.breadth)")

L'output sopra l'esecuzione del programma è il seguente:

矩形面积为 72.0

i valori delle proprietà di default

Siamo in grado di impostare i valori iniziali per la proprietà di archiviazione di tipo nel costruttore, inoltre, è possibile impostare un valore predefinito quando una dichiarazione di proprietà.

Esso consente di utilizzare il pulitore costruttore di default, più chiaro, e può automaticamente dedurre dall'attributo tipo di valore predefinito.

Il seguente esempio vogliamo impostare il valore predefinito quando una dichiarazione di proprietà:

struct rectangle {
	// 设置默认值
    var length = 6
    var breadth = 12
}
var area = rectangle()
print("矩形的面积为 \(area.length*area.breadth)")

L'output sopra l'esecuzione del programma è il seguente:

矩形面积为 72

parametri di configurazione

È possibile definire il costruttore a condizione che il parametro del costruttore init (), come segue:

struct Rectangle {
    var length: Double
    var breadth: Double
    var area: Double
    
    init(fromLength length: Double, fromBreadth breadth: Double) {
        self.length = length
        self.breadth = breadth
        area = length * breadth
    }
    
    init(fromLeng leng: Double, fromBread bread: Double) {
        self.length = leng
        self.breadth = bread
        area = leng * bread
    }
}

let ar = Rectangle(fromLength: 6, fromBreadth: 12)
print("面积为: \(ar.area)")

let are = Rectangle(fromLeng: 36, fromBread: 12)
print("面积为: \(are.area)")

L'output sopra l'esecuzione del programma è il seguente:

面积为: 72.0
面积为: 432.0

nome del parametro interno ed esterno

Funzioni e metodi con gli stessi parametri, parametri strutturali ci sono anche il nome di un parametro nel costruttore per uso interno e nomi dei parametri esterni utilizzati quando si chiama un costruttore.

Tuttavia, la configurazione non è come prima c'è un nome riconoscibile in parentesi come funzioni e metodi. Quindi chiamare il costruttore, il costruttore è determinata principalmente dalla necessità di chiamare i nomi dei parametri costruttore e tipi.

Se non si forniscono argomenti quando si definisce il nome esterno del costruttore, Swift genererà automaticamente un nome con lo stesso nome interno esterno per ogni parametro del costruttore.

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
    }
}

// 创建一个新的Color实例,通过三种颜色的外部参数名来传值,并调用构造器
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)

print("red 值为: \(magenta.red)")
print("green 值为: \(magenta.green)")
print("blue 值为: \(magenta.blue)")

// 创建一个新的Color实例,通过三种颜色的外部参数名来传值,并调用构造器
let halfGray = Color(white: 0.5)
print("red 值为: \(halfGray.red)")
print("green 值为: \(halfGray.green)")
print("blue 值为: \(halfGray.blue)")

L'output sopra l'esecuzione del programma è il seguente:

red 值为: 1.0
green 值为: 0.0
blue 值为: 1.0
red 值为: 0.5
green 值为: 0.5
blue 值为: 0.5

Nessun nome del parametro esterno

Se non si desidera fornire nome esterno per un parametro del costruttore, è possibile utilizzare un trattino basso _ per descrivere il suo nome display esterno.

struct Rectangle {
    var length: Double
    
    init(frombreadth breadth: Double) {
        length = breadth * 10
    }
    
    init(frombre bre: Double) {
        length = bre * 30
    }
    //不提供外部名字
    init(_ area: Double) {
        length = area
    }
}

// 调用不提供外部名字
let rectarea = Rectangle(180.0)
print("面积为: \(rectarea.length)")

// 调用不提供外部名字
let rearea = Rectangle(370.0)
print("面积为: \(rearea.length)")

// 调用不提供外部名字
let recarea = Rectangle(110.0)
print("面积为: \(recarea.length)")

L'output sopra l'esecuzione del programma è il seguente:

面积为: 180.0
面积为: 370.0
面积为: 110.0

Attributi opzionali Tipo

Se il vostro tipo personalizzato contiene un argomento logico per consentire vuoti gli attributi di storage di tipo, è necessario definire come un tipo opzionale opzionale di Tipo (opzionale tipo di attributo).

Quando si conserva dichiarazione di proprietà è facoltativo, verrà inizializzato automaticamente a zero vuoto.

struct Rectangle {
    var length: Double?
    
    init(frombreadth breadth: Double) {
        length = breadth * 10
    }
    
    init(frombre bre: Double) {
        length = bre * 30
    }
    
    init(_ area: Double) {
        length = area
    }
}

let rectarea = Rectangle(180.0)
print("面积为:\(rectarea.length)")

let rearea = Rectangle(370.0)
print("面积为:\(rearea.length)")

let recarea = Rectangle(110.0)
print("面积为:\(recarea.length)")

L'output sopra l'esecuzione del programma è il seguente:

面积为:Optional(180.0)
面积为:Optional(370.0)
面积为:Optional(110.0)

Modificare processo di costruzione Proprietà costante

Poco prima della fine del processo di costruzione può determinare il valore di una costante, è possibile modificare il valore degli attributi costante in qualsiasi punto nel processo di costruzione.

Per un'istanza di classe, il suo attributo costante può essere definito solo nelle sue modificazioni processo di costruzione di classe, non può essere modificato in una sottoclasse.

Nonostante la proprietà length è ormai è una costante, possiamo ancora impostare il suo valore nel costruttore della sua classe:

struct Rectangle {
    let length: Double?
    
    init(frombreadth breadth: Double) {
        length = breadth * 10
    }
    
    init(frombre bre: Double) {
        length = bre * 30
    }
    
    init(_ area: Double) {
        length = area
    }
}

let rectarea = Rectangle(180.0)
print("面积为:\(rectarea.length)")

let rearea = Rectangle(370.0)
print("面积为:\(rearea.length)")

let recarea = Rectangle(110.0)
print("面积为:\(recarea.length)")

L'output sopra l'esecuzione del programma è il seguente:

面积为:Optional(180.0)
面积为:Optional(370.0)
面积为:Optional(110.0)

Il costruttore di default

Il costruttore di default sarà sufficiente creare tutti i valori delle proprietà sono impostate per l'istanza predefinita:

Gli esempi che seguono, tutte le proprietà ShoppingListItem classe ha un valore di default, e non è il padre della classe base, otterrà automaticamente un possibile impostare i valori di default per tutte le proprietà del costruttore di default

class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()


print("名字为: \(item.name)")
print("数理为: \(item.quantity)")
print("是否付款: \(item.purchased)")

L'output sopra l'esecuzione del programma è il seguente:

名字为: nil
数理为: 1
是否付款: false

Ogni membro della struttura costruttore

Se la struttura di tutte le proprietà di archiviazione di tipo forniscono valori di default e non forniscono loro costruttore personalizzato, ottengono automaticamente ogni membro di un costruttore.

Quando chiamiamo a ciascun membro del costruttore, eseguendo i valori tradizionali e dei membri dello stesso attributo name nome del parametro per completare l'assegnazione iniziale di proprietà dei membri.

L'esempio seguente definisce una struttura rettangolare, che contiene la lunghezza di due attributi e in largo. Swift può essere assegnato in base alla prima 100,0 di queste due proprietà, 200.0 derivano automaticamente il loro tipo Double.

struct Rectangle {
    var length = 100.0, breadth = 200.0
}
let area = Rectangle(length: 24.0, breadth: 32.0)

print("矩形的面积: \(area.length)")
print("矩形的面积: \(area.breadth)")

Dal momento che le proprietà di due contenitori hanno valori di default, strutture rettangolo automaticamente un membro di ogni init costruttore (larghezza: altezza :). È possibile utilizzarlo per creare una nuova istanza di Rectangle.

L'output sopra l'esecuzione del programma è il seguente:

名字为: nil
矩形的面积: 24.0
矩形的面积: 32.0

Valore Agente tipo costruttore

Costruttore chiamando altri costruttori per completare una parte dell'istanza del processo di costruzione. Questo processo è chiamato agente di struttura, si può ridurre la duplicazione del codice tra più costruttori.

Gli esempi che seguono, Rect struttura chiamata processo di costruzione e Point Superficie:

struct Size {
    var width = 0.0, height = 0.0
}
struct Point {
    var x = 0.0, y = 0.0
}

struct Rect {
    var origin = Point()
    var size = Size()
    init() {}
    init(origin: Point, size: Size) {
        self.origin = origin
        self.size = size
    }
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}


// origin和size属性都使用定义时的默认值Point(x: 0.0, y: 0.0)和Size(width: 0.0, height: 0.0):
let basicRect = Rect()
print("Size 结构体初始值: \(basicRect.size.width, basicRect.size.height) ")
print("Rect 结构体初始值: \(basicRect.origin.x, basicRect.origin.y) ")

// 将origin和size的参数值赋给对应的存储型属性
let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
    size: Size(width: 5.0, height: 5.0))

print("Size 结构体初始值: \(originRect.size.width, originRect.size.height) ")
print("Rect 结构体初始值: \(originRect.origin.x, originRect.origin.y) ")


//先通过center和size的值计算出origin的坐标。
//然后再调用(或代理给)init(origin:size:)构造器来将新的origin和size值赋值到对应的属性中
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
    size: Size(width: 3.0, height: 3.0))

print("Size 结构体初始值: \(centerRect.size.width, centerRect.size.height) ")
print("Rect 结构体初始值: \(centerRect.origin.x, centerRect.origin.y) ")

L'output sopra l'esecuzione del programma è il seguente:

Size 结构体初始值: (0.0, 0.0) 
Rect 结构体初始值: (0.0, 0.0) 
Size 结构体初始值: (5.0, 5.0) 
Rect 结构体初始值: (2.0, 2.0) 
Size 结构体初始值: (3.0, 3.0) 
Rect 结构体初始值: (2.5, 2.5) 

regole di costruzione del proxy

valore Tipo Tipo Classe
Esso non supporta l'ereditarietà, in modo che il processo è relativamente semplice agente struttura, mentre altri agenti possono solo costruttore di dotarsi. È possibile utilizzare riferimento self.init altro costruttore appartenenti allo stesso tipo di valore in un costruttore personalizzato. Si può ereditare da altre classi, il che significa che la classe ha la responsabilità di garantire tutte le sue proprietà ereditate quando la struttura di stoccaggio-tipo può essere inizializzato correttamente.

Ereditarietà e la costruzione processo della classe

Swift fornisce due tipi di costruttore di classe al fine di garantire che tutte le istanze delle proprietà di classe di memorizzazione possono essere ottenuti in valori iniziali, che sono specificati costruttore e costruttore di convenienza.

Specifica il costruttore costruttore convenienza
Il costruttore della classe principale Classe relativamente minore, costruttore assistito
Tutte le proprietà viene inizializzata classe offerto e chiamare il costruttore della classe genitore in base alla catena di genitore per raggiungere l'inizializzazione della classe padre. È possibile definire costruttore convenienza per chiamare la stessa classe, come specificato nel costruttore, e fornisce i valori di default per i parametri. È inoltre possibile definire costruttore convenienza di creare un'istanza di un particolare scopo o ingressi specifici.
Ogni classe deve avere almeno un costruttore specificato Solo quando è necessario per facilitare il costruttore della classe
Init(parameters) {
    statements
}
convenience init(parameters) {
      statements
}

Specifica il costruttore di istanza

class mainClass {
    var no1 : Int // 局部存储变量
    init(no1 : Int) {
        self.no1 = no1 // 初始化
    }
}
class subClass : mainClass {
    var no2 : Int // 新的子类存储变量
    init(no1 : Int, no2 : Int) {
        self.no2 = no2 // 初始化
        super.init(no1:no1) // 初始化超类
    }
}

let res = mainClass(no1: 10)
let res2 = subClass(no1: 10, no2: 20)

print("res 为: \(res.no1)")
print("res2 为: \(res2.no1)")
print("res2 为: \(res2.no2)")

L'output sopra l'esecuzione del programma è il seguente:

res 为: 10
res 为: 10
res 为: 20

Esempi di costruttore di convenienza

class mainClass {
    var no1 : Int // 局部存储变量
    init(no1 : Int) {
        self.no1 = no1 // 初始化
    }
}

class subClass : mainClass {
    var no2 : Int
    init(no1 : Int, no2 : Int) {
        self.no2 = no2
        super.init(no1:no1)
    }
    // 便利方法只需要一个参数
    override convenience init(no1: Int)  {
        self.init(no1:no1, no2:0)
    }
}
let res = mainClass(no1: 20)
let res2 = subClass(no1: 30, no2: 50)

print("res 为: \(res.no1)")
print("res2 为: \(res2.no1)")
print("res2 为: \(res2.no2)")

L'output sopra l'esecuzione del programma è il seguente:

res 为: 20
res2 为: 30
res2 为: 50

Ereditarietà e costruttore di sovraccarico

Swift sottoclasse non eredita il costruttore di default della classe padre.

Il costruttore della classe genitore è ereditato solo nella determinazione caso e la sicurezza.

Quando si sostituisce un costruttore della classe padre specificato, è necessario scrivere un modificatore override.

class SuperClass {
    var corners = 4
    var description: String {
        return "\(corners) 边"
    }
}
let rectangle = SuperClass()
print("矩形: \(rectangle.description)")

class SubClass: SuperClass {
    override init() {  //重载构造器
        super.init()
        corners = 5
    }
}

let subClass = SubClass()
print("五角型: \(subClass.description)")

L'output sopra l'esecuzione del programma è il seguente:

矩形: 4 边
五角型: 5 边

Specifica gli esempi del costruttore e la convenienza costruttori

Il seguente esempio dimostrerà l'operazione specificata nel costruttore, costruttori e facilitare la successione automatica costruttore.

Esso contiene due classi MainClass, gerarchia di classi SubClass definiti, e dimostrare come la loro interazione costruttori.

class MainClass {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    convenience init() {
        self.init(name: "[匿名]")
    }
}
let main = MainClass(name: "w3big")
print("MainClass 名字为: \(main.name)")

let main2 = MainClass()
print("没有对应名字: \(main2.name)")

class SubClass: MainClass {
    var count: Int
    init(name: String, count: Int) {
        self.count = count
        super.init(name: name)
    }
    
    override convenience init(name: String) {
        self.init(name: name, count: 1)
    }
}

let sub = SubClass(name: "w3big")
print("MainClass 名字为: \(sub.name)")

let sub2 = SubClass(name: "w3big", count: 3)
print("count 变量: \(sub2.count)")

L'output sopra l'esecuzione del programma è il seguente:

MainClass 名字为: w3big
没有对应名字: [匿名]
MainClass 名字为: w3big
count 变量: 3

Il costruttore della classe può fallire

Se una classe, oggetto, struttura, o il tipo di enumerazione, è possibile strutturarsi nel processo non riesce, l'incapacità di definire un costruttore.

inizializzazione delle variabili falliti possibili ragioni sono:

  • Incoming valore del parametro non valido.

  • Mancano alcune risorse esterne necessarie.

  • Essa non ha soddisfatto determinate condizioni.

Al fine di gestire adeguatamente il caso di questo processo di configurazione può riuscire.

È possibile in una definizione di tipo di classe, o enum della struttura, aggiungere uno o più costruttore fallito. La sintassi è un punto interrogativo dopo l'init parola chiave Jiatian (init?).

Esempi

Nel seguente esempio, la definizione di una struttura denominata animale, che ha chiamato le specie, il tipo String attributo costanti.

Nel frattempo, la struttura definisce anche una con una specie di parametri di tipo String può fallire costruttore. Il costruttore può fallire, viene utilizzata per verificare se l'argomento passato a una stringa vuota, una stringa vuota, il costruttore può fallire, la mancata costruzione di un oggetto, altrimenti il ​​successo.

struct Animal {
    let species: String
    init?(species: String) {
        if species.isEmpty { return nil }
        self.species = species
    }
}

//通过该可失败构造器来构建一个Animal的对象,并检查其构建过程是否成功
// someCreature 的类型是 Animal? 而不是 Animal
let someCreature = Animal(species: "长颈鹿")

// 打印 "动物初始化为长颈鹿"
if let giraffe = someCreature {
    print("动物初始化为\(giraffe.species)")
}

L'output sopra l'esecuzione del programma è il seguente:

动物初始化为长颈鹿

Tipo costruttore enumerato può fallire

È possibile con uno o più parametri possono essere configurati dal costruttore non è riuscito a ottenere un tipo enumerato i membri di enumerazione specifici.

Esempi

Nel seguente esempio, la definizione di un tipo enumerato nome TemperatureUnit. Che contiene tre possibili membro enum (Kelvin, Celsius, Fahrenheit e) e un fallimento può essere utilizzato per trovare i valori costruttore personaggio corrispondente membri di enumerazione:

enum TemperatureUnit {
	// 开尔文,摄氏,华氏
    case Kelvin, Celsius, Fahrenheit
    init?(symbol: Character) {
        switch symbol {
        case "K":
            self = .Kelvin
        case "C":
            self = .Celsius
        case "F":
            self = .Fahrenheit
        default:
            return nil
        }
    }
}


let fahrenheitUnit = TemperatureUnit(symbol: "F")
if fahrenheitUnit != nil {
    print("这是一个已定义的温度单位,所以初始化成功。")
}

let unknownUnit = TemperatureUnit(symbol: "X")
if unknownUnit == nil {
    print("这不是一个已定义的温度单位,所以初始化失败。")
}

L'output sopra l'esecuzione del programma è il seguente:

这是一个已定义的温度单位,所以初始化成功。
这不是一个已定义的温度单位,所以初始化失败。

Il costruttore della classe può fallire

I tipi di valore (come le strutture o tipo enumerato) potrebbero non riuscire costruttore, quando e dove per innescare la costruzione fallisce senza alcuna limitazione di questo comportamento.

Tuttavia, il costruttore della classe può fallire e l'agente può solo chiamare il costruttore tra tutte le classi si è verificato in tutte le proprietà della classe vengono inizializzati dopo comportamento mancata accensione.

Esempi

Con l'esempio, la definizione di una classe denominata StudRecord perché la proprietà studname è una costante, quindi una volta il successo di classe StudRecord costruttore, proprietà studname deve avere un valore non-zero.

class StudRecord {
    let studname: String!
    init?(studname: String) {
        self.studname = studname
        if studname.isEmpty { return nil }
    }
}
if let stname = StudRecord(studname: "失败构造器") {
    print("模块为 \(stname.studname)")
}

L'output sopra l'esecuzione del programma è il seguente:

模块为 失败构造器

Coprendo un costruttore può fallire

Come altri costruttori, come, si può anche ignorare il costruttore della classe base può riuscire con il costruttore della sottoclasse può fallire.

È anche possibile sostituire da un costruttore della classe base può fallire con il fallimento della non-costruttore della sottoclasse.

È possibile utilizzare un costruttore non riuscita che copre un costruttore può fallire, ma a sua volta, non funziona.

Un costruttore non fallito non può mai chiamare un agente potrebbe non riuscire costruttore.

Esempi

L'esempio che segue descrive un fallimento e non fallimento Costruttore:

class Planet {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    convenience init() {
        self.init(name: "[No Planets]")
    }
}
let plName = Planet(name: "Mercury")
print("行星的名字是: \(plName.name)")

let noplName = Planet()
print("没有这个名字的行星: \(noplName.name)")

class planets: Planet {
    var count: Int
    
    init(name: String, count: Int) {
        self.count = count
        super.init(name: name)
    }
    
    override convenience init(name: String) {
        self.init(name: name, count: 1)
    }
}

L'output sopra l'esecuzione del programma è il seguente:

行星的名字是: Mercury
没有这个名字的行星: [No Planets]

Potrebbe non riuscire costruttore init!

In generale, si aggiunge un punto interrogativo dopo il modo in cui parola chiave init (init?) Può riuscire a definire un costruttore, ma è anche possibile utilizzare il init aggiungendo un punto esclamativo dopo il modo di definire un costruttore fallito (init!) . Esempi sono i seguenti:

struct StudRecord {
    let stname: String
    
    init!(stname: String) {
        if stname.isEmpty {return nil }
        self.stname = stname
    }
}

let stmark = StudRecord(stname: "w3big")
if let name = stmark {
    print("指定了学生名")
}

let blankname = StudRecord(stname: "")
if blankname == nil {
    print("学生名为空")
}

L'output sopra l'esecuzione del programma è il seguente:

指定了学生名
学生名为空