- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
让我们用这两个简单的类来说明我的问题:
class Object{
var name:String?
// keep it simple... and useless
}
class TestClass {
var objects:AnyObject[]?
func initializeObjects (){
objects?.insert(Object(), atIndex:0) // Error
objects?.insert(Object(), atIndex:1) // Error
objects?.insert(Object(), atIndex:2) // Error
}
}
通过这个实现,我得到了 3 个错误 Could not find member 'insert'
我尝试将对象添加到 objects
数组中。
现在,如果我从 objects
定义中删除可选项,并在 initializeObjects
中删除可选链,它就可以正常工作(这里是工作代码)
class Object{
var name:String?
}
class TestClass {
var objects:AnyObject[] = AnyObject[]() // REMOVE optional and initialize an empty array
func initializeObjects (){
objects.insert(Object(), atIndex:0) // Remove Opt chaining
objects.insert(Object(), atIndex:1) // Remove Opt chaining
objects.insert(Object(), atIndex:2) // Remove Opt chaining
}
}
我不明白第一个实现有什么问题。我认为它会检查 objects?
如果 objects
不是 nil
并且此时它使用 insert:atIndex:< 添加一个元素
。但我可能错了-.-
最佳答案
Swift 中的数组是结构体,而结构体是值类型。
Swift 中的可选项实际上是枚举( Optional<T>
或 ImplicitlyUnwrappedOptional<T>
)。
当您解包值类型的可选(隐式或显式)时,您得到的实际上是该结构的常量副本。你不能调用 mutating
常量结构上的方法。
正在执行 objects?.insert(Object(), atIndex:0)
基本上是这样的:
if let tmp = objects {
tmp.insert(Object(), atIndex:0)
}
作为解决方法,您需要将展开的值分配给一个变量,然后将该变量分配回您的可选属性。这就是值类型的工作方式。
这对于任何结构都是可重现的,而不仅仅是数组:
struct S {
var value: Int = 0
}
var varS: S = S()
varS.value = 10 //can be called
let constS: S = S()
constS.value = 10 //cannot be called - constant!
var optionalS: S? = S()
optionalS?.value = 10 //cannot be called, unwrapping makes a constant copy!
//workaround
if optionalS {
var tmpS = optionalS!
tmpS.value = 10
optionalS = tmpS
}
这里有一些相关的讨论:https://devforums.apple.com/thread/233111?tstart=60
关于swift - swift 中的可选链接和数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24451960/
我正在尝试用 Swift 编写这段 JavaScript 代码:k_combinations 到目前为止,我在 Swift 中有这个: import Foundation import Cocoa e
我是一名优秀的程序员,十分优秀!