深刻解析Swift說話編程中的可選鏈。本站提示廣大學習愛好者:(深刻解析Swift說話編程中的可選鏈)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析Swift說話編程中的可選鏈正文
查詢,挪用屬性,下標和辦法上的一個可選能夠 'nil' 的進程被界說為可選的鏈。可選鏈前往兩個值
假如可選包括一個值,然後挪用其相干屬性,辦法和下標前往值
假如可選包括一個“nil”值,一切的相干屬性,辦法和下標前往nil
因為多種查詢辦法,屬性和下標毛病組合在一路,以一種鏈將影響到全部鏈,並招致發生 'nil' 的值。
可選鏈作為一種替換強迫解包裹
可選鏈與可選值後指定“?”挪用一個屬性,辦法或下標當可選的值前往一些值。
法式用於可選鏈 '!'
class ElectionPoll {
var candidate: Pollbooth?
}
class Pollbooth {
var name = "MP"
}
let cand = ElectionPoll()
let candname = cand.candidate!.name
當我們應用 playground 運轉下面的法式,獲得以下成果。
fatal error: unexpectedly found nil while unwrapping an Optional value 0 swift 0x0000000103410b68 llvm::sys::PrintStackTrace(__sFILE*) + 40 1 swift 0x0000000103411054 SignalHandler(int) + 452 2 libsystem_platform.dylib 0x00007fff9176af1a _sigtramp + 26 3 libsystem_platform.dylib 0x000000000000000b _sigtramp + 1854492939 4 libsystem_platform.dylib 0x00000001074a0214 _sigtramp + 1976783636 5 swift 0x0000000102a85c39 llvm::JIT::runFunction(llvm::Function*, std::__1::vector > const&) + 329 6 swift 0x0000000102d320b3 llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&, char const* const*) + 1523 7 swift 0x000000010296e6ba swift::RunImmediately(swift::CompilerInstance&, std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&, swift::IRGenOptions&, swift::SILOptions const&) + 1066 8 swift 0x000000010275764b frontend_main(llvm::ArrayRef, char const*, void*) + 5275 9 swift 0x0000000102754a6d main + 1677 10 libdyld.dylib 0x00007fff8bb9e5c9 start + 1 11 libdyld.dylib 0x000000000000000c start + 1950751300 Stack 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” 作為類名,並包括了作為附屬函數“candidate”。子類被聲明為 “poll booth” 和 “name” 作為被初始化為 'MP' 的附屬度函數。對超類的挪用是經由過程創立一個實例,“cand”可選的初始化 "!“。因為這些值在它的基類沒有聲明,“nil” 值被存儲,從而經由過程強迫解包處置進程前往一個致命的毛病。
法式用於可選鏈 '?'
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")
}
當我們應用 playground 運轉下面的法式,獲得以下成果。
Candidate name cannot be retreived
上述法式中聲明“ election poll” 作為類名,並包括了作為附屬函數“candidate”。子類被聲明為 “poll booth” 和 “name” 作為被初始化為 'MP' 的附屬度函數。對超類的挪用是經由過程創立一個實例,“cand”可選的初始化“?”。因為基類 'nil' 的值不聲明被存儲並打印在掌握台,由其他法式塊處置。
界說模子類的可選鏈接和拜訪屬性
Swift 說話還供給可選鏈的概念,聲明多個子類的模子類。這個概念將是界說龐雜的模子和拜訪屬性,辦法和下標子屬性異常有效。
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")
}
當我們應用 playground 運轉下面的法式,獲得以下成果。
Rectangle Area is not specified
經由過程可選鏈挪用辦法
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")
}
當我們應用 playground 運轉下面的法式,獲得以下成果。
Area of circle is not specified
該函數circleprint()在circle()子類中聲明經由過程創立名為 “circname” 的一個實例來挪用。函數會前往一個值 假如它包括必定的值則前往一些用戶界說的打印信息。不然會被檢討的語句 'if circname.print?.circleprint() != nil“
下標拜訪經由過程可選鏈
可選鏈設置和檢索下標值以驗證能否要挪用該下標前往一個值。 '?' 被放置鄙人標括號之前來拜訪特定的標可選值。
法式 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.")
}
當我們應用 playground 運轉下面的法式,獲得以下成果。
Radius is not specified.
在以上法式未指定成員函數 “radiusName” 的實例值。是以,法式挪用該函數將前往獨一內容,以前往必需界說特定成員函數值的一部門。
法式 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.")
}
當我們應用 playground 運轉下面的法式,獲得以下成果。
Radius is measured in Units.
在下面的法式被指定為成員函數 “radiusName” 的實例值。 是以,法式如今挪用函數將有前往值。
可選類型拜訪下標
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])
當我們應用 playground 運轉下面的法式,獲得以下成果。
Optional(35) Optional(78) Optional(78) Optional(101) Optional(90) Optional(44) Optional(56)
關於下標可選的值可以經由過程參考其下標值來拜訪。它可拜訪為 subscript[0], subscript[1]等。radius 的默許值下標起首被指定為 [35,45,78,101] 和 Circle[90,45,56]。然後,下標值作為 Radius[0] 至78,和Circle[1]〜45。
鏈接鏈的多條理性
多個子類也能夠憑仗其超類的辦法,屬性和下標經由過程可選鏈接接洽。
可選的多個鏈可以鏈接:
假如檢索類型是弗成選的,可選鏈會前往一個可選值。例如,假如字符通同過可選鏈就會前往字符串?值
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.")
}
當我們應用 playground 運轉下面的法式,獲得以下成果。
Radius is not specified.
在以上法式未指定附屬函數 “radiusName” 的實例值。 是以,法式挪用該函數將前往獨一內容,我們必需界說前往值的特定附屬作為函數值的一部門。
假如檢索式曾經是可選的,那末可選鏈也將前往一個可選值。例如,假如字符串 ? 經由過程可選的鏈也將拜訪前往字符串 ?值。
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.")
}
當我們應用 playground 運轉下面的法式,獲得以下成果。
Radius is measured in Units.
在下面的法式被指定為附屬函數 “radiusName” 的實例值。是以,法式挪用函數將前往值。
鏈上的辦法可選前往值
可選鏈是用來界說辦法來拜訪子類。
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.")
}
當我們應用 playground 運轉下面的法式,獲得以下成果。
Area of circle is not specified