【问题标题】:Why Implicitly unwrapped optional was not assigned?为什么未分配隐式展开的可选选项?
【发布时间】:2017-04-07 23:59:59
【问题描述】:

在下面的代码中,为什么 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
    }
}

【问题讨论】:

  • 为 var 赋值的正确方法是 somevar = 5 而不是 somevar? = 5

标签: swift optional forced-unwrapping


【解决方案1】:

当我们执行 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's awesome Swift book 中有介绍。
(顺便说一句,一本非常好的书!?❤️)

【讨论】:

  • @LeoDabus 考虑到这个问题没有任何区别,但我明白你的意思并相应地改变了我的答案。谢谢。
  • 还有“强制阅读”(强制展开)=金! :) (提到澄清了很多)通过这本书
【解决方案2】:

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 设置为5,如果它不是nil

【讨论】:

  • 谢谢你,安德鲁的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-26
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多