Latest web development tutorials

ขั้นตอนการก่อสร้างสวิฟท์

การดำเนินการก่อสร้างคือการใช้อินสแตนซ์ของชั้นโครงสร้างหรือประเภทการแจงนับดำเนินการขั้นตอนการเตรียม กระบวนการนี้เกี่ยวข้องกับการตั้งค่าเริ่มต้นสำหรับแต่ละแอตทริบิวต์และอินสแตนซ์สำหรับการเตรียมการและการดำเนินงานที่จำเป็นในการเริ่มต้น

สวิฟท์คอนสตรัค init () วิธีการ

และวัตถุประสงค์ -C ในตัวสร้างที่แตกต่างกันสร้างสวิฟท์ไม่จำเป็นต้องคืนค่างานหลักของพวกเขาคือเพื่อให้แน่ใจว่าตัวอย่างใหม่จะเสร็จสมบูรณ์ก่อนที่จะใช้งานครั้งแรกเริ่มต้นที่เหมาะสม

อินสแตนซ์ชั้นอาจจะกำหนดงาน Cleanup destructor (deinitializer) หน่วยความจำก่อนเช่นชั้นจะถูกปล่อยออก


การกำหนดเริ่มต้นของการจัดเก็บข้อมูลประเภททรัพย์สิน

การเรียนการสอนและโครงสร้างเมื่ออินสแตนซ์ถูกสร้างขึ้นก็ต้องตั้งค่าเริ่มต้นที่เหมาะสมสำหรับแอตทริบิวต์การจัดเก็บข้อมูลทุกประเภท

เมื่อเก็บได้รับมอบหมายคุณสมบัติในตัวสร้างค่านิยมของพวกเขาจะถูกตั้งค่าได้โดยตรงและไม่ก่อให้เกิดการสังเกตการณ์ทรัพย์สินใด ๆ

คุณสมบัติขั้นตอนการจัดเก็บข้อมูลที่ได้รับมอบหมายในการสร้าง:

  • การสร้างค่าเริ่มต้น

  • ในความหมายแอตทริบิวต์ระบุค่าสถานที่ให้บริการเริ่มต้น

  • เริ่มต้นอินสแตนซ์และบริการโทร init () วิธีการ


นวกรรมิก

นวกรรมิกเรียกว่าเมื่อคุณสร้างตัวอย่างใหม่ของประเภทใดประเภทหนึ่ง รูปแบบที่ง่ายมันจะคล้ายกับวิธีการเช่นไม่มีพารามิเตอร์ใด ๆ ชื่อ init คำหลัก

ไวยากรณ์

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

ตัวอย่าง

โครงสร้างต่อไปนี้กำหนด init ตัวสร้างด้วยไม่มีข้อโต้แย้งและภายในระยะเวลาแอตทริบิวต์ประเภทการจัดเก็บข้อมูลและความกว้างของมูลค่าการเริ่มต้นของ 6 และ 12:

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

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

矩形面积为 72.0

ค่าทรัพย์สินเริ่มต้น

เราสามารถตั้งค่าเริ่มต้นสำหรับการจัดเก็บชนิดคุณสมบัติในคอนสตรัคนั้นนอกจากนี้ยังสามารถตั้งค่าเริ่มต้นเมื่อประกาศสถานที่ให้บริการ

จะช่วยให้คุณใช้ทำความสะอาดสร้างเริ่มต้นชัดเจนและสามารถสรุปได้โดยอัตโนมัติตามประเภทแอตทริบิวต์ค่าเริ่มต้น

ตัวอย่างต่อไปนี้เราต้องการที่จะตั้งค่าเริ่มต้นเมื่อมีการประกาศทรัพย์สิน:

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

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

矩形面积为 72

การกำหนดค่าพารามิเตอร์

คุณสามารถกำหนดสร้างให้ init () พารามิเตอร์ตัวสร้างดังนี้

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

面积为: 72.0
面积为: 432.0

ชื่อพารามิเตอร์ภายในและภายนอก

ฟังก์ชั่นและวิธีการที่มีพารามิเตอร์เดียวกันพารามิเตอร์โครงสร้างนอกจากนี้ยังมีชื่อของพารามิเตอร์ในตัวสร้างสำหรับการใช้งานภายในและภายนอกชื่อพารามิเตอร์ใช้เมื่อเรียกผู้สร้าง

อย่างไรก็ตามการกำหนดค่าไม่เป็นก่อนที่จะมีชื่อเป็นที่รู้จักในวงเล็บเช่นฟังก์ชั่นและวิธีการ ดังนั้นเรียกที่กำหนดคอนสตรัคจะถูกกำหนดโดยส่วนใหญ่จำเป็นต้องเรียกชื่อพารามิเตอร์ตัวสร้างและประเภท

หากคุณไม่ได้ให้ข้อโต้แย้งเมื่อคุณกำหนดตัวสร้างชื่อภายนอกที่สวิฟท์จะสร้างชื่อที่มีชื่อเดียวกันภายในภายนอกสำหรับแต่ละพารามิเตอร์ตัวสร้างโดยอัตโนมัติ

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

ไม่มีชื่อพารามิเตอร์ภายนอก

หากคุณไม่ต้องการที่จะให้ชื่อภายนอกสำหรับพารามิเตอร์นวกรรมิกคุณสามารถใช้ขีดล่าง _ เพื่ออธิบายชื่อที่ปรากฏภายนอก

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

ประเภทแอตทริบิวต์ตัวเลือก

ถ้าชนิดที่กำหนดเองของคุณมีการโต้แย้งตรรกะที่จะช่วยให้การจัดเก็บคุณลักษณะชนิดที่ว่างเปล่าคุณจะต้องกำหนดมันเป็นตัวเลือกประเภทเลือกประเภท (ประเภทแอตทริบิวต์ตัวเลือก)

เมื่อเก็บประกาศคุณสมบัติเป็นตัวเลือกก็จะสามารถเริ่มต้นโดยอัตโนมัติไปยังศูนย์ที่ว่างเปล่า

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

ปรับเปลี่ยนการดำเนินการก่อสร้างสถานที่ให้บริการอย่างต่อเนื่อง

เพียงแค่ก่อนสิ้นขั้นตอนการก่อสร้างสามารถกำหนดค่าของค่าคงที่ที่คุณสามารถเปลี่ยนค่าของแอตทริบิวต์คงที่จุดใด ๆ ในขั้นตอนการก่อสร้าง

ยกตัวอย่างเช่นชั้นแอตทริบิวต์คงที่สามารถกำหนดได้เฉพาะในชั้นการปรับเปลี่ยนขั้นตอนการก่อสร้างของตนไม่สามารถเปลี่ยนแปลงได้ในประเภทรอง

แม้จะมีคุณสมบัติที่มีความยาวอยู่ในขณะนี้เป็นค่าคงที่เรายังคงสามารถตั้งค่าของมันในตัวสร้างของชั้นนี้:

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

ตัวสร้างเริ่มต้น

ตัวสร้างเริ่มต้นก็จะสร้างทั้งหมดของมูลค่าทรัพย์สินที่มีการตั้งอินสแตนซ์เริ่มต้น:

ตัวอย่างต่อไปนี้ชั้นคุณสมบัติทั้งหมด ShoppingListItem มีค่าเริ่มต้นและมันก็ไม่ได้เป็นพ่อของชั้นฐานที่มันจะได้รับโดยอัตโนมัติสามารถตั้งค่าเริ่มต้นสำหรับคุณสมบัติทั้งหมดของ constructor เริ่มต้น

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


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

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

สมาชิกของโครงสร้างสร้างแต่ละ

หากโครงสร้างของคุณสมบัติการจัดเก็บข้อมูลประเภทให้เป็นค่าเริ่มต้นและไม่ให้สร้างที่กำหนดเองของตัวเองพวกเขาโดยอัตโนมัติได้รับสมาชิกของแต่ละตัวสร้าง

เมื่อเราเรียกร้องให้สมาชิกสร้างแต่ละโดยการดำเนินการค่านิยมดั้งเดิมและสมาชิกของชื่อพารามิเตอร์ชื่อแอตทริบิวต์เดียวกันเพื่อความสมบูรณ์ของการกำหนดคุณสมบัติเบื้องต้นของสมาชิก

ตัวอย่างต่อไปนี้กำหนดโครงสร้างสี่เหลี่ยมผืนผ้าซึ่งมีคุณลักษณะที่สองยาวและความกว้าง สวิฟท์จะได้รับมอบหมายตามที่เริ่มต้น 100.0 ของทั้งสองคุณสมบัติ 200.0 โดยอัตโนมัติได้รับมาประเภทดับเบิล

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

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

เนื่องจากคุณสมบัติที่สองการจัดเก็บข้อมูลที่มีค่าเริ่มต้นโครงสร้างสี่เหลี่ยมผืนผ้าโดยอัตโนมัติเป็นสมาชิกของแต่ละตัวสร้าง init (กว้าง: ความสูง :) คุณสามารถใช้มันเพื่อสร้างตัวอย่างใหม่ของสี่เหลี่ยมผืนผ้า

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

ราคาตัวแทนประเภทคอนสตรัค

คอนสตรัคโดยการเรียกก่อสร้างอื่น ๆ เพื่อให้เป็นส่วนหนึ่งของอินสแตนซ์ขั้นตอนการก่อสร้าง กระบวนการนี้เรียกว่าตัวแทนโครงสร้างก็สามารถลดความซ้ำซ้อนรหัสระหว่างการก่อสร้างหลาย

ตัวอย่างต่อไปนี้โครงสร้างที่เรียกว่า Rect ขั้นตอนการก่อสร้างและจุดขนาด:

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) ")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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) 

กฎพร็อกซีคอนสตรัค

ชนิดค่า ชั้นประเภท
มันไม่ได้สนับสนุนการสืบทอดดังนั้นกระบวนการเป็นตัวแทนโครงสร้างค่อนข้างง่ายเป็นตัวแทนอื่น ๆ ที่พวกเขาสามารถคอนสตรัคเพียงเพื่อให้ตัวเอง คุณสามารถใช้อ้างอิง self.init คอนสตรัคอื่น ๆ ที่เป็นชนิดเดียวกันที่มีมูลค่าในตัวสร้างที่กำหนดเอง มันสามารถสืบทอดจากคลาสอื่น ๆ ซึ่งหมายความว่าระดับมีความรับผิดชอบเพื่อให้แน่ใจว่าทั้งหมดของคุณสมบัติที่สืบทอดมาของมันเมื่อโครงสร้างการจัดเก็บชนิดสามารถเริ่มต้นได้อย่างถูกต้อง

มรดกและการก่อสร้างกระบวนการของการเรียน

สวิฟท์มีสองประเภทของการสร้างชั้นเพื่อให้แน่ใจว่าทุกกรณีของคุณสมบัติชั้นจัดเก็บข้อมูลสามารถหาได้ในค่าเริ่มต้นซึ่งมีการระบุคอนสตรัคคอนสตรัคและความสะดวกสบาย

ระบุสร้าง ตัวสร้างความสะดวกสบาย
ตัวสร้างระดับหลัก ระดับค่อนข้างน้อยคอนสตรัคช่วย
สถานที่ทั้งหมดเป็นชั้นที่เริ่มเสนอขึ้นมาและเรียก constructor ของระดับผู้ปกครองขึ้นอยู่กับห่วงโซ่ผู้ปกครองเพื่อให้เกิดการเริ่มต้นของการเรียนผู้ปกครอง คุณสามารถกำหนดตัวสร้างความสะดวกสบายที่จะเรียกระดับเดียวกับที่ระบุไว้ในตัวสร้างและให้ค่าเริ่มต้นสำหรับพารามิเตอร์ นอกจากนี้คุณยังสามารถกำหนดตัวสร้างความสะดวกสบายให้สร้างตัวอย่างของวัตถุประสงค์เฉพาะหรือปัจจัยการผลิตที่เฉพาะเจาะจง
แต่ละชั้นจะต้องมีอย่างน้อยนวกรรมิกระบุ เมื่อจำเป็นเท่านั้นเพื่ออำนวยความสะดวกคอนสตรัคชั้นเรียน
Init(parameters) {
    statements
}
convenience init(parameters) {
      statements
}

ระบุตัวสร้างอินสแตนซ์

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

ตัวอย่างของตัวสร้างความสะดวกสบาย

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

มรดกและตัวสร้างการบรรทุกเกินพิกัด

สวิฟท์ชั้นย่อยไม่สืบทอดสร้างเริ่มต้นของระดับผู้ปกครอง

ตัวสร้างของระดับผู้ปกครองคือการสืบทอดเฉพาะในกรณีที่ความมุ่งมั่นและความปลอดภัย

เมื่อคุณแทนที่นวกรรมิกระดับผู้ปกครองที่ระบุไว้คุณจะต้องเขียนปรับปรุงแทนที่

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

矩形: 4 边
五角型: 5 边

ระบุตัวอย่างคอนสตรัคและความสะดวกสบายก่อสร้าง

ตัวอย่างต่อไปนี้จะแสดงให้เห็นการดำเนินงานที่ระบุไว้ในคอนสตรัค, การก่อสร้างและการอำนวยความสะดวกในการรับมรดกคอนสตรัคอัตโนมัติ

มันมีสองชั้น MainClass กำหนดลำดับชั้น subclass และแสดงให้เห็นว่าพวกเขามีปฏิสัมพันธ์ก่อสร้าง

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)")

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

ตัวสร้างชั้นสามารถล้มเหลว

ถ้าชั้นวัตถุโครงสร้างหรือประเภทการแจงนับก็เป็นไปได้ในการจัดโครงสร้างตัวเองในกระบวนการล้มเหลว, ความล้มเหลวในการกำหนดผู้สร้าง

ตัวแปรเริ่มต้นล้มเหลวด้วยเหตุผลที่เป็นไปได้คือ

  • ที่เข้ามาค่าพารามิเตอร์ที่ไม่ถูกต้อง

  • หายทรัพยากรภายนอกบางอย่างที่จำเป็น

  • มันไม่เป็นไปตามเงื่อนไขบางอย่าง

เพื่อให้ถูกต้องจัดการกับกรณีของกระบวนการการกำหนดค่านี้อาจล้มเหลว

คุณสามารถในชั้นเรียนหรือการกำหนดประเภท enum ของโครงสร้างเพิ่มหนึ่งหรือล้มเหลวมากขึ้นคอนสตรัค ไวยากรณ์เป็นเครื่องหมายคำถามหลังจากที่คำหลัก init Jiatian (init?)

ตัวอย่าง

ในตัวอย่างต่อไปนี้ความหมายของโครงสร้างที่เรียกว่าสัตว์ที่ได้รับการตั้งชื่อสายพันธุ์ชนิด String แอตทริบิวต์ค่าคงที่

ในขณะเดียวกันโครงสร้างยังกำหนดชนิด String พารามิเตอร์ชนิดสามารถล้มเหลวคอนสตรัค ตัวสร้างสามารถล้มเหลวจะใช้ในการตรวจสอบว่าอาร์กิวเมนต์ส่งผ่านไปยังสตริงว่างสตริงว่างสร้างสามารถล้มเหลว, ความล้มเหลวในการสร้างวัตถุที่ประสบความสำเร็จเป็นอย่างอื่น

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

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

动物初始化为长颈鹿

ระบุประเภทคอนสตรัคสามารถล้มเหลว

คุณสามารถมีพารามิเตอร์หนึ่งหรือมากกว่าหนึ่งสามารถกำหนดค่าโดยการสร้างความล้มเหลวที่จะได้รับชนิดนับสมาชิกแจงนับเฉพาะ

ตัวอย่าง

ในตัวอย่างต่อไปนี้ความหมายของชนิดนับชื่อ TemperatureUnit ซึ่งประกอบด้วยสาม enum สมาชิกที่เป็นไปได้ (เคลวินเซลเซียสและฟาเรนไฮต์) และความล้มเหลวที่สามารถใช้ในการหาค่าตัวสร้างตัวละครสมาชิกแจงนับสอดคล้องกัน:

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("这不是一个已定义的温度单位,所以初始化失败。")
}

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

ตัวสร้างชั้นสามารถล้มเหลว

ประเภทค่า (เช่นโครงสร้างหรือระบุชนิด) อาจล้มเหลวคอนสตรัคเมื่อใดและที่จะเรียกก่อสร้างล้มเหลวโดยไม่มีข้อ จำกัด ของพฤติกรรมนี้ใด ๆ

อย่างไรก็ตามคอนสตรัคชั้นสามารถล้มเหลวและตัวแทนเท่านั้นที่สามารถเรียก constructor หมู่เรียนทั้งหมดที่เกิดขึ้นในระดับคุณสมบัติทั้งหมดจะเริ่มต้นหลังจากที่พฤติกรรมการจุดระเบิดความล้มเหลว

ตัวอย่าง

โดยยกตัวอย่างเช่นความหมายของระดับที่เรียกว่า StudRecord เพราะคุณสมบัติ studname เป็นค่าคงที่ดังนั้นเมื่อประสบความสำเร็จในระดับคอนสตรัค StudRecord คุณสมบัติ studname ต้องมีค่าที่ไม่ใช่ศูนย์

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

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

模块为 失败构造器

ครอบคลุมผู้สร้างสามารถล้มเหลว

เช่นเดียวกับการก่อสร้างอื่น ๆ เช่นคุณยังสามารถแทนที่การสร้างชั้นฐานสามารถล้มเหลวด้วยตัวสร้างประเภทรองสามารถล้มเหลว

นอกจากนี้คุณยังสามารถแทนที่โดยสร้างชั้นฐานสามารถล้มเหลวกับความล้มเหลวของการไม่ตัวสร้างประเภทรอง

คุณสามารถใช้ตัวสร้างที่ไม่ล้มเหลวครอบคลุมคอนสตรัคสามารถล้มเหลว แต่ในทางกลับกันมันไม่ทำงาน

ตัวสร้างที่ไม่ล้มเหลวไม่สามารถเรียกตัวแทนคอนสตรัคอาจล้มเหลว

ตัวอย่าง

ตัวอย่างต่อไปนี้จะอธิบายถึงความล้มเหลวและความล้มเหลวไม่สร้าง:

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

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

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

อาจล้มเหลว init คอนสตรัค!

โดยทั่วไปเราเพิ่มเครื่องหมายคำถามหลังจากที่ทาง init คำหลัก (init?) อาจล้มเหลวในการกำหนดตัวสร้าง แต่คุณยังสามารถใช้ init โดยการเพิ่มเครื่องหมายอัศเจรีย์หลังจากที่วิธีการที่จะกำหนดคอนสตรัคล้มเหลว (init!) . ตัวอย่างมีดังนี้

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("学生名为空")
}

เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:

指定了学生名
学生名为空