-3

在下面的代码中,为什么 5 没有分配给 "somevar" ?

class ViewController: UIViewController {

    var somevar : Int?

    override func viewDidLoad() {
        super.viewDidLoad()
        somevar! = Int(5) // why 5 is not assigned to somevar here
    }
}

背景:

somevar被声明为可选变量,这意味着如果此变量为 nil,则使用此变量的命令将被忽略。

例子:

class ViewController: UIViewController {

    var somevar : Int?

    override func viewDidLoad() {
        super.viewDidLoad()
        somevar? = 5 // this command will be ignored bcz somevar is nil
    }
}

为了在我们自己的风险下强制执行命令,我们使用“隐式解包可选”,以便我们确定命令将被执行,在这种情况下执行以下行

somevar! = 5 

致命错误:在展开可选值时意外发现 nil

执行此行时,为什么没有将“5”分配给“somevar”而是发生致命错误?

class ViewController: UIViewController {

    var somevar : Int?

    override func viewDidLoad() {
        super.viewDidLoad()
        somevar! = 5
    }
}
4

2 回答 2

2

当我们这样做时something!(强调!标记),我们是“强制阅读”(强制展开)一个可选的。

也就是说,上面的代码something在给它赋值之前尝试读取。
既然somethingnil,代码就会爆炸。

为了显示:

var somevar: Int?

print(somevar!)
// Code explodes! 

print(somevar)
// Output is "nil"

somevar = 5

print(somevar!)
// Output is "5"

print(somevar)
// Output is "Optional(5)"

正如@LeoDabus 所说,这在Apple 很棒的 Swift book中有介绍。
(顺便说一句,一本非常好的书!❤️)

于 2017-04-08T00:21:53.150 回答
0

somevar? = 5正在做的事情一些颜色。

//: Playground - noun: a place where people can play

import Foundation

// In swift you have to unwrap an optional before you can do anything with it
var x: Int? = 1
var y: Int? = 2

// So you can't do this
//var z = x + y

// You have to do this
if let x = x,
    let y = y {
    // Here x and y are no longer of the type Int? they are of the type Int
    var z = x + y
}

// You don't have to name them the same
if let someX = x,
    let someY = y {
    // Here x and y are no longer of the type Int? they are of the type Int
    var z = someX + someY
}

// This can be a pain sometimes if you want to "do nothing" in the nil case, or want to unwrap something multiple "levels"
// of optionals deep. For example:

struct Pet {
    let name: String
}

struct Person {
    let pet: Pet?
}

var person: Person? = Person(pet: Pet(name: "Rex"))

// To get the person's pet's name we have to unwrap a few things
if let person = person,
    let pet = person.pet {
    print("The pet's name is \(pet.name)")
}

// We can do this a little easier by using "Optional Chaining"
if let name = person?.pet?.name {
    print("The pet's name is \(name)")
}

// So here's where your problem comes in
var number: Int? = nil

// This is "optional chaining" the assignment of 5 to number. But, because number is current nil the assignment won't happen.
number? = 5

// However
number = 5

// Now the number is 5

number? = 10

// Now the number is 10, because the optional chaining succeded because number was not nil. All this being said, I've never
// seen someone use x? = 5 in production code, and I can't think of a reason to do that. Just do x = 5 like the other
// answers have said.

TL; DR,仅在不是somevar? = 5时才使用可选链接设置somevar为。5nil

于 2017-04-08T00:38:42.507 回答