2015-10-03 28 views
8

bir varsayılan değeri olan bir dizinin oluşturulması Bir Varsayılan Değer bir dizinin oluşturulması içinde (IMHOve tehlikeli) behavoir garip biraz fark ettim.Swift: farklı nesne örnekleri

Swift 2.1: Collection Types belirtildiği gibi Swift Dizi türü aynı varsayılan değer olarak ayarlanmış tüm değerleri ile belirli bir büyüklükteki bir dizi oluşturmak için bir başlatıcı içerir.

noktasıdır: Sen öğe sayısı yeni dizisi (denilen sayımı) eklenecek bu başlatıcı ve (repeatedValue denir) uygun türde bir varsayılan değer geçmesi aynı varsayılan değeri; verir

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)") 
} 

: o iş nasıl anlamak için, bu örnek sınıfın

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 
    } 
} 

unsurlarının bir dizi ve bu test kodu oluşturmak için çalıştık

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 

olduğunu kesin başlatıcıyı yeni diziye eklenecek öğe sayısıyla ve uygun türün varsayılan değeriyle kanıtlayın: aynı nesne örneği

olarak kısa ve mümkün olduğu akıllı bir şekilde olan

, aynı varsayılan değer (aynı örneği aynı varsayılan değeri ile başlatılmasının örneklerde, bir dizi) ile instatiated farklı nesne örnekleri bir dizi elde etmek üzere ?

cevap

16

sınıfları bu nedenle referans türleri - fark olarak -

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

referans (dizi başlatıcı için bir bağımsız değişken olarak, birinci ve ardından oluşturulan geçirilir) aynı nesne, örneğin tüm dizi elemanları.

struct türü için farklı bir sonuç elde edersiniz.

Muhtemel bir çözüm: burada

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

, bir User örneği dizi indeksleri her biri için oluşturulur.

sık o zaman "autoclosure" parametre alır yöntemle init bir dizi tanımlamak verebilecek gerekirse: Şimdi ikinci argüman User(thinkTime: 10.0) bir kapatma içine derleyici tarafından sarılır

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)) 

ve Her dizi dizini için kapatma gerçekleştirilir. Swift 3


Güncelleme:

extension Array { 
    public init(count: Int, elementCreator: @autoclosure() -> Element) { 
     self = (0 ..< count).map { _ in elementCreator() } 
    } 
}