查詢,調(diào)用屬性,下標(biāo)和方法上的一個(gè)可選可能 'nil' 的過程被定義為可選的鏈??蛇x鏈返回兩個(gè)值
如果可選包含一個(gè)值,然后調(diào)用其相關(guān)屬性,方法和下標(biāo)返回值
如果可選包含一個(gè)“nil”值,所有的相關(guān)屬性,方法和下標(biāo)返回nil
由于多種查詢方法,屬性和下標(biāo)故障組合在一起,以一種鏈將影響到整個(gè)鏈,并導(dǎo)致產(chǎn)生 'nil' 的值。
可選鏈作為一種替代強(qiáng)制解包裹
可選鏈與可選值后指定“?”調(diào)用一個(gè)屬性,方法或下標(biāo)當(dāng)可選的值返回一些值。
程序用于可選鏈 '!'
class ElectionPoll {
var candidate: Pollbooth?
}
class Pollbooth {
var name = "MP"
}
let cand = ElectionPoll()
let candname = cand.candidate!.name
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
fatal error: unexpectedly found nil while unwrapping an Optional value0 swift 0x0000000103410b68 llvm::sys::PrintStackTrace(__sFILE*) + 401 swift 0x0000000103411054 SignalHandler(int) + 4522 libsystem_platform.dylib 0x00007fff9176af1a _sigtramp + 263 libsystem_platform.dylib 0x000000000000000b _sigtramp + 18544929394 libsystem_platform.dylib 0x00000001074a0214 _sigtramp + 19767836365 swift 0x0000000102a85c39 llvm::JIT::runFunction(llvm::Function*, std::__1::vector > const&) + 3296 swift 0x0000000102d320b3 llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&, char const* const*) + 15237 swift 0x000000010296e6ba swift::RunImmediately(swift::CompilerInstance&, std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&, swift::IRGenOptions&, swift::SILOptions const&) + 10668 swift 0x000000010275764b frontend_main(llvm::ArrayRef, char const*, void*) + 52759 swift 0x0000000102754a6d main + 167710 libdyld.dylib 0x00007fff8bb9e5c9 start + 111 libdyld.dylib 0x000000000000000c start + 1950751300Stack dump:0. Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret - -target x86_64-apple-darwin14.0.0 -target-cpu core2 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -module-name main /bin/sh: line 47: 15672 Done cat <<'SWIFT'import Foundation
上述程序中聲明“ election poll” 作為類名,并包含了作為隸屬函數(shù)“candidate”。子類被聲明為 “poll booth” 和 “name” 作為被初始化為 'MP' 的隸屬度函數(shù)。對(duì)超類的調(diào)用是通過創(chuàng)建一個(gè)實(shí)例,“cand”可選的初始化 "!“。由于這些值在它的基類沒有聲明,“nil” 值被存儲(chǔ),從而通過強(qiáng)制解包處理過程返回一個(gè)致命的錯(cuò)誤。
程序用于可選鏈 '?'
class ElectionPoll {
var candidate: Pollbooth?
}
class Pollbooth {
var name = "MP"
}
let cand = ElectionPoll()
if let candname = cand.candidate?.name {
println("Candidate name is /(candname)")
}
else {
println("Candidate name cannot be retreived")
}
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Candidate name cannot be retreived
上述程序中聲明“ election poll” 作為類名,并包含了作為隸屬函數(shù)“candidate”。子類被聲明為 “poll booth” 和 “name” 作為被初始化為 'MP' 的隸屬度函數(shù)。對(duì)超類的調(diào)用是通過創(chuàng)建一個(gè)實(shí)例,“cand”可選的初始化“?”。由于基類 'nil' 的值不聲明被存儲(chǔ)并打印在控制臺(tái),由其他程序塊處理。
定義模型類的可選鏈接和訪問屬性
Swift 語言還提供可選鏈的概念,聲明多個(gè)子類的模型類。這個(gè)概念將是定義復(fù)雜的模型和訪問屬性,方法和下標(biāo)子屬性非常有用。
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
println("The number of rooms is /(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var street: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let rectname = rectangle()
if let rectarea = rectname.print?.cprint {
println("Area of rectangle is /(rectarea)")
} else {
println("Rectangle Area is not specified")
}
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Rectangle Area is not specified
通過可選鏈調(diào)用方法
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
println("Area of Circle is: /(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
if circname.print?.circleprint() != nil {
println("Area of circle is specified)")
} else {
println("Area of circle is not specified")
}
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Area of circle is not specified
該函數(shù)circleprint()在circle()子類中聲明通過創(chuàng)建名為 “circname” 的一個(gè)實(shí)例來調(diào)用。函數(shù)會(huì)返回一個(gè)值 如果它包含一定的值則返回一些用戶定義的打印信息。否則會(huì)被檢查的語句 'if circname.print?.circleprint() != nil“
下標(biāo)訪問通過可選鏈
可選鏈設(shè)置和檢索下標(biāo)值以驗(yàn)證是否要調(diào)用該下標(biāo)返回一個(gè)值。 '?' 被放置在下標(biāo)括號(hào)之前來訪問特定的標(biāo)可選值。
程序 1
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
println("The number of rooms is /(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
if let radiusName = circname.print?[0].radiusname {
println("The first room name is /(radiusName).")
} else {
println("Radius is not specified.")
}
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Radius is not specified.
在以上程序未指定成員函數(shù) “radiusName” 的實(shí)例值。因此,程序調(diào)用該函數(shù)將返回唯一內(nèi)容,以返回必須定義特定成員函數(shù)值的一部分。
程序 2
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
println("The number of rooms is /(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")
let printing = circle()
printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing
if let radiusName = circname.print?[0].radiusname {
println("Radius is measured in /(radiusName).")
} else {
println("Radius is not specified.")
}
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Radius is measured in Units.
在上面的程序被指定為成員函數(shù) “radiusName” 的實(shí)例值。 因此,程序現(xiàn)在調(diào)用函數(shù)將有返回值。
可選類型訪問下標(biāo)
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
println("The number of rooms is /(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")
let printing = circle()
printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing
var area = ["Radius": [35, 45, 78, 101], "Circle": [90, 45, 56]]
area["Radius"]?[1] = 78
area["Circle"]?[1]--
println(area["Radius"]?[0])
println(area["Radius"]?[1])
println(area["Radius"]?[2])
println(area["Radius"]?[3])
println(area["Circle"]?[0])
println(area["Circle"]?[1])
println(area["Circle"]?[2])
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Optional(35)Optional(78)Optional(78)Optional(101)Optional(90)Optional(44)Optional(56)
對(duì)于下標(biāo)可選的值可以通過參考其下標(biāo)值來訪問。它可訪問為 subscript[0], subscript[1]等。radius 的默認(rèn)值下標(biāo)首先被指定為 [35,45,78,101] 和 Circle[90,45,56]。然后,下標(biāo)值作為 Radius[0] 至78,以及Circle[1]?45。
鏈接鏈的多層次性
多個(gè)子類也可以憑借其超類的方法,屬性和下標(biāo)通過可選鏈接聯(lián)系。
可選的多個(gè)鏈可以鏈接:
如果檢索類型是不可選的,可選鏈會(huì)返回一個(gè)可選值。例如,如果字符串通過可選鏈就會(huì)返回字符串?值
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
println("The number of rooms is /(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
if let radiusName = circname.print?[0].radiusname {
println("The first room name is /(radiusName).")
} else {
println("Radius is not specified.")
}
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Radius is not specified.
在以上程序未指定隸屬函數(shù) “radiusName” 的實(shí)例值。 因此,程序調(diào)用該函數(shù)將返回唯一內(nèi)容,我們必須定義返回值的特定隸屬作為函數(shù)值的一部分。
如果檢索式已經(jīng)是可選的,那么可選鏈也將返回一個(gè)可選值。例如,如果字符串 ? 通過可選的鏈也將訪問返回字符串 ?值。
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
println("The number of rooms is /(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
if let radiusName = circname.print?[0].radiusname {
println("The first room name is /(radiusName).")
} else {
println("Radius is not specified.")
}
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Radius is measured in Units.
在上面的程序被指定為隸屬函數(shù) “radiusName” 的實(shí)例值。因此,程序調(diào)用函數(shù)將返回值。
鏈上的方法可選返回值
可選鏈?zhǔn)怯脕矶x方法來訪問子類。
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
println("The number of rooms is /(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")
let printing = circle()
printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing
if let radiusName = circname.print?[0].radiusname {
println("Radius is measured in /(radiusName).")
} else {
println("Radius is not specified.")
}
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Area of circle is not specified




















