我注意到使用默认值创建数组中的行为有点奇怪(且危险的恕我直言)。如 Swift 2.1: Collection Types 中所述
Swift’s Array type also provides an initializer for creating an array of a certain size with all of its values set to the same default value. You pass this initializer the number of items to be added to the new array (called count) and a default value of the appropriate type (called repeatedValue):
重点是:相同的默认值;为了理解它是如何工作的,我尝试创建这个示例类的元素数组
class User {
private struct Shared {
static var sequence: Int = 0
}
var id: Int
var thinkTime: NSTimeInterval // typealias di Double
init (thinkTime: NSTimeInterval) {
User.Shared.sequence = User.Shared.sequence+1
id = User.Shared.sequence
self.thinkTime = thinkTime
}
}
以及此测试代码:
let howManyUsers: Int = 3
var users = [User](count: howManyUsers, repeatedValue:User(thinkTime: 10.0))
let u2: User = User(thinkTime: 10)
let u3: User = User(thinkTime: 10)
users.append(u2)
users.append(u3)
users[1].thinkTime = 20
users[3].thinkTime = 30
for u in users {
print("User id:\(u.id) thinktime:\(u.thinkTime)")
}
给出:
User id:1 thinktime:20.0
User id:1 thinktime:20.0
User id:1 thinktime:20.0
User id:2 thinktime:30.0
User id:3 thinktime:10.0
明确证明初始化程序包含要添加到新数组的项目数和适当类型的默认值是:相同的对象实例
这是一种尽可能简洁和智能的方法,用于获取一组不同的对象实例,并使用相同的默认值进行初始化(不是同一个实例,而是使用相同的默认值)?
最佳答案
类是引用类型,因此 - 正如您所注意到的 - 所有数组 中的元素
var users = [User](count: howManyUsers, repeatedValue:User(thinkTime: 10.0))
引用相同的对象实例(首先创建,然后 作为参数传递给数组初始值设定项)。
对于 struct
类型,您会得到不同的结果。
可能的解决方案:
var users = (0 ..< howManyUsers).map { _ in User(thinkTime: 10.0) }
这里,为每个数组索引创建一个 User
实例。
如果你经常需要,那么你可以定义一个数组 init 采用“自动关闭”参数的方法:
extension Array {
public init(count: Int, @autoclosure elementCreator: () -> Element) {
self = (0 ..< count).map { _ in elementCreator() }
}
}
var users = Array(count: howManyUsers, elementCreator: User(thinkTime: 10.0) )
现在第二个参数 User(thinkTime: 10.0)
由
编译成一个闭包,并且每个闭包都会被执行
数组索引。
Swift 3 更新:
extension Array {
public init(count: Int, elementCreator: @autoclosure () -> Element) {
self = (0 ..< count).map { _ in elementCreator() }
}
}
关于arrays - Swift:创建具有不同对象实例默认值的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39268005/