Fra*_*ini 13 arrays initialization instantiation instance swift
在创建具有默认值的数组时,我注意到有点奇怪(和危险的恕我直言)行为.如Swift 2.1中所述:集合类型
Swift的Array类型还提供了一个初始化器,用于创建一个特定大小的数组,并将其所有值设置为相同的默认值.您将此初始值设定项传递给要添加到新数组的项目数(称为计数)和相应类型的默认值(称为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
}
}
Run Code Online (Sandbox Code Playgroud)
和这个测试代码:
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)")
}
Run Code Online (Sandbox Code Playgroud)
得到:
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
Run Code Online (Sandbox Code Playgroud)
最终证明初始化程序具有要添加到新数组的项目数,并且相应类型的默认值为:相同的对象实例
为了获得一组不同的对象实例,使用相同的默认值(不是相同的实例,但是使用相同的默认值初始化的实例数)实例化,尽可能简洁明智的方式是什么?
Mar*_*n R 28
类是引用类型,因此 - 正如您所注意到的 - 所有数组元素
var users = [User](count: howManyUsers, repeatedValue:User(thinkTime: 10.0))
Run Code Online (Sandbox Code Playgroud)
引用相同的对象实例(首先创建,然后作为参数传递给数组初始值设定项).
对于某种struct类型,您会得到不同的结果.
可能的解决方案:
var users = (0 ..< howManyUsers).map { _ in User(thinkTime: 10.0) }
Run Code Online (Sandbox Code Playgroud)
这里,User为每个数组索引创建一个实例.
如果您经常需要,那么您可以定义一个数组init方法,该方法采用"autoclosure"参数:
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) )
Run Code Online (Sandbox Code Playgroud)
现在第二个参数User(thinkTime: 10.0)被编译器包装到一个闭包中,并且为每个数组索引执行闭包.
Swift 3更新:
extension Array {
public init(count: Int, elementCreator: @autoclosure () -> Element) {
self = (0 ..< count).map { _ in elementCreator() }
}
}
Run Code Online (Sandbox Code Playgroud)