所以我按照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 tempItems常量的用途。
答案 0 :(得分:0)
let itemsObject = UserDefaults.standard.object(forKey: "items")
itemsObject现在属于Any?
类型所以我们需要做两件事:抛出它并检查它是否为零
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]?
是一个字符串数组,可以是nil
[String]
是一个不能为零的字符串数组
答案 1 :(得分:0)
考虑以下简化示例:
let foo: Any = 1
if let bar = foo as? Int { /* ... */ }
那么我们在最后一行做什么呢?我们尝试有条件地将Any
实例(foo
)转换为Int
类型。这种条件类型转换(as?
)的结果是Optional
:
foo as? Int // type: Optional<Int>
继续,我们尝试可选地将可能成功的转换绑定到类型为Int
的不可变具体实例(bar
属性)。有关详细信息,请参阅语言指南中的optional binding。
现在,我们执行可选绑定的方式只是value-binding pattern matching的语法糖,在(给定成功的模式匹配)上下文中尝试将enum
个案的关联值绑定到属性。可选绑定的语法糖可用于极端常见的Optional<Wrapped>
枚举类型,而对于其他enum
类型,我们需要使用通用值绑定模式语法
if case let .anEnumCase(bindAssociatedValueToMe) = someEnumInstance { /* ... */ }
// alternatively
if case .anEnumCase(let bindAssociatedValueToMe) = someEnumInstance { /* ... */ }
即,以下两个(三个)是等价的
// 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 { /* .. */ }
并且,为了给这个问题添加一些额外的混淆,我们还有另一个特殊的语法糖可用于特殊的枚举Optional<Wrapped>
(特别是.some(let bindWrappedToThis)
的情况),这样以下也是等价的到上面两个:
// using the sugar '_?' instead of '.some(_)', here replacing
// '... let .some(bar)' with '... let bar?'
if case let bar? = foo as? Int { /* .. */ }
理解上述内容的关键是理解以下内容:
使用as?
进行的尝试类型转换将导致Optional<Wrapped>
实例,其中Wrapped
类型是类型转换的目标类型。即,someInstance as? SomeType
将生成Optional<SomeType>
的实例,可能是nil
(.none
),或者可能包含SomeType
的具体实例({ {1}})。
Swift中的.some(someInstanceOfSomeType)
类型,当省略所有特殊的整洁/糖时,枚举,
最后,该值绑定模式匹配与赋值不同。
1)通过详尽的描述是不言自明的。要理解2)&amp; 3),我们可以研究以下简单示例,显示一个自定义&#34;可选&#34;类似Optional<Wrapped>
,其中enum
包含一个通用关联值,对于给定的实例, case
,我们尝试有条件地绑定到属性:
enum
注意上面最后一行中的值绑定,并与上面上面代码片段中的非加糖可选绑定进行比较。
最后,请注意,除了可选绑定之外,您还可以访问并对可选的(可能存在的)包装值执行操作。例如。使用map(_:)
method of Optional
时,为了清晰起见,我们可以在您的热门代码段中将您的示例(以及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 { /* .. */ }
不可变)压缩为以下内容:
items
在单个表达式中,使用以下内容:
let items = (UserDefaults.standard.object(forKey: "items") as? [String])
.map { $0 + [textfield.text!] } ?? []
值的条件类型转换为UserDefaults
[String]
附加到具体的textField.text!
值并分配给[String]
items
合并运算符nil
提供并清空数组??
,作为[]
的默认值。