Latest web development tutorials

ห่วงโซ่ตัวเลือกสวิฟท์

ห่วงโซ่เป็นตัวเลือก (ตัวเลือก Chaining) เป็นวิธีการขอและเรียกร้องทรัพย์สินวิธีการกระบวนการและย่อยสคริปต์เรียกร้องให้มีการร้องขอเป้าหมายหรืออาจจะเป็นศูนย์

ห่วงโซ่ไม่บังคับส่งกลับสองค่า:

  • ถ้าเป้าหมายมีค่าโทรสำเร็จค่าส่งกลับ

  • ถ้าเป้าหมายเป็นศูนย์โทรจะกลับศูนย์

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


ทางเลือกที่ห่วงโซ่เป็นตัวเลือกบังคับให้แก้ไข

โดยการผนวกคุณสมบัติของวิธีการหรือสคริปต์ดัชนีค่าตัวเลือกใส่เครื่องหมายคำถาม (?) คุณสามารถกำหนดโซ่ตัวเลือก

ห่วงโซ่ตัวเลือก '?' เครื่องหมายอัศเจรีย์ (!) ในการบังคับวิธีการขยายตัวคุณสมบัติสคริปต์ห้อยโซ่ตัวเลือก
? ค่าตัวเลือกที่วางอยู่บนต่อมาเรียกวิธีคุณสมบัติสคริปต์ห้อย ! ค่าตัวเลือกที่วางอยู่บนวิธีการโทรต่อมาคุณสมบัติสคริปต์ห้อยที่จะขยายค่าบังคับ
เมื่อการส่งออกที่ไม่จำเป็นเป็นศูนย์ข้อความผิดพลาดที่เป็นมิตรมากขึ้น เมื่อการขยายตัวที่ไม่จำเป็นที่จะไม่มีข้อผิดพลาดการดำเนินการบังคับ

ใช้เครื่องหมายอัศเจรีย์ (!) ตัวอย่างของห่วงโซ่ตัวเลือก

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

//将导致运行时错误
let roomCount = john.residence!.numberOfRooms

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

fatal error: unexpectedly found nil while unwrapping an Optional value

ต้องการที่จะใช้เครื่องหมายอัศเจรีย์ (!) ในการบังคับแยกของมูลค่า numberOfRooms อสังหาริมทรัพย์ที่อยู่อาศัยนี้คนก็จะโยนความผิดพลาด runtime แล้วเพราะไม่มีค่าสามารถนำมาใช้สำหรับการอยู่อาศัยได้รับการแก้ไข

ใช้เครื่องหมายอัศเจรีย์ (!) ตัวอย่างของห่วงโซ่ตัวเลือก

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

// 链接可选residence?属性,如果residence存在则取回numberOfRooms的值
if let roomCount = john.residence?.numberOfRooms {
    print("John 的房间号为 \(roomCount)。")
} else {
    print("不能查看房间号")
}

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

不能查看房间号

เนื่องจากการดำเนินความพยายามเหล่านี้อาจล้มเหลว numberOfRooms โซ่ตัวเลือกจะกลับ Int? ค่าชนิดหรือที่เรียกว่า "ตัวเลือก Int" เมื่อที่อยู่อาศัยเป็นที่ว่างเปล่าเมื่อ (ตัวอย่าง) เลือก Int จะว่างเปล่าดังนั้นจะไม่มีกรณีของ numberOfRooms เข้าถึง

มันควรจะตั้งข้อสังเกตว่าแม้ numberOfRooms ไม่เลือก Int (int?) เมื่อเป็นเช่นนี้ยังเป็นจริง ตราบใดที่ขอเป็นโซ่ตัวเลือกโดยวิธีการของ numberOfRooms สุดท้ายเสมอกลับ Int? แทน Int


รูปแบบการเรียนถูกกำหนดให้เป็นห่วงโซ่ที่เป็นตัวเลือก

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

ตัวอย่าง

รุ่นกำหนดสี่ชั้นเรียนรวมทั้งห่วงโซ่หลายตัวเลือก:

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

ด้วยวิธีการห่วงโซ่ตัวเลือกการโทร

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

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()


if ((john.residence?.printNumberOfRooms()) != nil) {
    print("输出房间号")
} else {
    print("无法输出房间号")
}

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

无法输出房间号

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


โดยใช้โซ่เป็นตัวเลือกสคริปต์โทรห้อย

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

ตัวอย่างที่ 1

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()
if let firstRoomName = john.residence?[0].name {
    print("第一个房间名 \(firstRoomName).")
} else {
    print("无法检索到房间")
}

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

无法检索到房间

สคริปต์มาตรฐานต่อไปเรียกว่าห่วงโซ่ตัวเลือกโดยตรงหลังเครื่องหมายคำถาม circname.print สคริปต์มาตรฐานต่อไปวงเล็บด้านหน้าเพราะ circname.print ห่วงโซ่ไม่จำเป็นพยายามที่จะได้รับค่าตัวเลือก

ตัวอย่างที่ 2

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

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()
let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "客厅"))
johnsHouse.rooms.append(Room(name: "厨房"))
john.residence = johnsHouse

if let firstRoomName = john.residence?[0].name {
    print("第一个房间名为\(firstRoomName)")
} else {
    print("无法检索到房间")
}

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

第一个房间名为客厅

ในการเข้าถึงดัชนีผ่านสาย link ตัวเลือก

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

ตัวอย่าง

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()

let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "客厅"))
johnsHouse.rooms.append(Room(name: "厨房"))
john.residence = johnsHouse

if let firstRoomName = john.residence?[0].name {
    print("第一个房间名为\(firstRoomName)")
} else {
    print("无法检索到房间")
}

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

第一个房间名为客厅

การเข้าถึงเลือกประเภทของดัชนี

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

var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]]
testScores["Dave"]?[0] = 91
testScores["Bev"]?[0]++
testScores["Brian"]?[0] = 72
// the "Dave" array is now [91, 82, 84] and the "Bev" array is now [80, 94, 81]

ตัวอย่างข้างต้นกำหนดอาร์เรย์ testScores มีสองคู่ค่าคีย์ที่สำคัญชนิดสตริงถูกแมปไปอาร์เรย์จำนวนเต็ม

ตัวอย่างนี้สายที่มีการเชื่อมโยงที่ไม่จำเป็นที่จะ "เดฟ" ตั้งค่าเป็นองค์ประกอบแรกของอาร์เรย์ 91 องค์ประกอบแรก +1 "เบฟ" อาร์เรย์และจากนั้นพยายามที่จะ "ไบรอัน" องค์ประกอบแรกของอาร์เรย์ถูกตั้งไว้ที่ 72 .

สองสายแรกที่ประสบความสำเร็จเพราะการปรากฏตัวของทั้งสองคีย์ แต่ที่สำคัญ "ไบรอัน" ในพจนานุกรมไม่ได้อยู่เพื่อให้สายที่สามล้มเหลว


การเชื่อมต่อแบบมัลติลิงค์

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

ถ้าคุณพยายามที่จะได้รับผ่านตัวเลือกห่วงโซ่คุณค่า Int โดยไม่คำนึงถึงวิธีการหลายชั้นเชื่อมโยงเสมอกลับ Int? ในทำนองเดียวกันถ้าคุณพยายามที่จะได้รับผ่านห่วงโซ่ตัวเลือก Int? ราคาโดยไม่คำนึงถึงวิธีการหลายชั้นเชื่อมโยงเสมอกลับ Int?

ตัวอย่างที่ 1

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

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()

if let johnsStreet = john.residence?.address?.street {
    print("John 的地址为 \(johnsStreet).")
} else {
    print("不能检索地址")
}

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

不能检索地址

ตัวอย่างที่ 2

ถ้าคุณตั้งค่าตัวอย่างที่จะอยู่เป็น john.residence.address คุ้มค่าและการตั้งค่าสำหรับที่อยู่สถานที่จริงของทรัพย์สินที่คุณสามารถโซ่หลายชั้นจะได้รับนี้ค่าแอตทริบิวต์ตัวเลือก

class Person {
   var residence: Residence?
}

class Residence {
    
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        get{
            return rooms[i]
        }
        set {
            rooms[i] = newValue
        }
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

class Room {
    let name: String
    init(name: String) { self.name = name }
}

class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}
let john = Person()
john.residence?[0] = Room(name: "浴室")

let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "客厅"))
johnsHouse.rooms.append(Room(name: "厨房"))
john.residence = johnsHouse

if let firstRoomName = john.residence?[0].name {
    print("第一个房间是\(firstRoomName)")
} else {
    print("无法检索房间")
}

เอาท์พุทตัวอย่างข้างต้นคือ

第一个房间是客厅

ฟังก์ชั่นที่ไม่จำเป็นของความคุ้มค่าของการเชื่อมโยงกลับมาที่

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

ตัวอย่าง

class Person {
    var residence: Residence?
}

// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {
    var rooms = [Room]()
    var numberOfRooms: Int {
        return rooms.count
    }
    subscript(i: Int) -> Room {
        return rooms[i]
    }
    func printNumberOfRooms() {
        print("房间号为 \(numberOfRooms)")
    }
    var address: Address?
}

// Room 定义一个name属性和一个设定room名的初始化器
class Room {
    let name: String
    init(name: String) { self.name = name }
}

// 模型中的最终类叫做Address
class Address {
    var buildingName: String?
    var buildingNumber: String?
    var street: String?
    func buildingIdentifier() -> String? {
        if (buildingName != nil) {
            return buildingName
        } else if (buildingNumber != nil) {
            return buildingNumber
        } else {
            return nil
        }
    }
}

let john = Person()

if john.residence?.printNumberOfRooms() != nil {
    print("指定了房间号)")
}  else {
    print("未指定房间号")
}

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

未指定房间号