为了账号安全,请及时绑定邮箱和手机立即绑定

Swift:使用不同对象实例的默认值创建一个数组

/ 猿问

Swift:使用不同对象实例的默认值创建一个数组

一只甜甜圈 2019-11-19 14:47:05

在创建具有默认值的数组时,我注意到了一些怪异(和危险的恕我直言)的行为。如Swift 2.1中所述:集合类型


Swift的Array类型还提供了一个初始化程序,用于创建一个特定大小的数组,并将其所有值设置为相同的默认值。您向此初始化程序传递要添加到新数组中的项目数(称为count)和适当类型的默认值(称为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

使用要添加到新数组中的项数以及适当类型的默认值来明确证明初始化程序是:相同的对象实例


哪种方法尽可能简洁明了,以获取具有相同默认值(不是相同的实例,而是用相同的默认值初始化的多个实例)而实例化的不同对象实例的数组?


查看完整描述

2 回答

?
茅侃侃

类是引用类型,因此-正如您所注意到的-中的所有数组元素


var users = [User](count: howManyUsers, repeatedValue:User(thinkTime: 10.0))

引用相同的对象实例(首先创建该实例,然后将其作为参数传递给数组初始化器)。


对于struct类型,您将得到不同的结果。


可能的解决方案:


var users = (0 ..< howManyUsers).map { _ in User(thinkTime: 10.0) }

在这里,User为每个数组索引创建一个实例。


如果您经常需要,则可以定义一个带有“ 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) )

现在,第二个参数User(thinkTime: 10.0)由编译器包装到一个闭包中,并对每个数组索引执行闭包。


Swift 3更新:


extension Array {

    public init(count: Int, elementCreator: @autoclosure () -> Element) {

        self = (0 ..< count).map { _ in elementCreator() }

    }

}


查看完整回答
反对 回复 2019-11-19
?
德玛西亚99

迅捷5


extension MSRoom {

    static var dummyDefaultRoom: MSRoom = {

        let members = MSRoom.Member.dummyMembers(maxCount: 6)

        let ownerUser = members.first!.user

        var room = MSRoom(id: "98236482724", info: .init(name: "Ahmed's Room", description: "your default room", isPrivate: true), owner: ownerUser)

        room.dateCreated = Date(timeIntervalSince1970: 1565222400)

        room.currentMembers = members

        return room

    }()


}


let rooms = [MSRoom](repeating: MSRoom.dummyDefaultRoom, count: 10)


查看完整回答
反对 回复 2019-11-19

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信