Ios 理解if let语句的逻辑-初始化前使用的变量

Ios 理解if let语句的逻辑-初始化前使用的变量,ios,swift,if-statement,nsuserdefaults,Ios,Swift,If Statement,Nsuserdefaults,因此,我正在学习udemy的教程,并拥有这段代码 let itemsObject = UserDefaults.standard.object(forKey: "items") var items:[String] if let tempItems = itemsObject as? [String] { // items = tempItems items.append(textfield.text!) }

因此,我正在学习udemy的教程,并拥有这段代码

   let itemsObject = UserDefaults.standard.object(forKey: "items")
    var items:[String]

    if let tempItems = itemsObject as? [String]
    {
        //
        items = tempItems
        items.append(textfield.text!)
    }
我理解itemsObject和items数组,但我想知道为什么我不能完全绕过tempItems常量,比如

var items:[String]
if items = itemsObject as? [String]
{
items.append(textfield.text!)
}
我不明白这个常量的用途

let itemsObject = UserDefaults.standard.object(forKey: "items")
itemsObject现在的类型是
Any?
,所以我们需要做两件事:强制转换它并检查它是否为nil

if let tempItems = itemsObject as? [String]
是以下各项的快捷方式:

let tempItems1 = itemsObject as? [String] // cast to [String]?
if tempItems1 != nil {
    let tempItems2 = tempItems1! // we know its not nil, so force unwrap it to [String]
    ...
}
提示:

[String]?
是一个可以为零的字符串数组

[String]
是一个不能为零的字符串数组

可选绑定是值绑定模式匹配,它不等同于赋值 考虑以下简化示例:

let foo: Any = 1

if let bar = foo as? Int { /* ... */ }
我们在最后一排干什么?我们尝试有条件地将
Any
实例(
foo
)转换为
Int
类型。这种条件类型转换(
as?
)的结果是一个
可选的

foo as? Int // type: Optional<Int>
即,以下两(三)项是等效的

// make use of syntactic sugar available for `Optional` enum
if let bar = foo as? Int { /* .. */ }

// or use the explicit value-binding pattern available to any
// enum with a case that holds and associated value
if case .some(let bar) = foo as? Int { /* .. */ }

// (for the latter: alternatively)
if case let .some(bar) = foo as? Int { /* .. */ }
此外,为了增加一些额外的混淆,我们还为特殊enum
Optional
提供了另一种特殊的语法糖类(具体来说是
.some(让bindWrappedToThis)
案例),因此以下内容也相当于上述两种情况:

// using the sugar '_?' instead of '.some(_)', here replacing
// '... let .some(bar)' with '... let bar?'
if case let bar? = foo as? Int { /* .. */ }

理解上述内容的关键是理解以下内容:

let items = (UserDefaults.standard.object(forKey: "items") as? [String])
    .map { $0 + [textfield.text!] } ?? []
  • 尝试将
    用作
    的类型转换将导致一个
    可选
    实例,其中
    包装的
    类型是类型转换的目标类型。例如,
    someInstance as?SomeType
    将生成一个
    可选的
    实例,该实例可能是
    零(
    .none
    ),或者可能是包装
    SomeType
    .someInstanceOfSomeType)
    )的一个具体实例

  • Swift中的类型
    可选
    是一个枚举,不包括所有特殊的整洁度/糖

  • 最后,值绑定模式匹配与赋值不同

  • 1) 通过其详尽的描述,这是不言自明的。为了理解2)和3),我们可以研究以下简单示例,其中显示了一个自定义的“可选”示例,如
    enum
    ,带有一个
    大小写
    ,该大小写包含一个通用关联值,对于
    enum
    的给定实例,我们尝试有条件地绑定到一个属性:

    enum MyOptional<Wrapped> {
        case none
        case some(Wrapped)
    }
    
    // instantiate with a case with an associated value
    let foo = MyOptional.some(1) // MyOptional<Int>.some(1)
    
    // use value-binding pattern matching to conditionally
    // access the associated value of the 'some(...)' case,
    // given that 'foo' is '.some' (and not '.none')
    if case .some(let bar) = foo { /* .. */ }
    
    其中,在单个表达式中,使用了以下内容:

    let items = (UserDefaults.standard.object(forKey: "items") as? [String])
        .map { $0 + [textfield.text!] } ?? []
    
    • UserDefaults
      值的条件类型转换为类型
      [String]
    • 如果类型转换成功,请追加
      textField.text到具体的
      [String]
      值并分配到
    • 如果类型转换不成功,请使用
      nil
      合并运算符
      提供并清空数组
      []
      ,作为
      项的默认值