ขั้นตอนการก่อสร้างสวิฟท์
การดำเนินการก่อสร้างคือการใช้อินสแตนซ์ของชั้นโครงสร้างหรือประเภทการแจงนับดำเนินการขั้นตอนการเตรียม กระบวนการนี้เกี่ยวข้องกับการตั้งค่าเริ่มต้นสำหรับแต่ละแอตทริบิวต์และอินสแตนซ์สำหรับการเตรียมการและการดำเนินงานที่จำเป็นในการเริ่มต้น
สวิฟท์คอนสตรัค 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("学生名为空") }
เอาท์พุทการทำงานของโปรแกรมข้างต้นเป็น:
指定了学生名 学生名为空