swift可选值只需要解包一次然后可以多次使用而不需要再次展开它是真的吗?

时间:2016-02-26 10:12:18

标签: swift optional unwrap

我是Swift的新手,正在尝试初学者构建计算器的项目。我知道“display.text”返回一个可选字符串,其中的字符串值必须用“!”解包。在它可以使用之前。

但是,我注意到“display.text”只需要打开一次,然后可以多次使用而无需再次打开它。这对Swift可选值是否正确?我在哪里可以找到关于此事的一些指导原则?

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var display: UILabel!

    var userIsInTheMiddleOfTypingANumber = false

    @IBAction func appendDigit(sender: UIButton) {
        let digit = sender.currentTitle!
        if userIsInTheMiddleOfTypingANumber {
            display.text = display.text! + digit
        } else {
            display.text = digit
            userIsInTheMiddleOfTypingANumber = true
        }
    }

3 个答案:

答案 0 :(得分:2)

两种标准选项,用于展开可以再次使用的可选项:

1)如果让

if let unwrappedValue = someOptional {
  // unwrappedValue can be used only inside this block of code
}

2)后卫

guard let unwrappedValue = someOptional else { return } 
/// unwrappedValue can be used as long as it is in scope

答案 1 :(得分:1)

试试这个。

guard let displayText = display.text else {
    // handle the case when optional has nil value
}

// In this scope you can use non-nil value of display.text as displayText.
print("displayText = \(displayText)")

这是在解缠一次后使用可选值的方法。另一种更简单的方法是使用而不是guard-let

if let displayText = display.text else {
    // safely unwrapped
}

希望有所帮助!

请检查此link以获取更多帮助。

答案 2 :(得分:0)

您通常应该避免强制解包选项(使用运算符!),因为如果可选项包含nil,这将产生运行时异常。下面介绍一些处理可选项解包的技巧。

可选绑定

请注意,唯一的方法是"展开一次,然后多次使用它" ,如果你打开并指定它另一个非可选变量到相同的固有类型

这是使用optional binding时所做的事情:

/* Example setup */
let display: UILabel = UILabel()
let digit = "1"

/* optional binding using if-let:
   _assign_ unwrapped value (if non-nil) to 'unwrapped' */
if let unwrappedText = display.text {
    // 'unwrapped' resides in scope inside of the if-let block
    display.text = unwrappedText + digit
}
else {
    display.text = digit
}

/* optional binding using guard-let-else:
   _assign_ unwrapped value (if non-nil) to 'unwrapped' */
func foo(disp: UILabel, _ dig: String) {
    guard let unwrappedText = display.text else {
        display.text = digit
        return
    }
    // 'unwrapped' resides in scope outside of the guard-let-else block
    display.text = unwrappedText + digit
}
foo(display, digit)

无合并运算符

如果您不想使用条件绑定显式分配未包装的值,则可以使用nil coalescing operator进行安全展开。

/* nil coalescing operator */
display.text = (display.text ?? "") + digit

现在,您可以以半可选绑定的方式使用nil合并运算符;如果可选项为nil,则指定可选或某个默认值的展开值:

let metaUnwrapped = display.text ?? ""

不可变metaUnwrapped在其范围内可用,并且包含display.text(在分配时)的值,如果不是nil或默认值"",如果display.text nil分配给metaUnwrapped。您可以在上面的可选绑定示例中以与不可变unwrapped相同的方式使用display.text = metaUnwrapped + digit

nil

可选链接

这稍微偏离w.r.t.你的问题,但由于我们关注的是选项和解包问题,我不妨提一下optional chaining

可选链接可用于访问某些可选属性的属性,前提是可选属性不是display.text。例如,假设您要计算.text中的字符数,但自然只有在可选的nil属性为非let numCharacters = display.text?.characters.count ?? 0 /* if text != nil, returns character count; otherwise, by nil coalescing operator, returns 0 /* 时才会计算。在这种情况下,可选链接与零合并运算符相结合可能是一种合适的选择方法:

selectedtext = list_of_lists[44]
print("Selected Text Is")
print(selectedtext)