2016-03-27 12 views
5

unwrapping sırasında 'nil' bulur. Aşağıdaki gibi görünüyor Swift for-in döngü dizide bulunandan daha fazla öğe geçmeye çalışıyor. ÖrneğinFor-in döngü bir-çok-uzak gider ve

, bu kodu:

C-Style for loop 
1 
2 
3 
4 
5 
6 
7 

For each loop 
1 
2 
3 
4 
5 
6 
7 
fatal error: unexpectedly found nil while unwrapping an Optional value 
... 
Illegal instruction: 4 

burada bir şey eksik gerekir:

var list:[Int?] = [1,2,3,4,5,6,7] 

print("C-Style for loop") 
for var i=0; i<list.count; i++ 
{ 
    var x:Int = list[i]! 
    print(x) 
} 

print("\nFor-in loop") 
for var x:Int! in list 
{ 
    print(x) 
} 

bu çıktıyı alır. list.count, for-in döngüsünün açılmaya çalıştığı öğelerin sayısı değil mi?

Yukarıda gösterildiği gibi, for-in döngüsü, listesini [Int?] kullanmak yerine, beklemede olmadan beklendiği gibi çalışır.

Ben Swift sürüm 2.1.1'deyim.

+0

Bazı garip davranışlar. Eğer 'listeyi' [Int] 'olarak etiketlerseniz ve' x '' Int? 'Olarak etiketlerseniz, 'for-in' döngüsü sonsuza kadar 'nil' yazdırır. – BallpointBen

+0

@Robert Çalışmanın nasıl çalıştığını anlarsanız bu davranış özellikle garip değildir ... ancak Swift muhtemelen x 'etiketini isteğe bağlı olarak engeller (çünkü bu yalnızca sonsuz bir döngüye neden olabilir). – nhgrif

+0

Neler olduğunu açıklayabilir misiniz? Bu neden sonsuz bir döngü yapar? – BallpointBen

cevap

4

Temelde yapmamanız gereken bir şey yaptınız ve bu nedenle muhtemelen derleyici bir hataya (çünkü derleyici sizi durdurmadığı için) tökezlediniz. Çok hoş!

Şimdi çözüm. Int! ile açılmaya çalışıyorsunuz. Güvenlepaketini for case sözdizimi kullanın:

let list:[Int?] = [1,2,3,4,5,6,7] 
for case let x? in list 
{ 
    print(x) // 1, 2, 3, 4, 5, 6, 7 
} 

Başka yolu (aynı sonuç): Burada

let list:[Int?] = [1,2,3,4,5,6,7] 
list.flatMap{$0}.forEach{print($0)} // 1, 2, 3, 4, 5, 6, 7 
+0

Yani ForEach aynı soruna katlanıyor ... korkutucu. – Darko

+0

@Darko hayır, aslında değil; Bu bana başka bir çözüm sunuyor - basit 'list.forEach {print (0 $!)} '(tabi ki diğer nedenlerden dolayı potansiyel olarak tehlikelidir) – matt

+0

Evet, ancak list.forEach {print ($ 0)} da çöker. FlatMap'e olan gereksinim benim için korkutucu. – Darko

2

x:Int! gibi Zorlu Ambalajlama, sıfırlanamayacağınız zaman tehlikeli bir kodlama stilidir. Aynı durum var x:Int = list[i]! için de geçerlidir.

Bu çalışır: Burada

print("\nFor-in loop") 
for x in list { 
    print(x) 
} 

x sıfır olmasına izin ve güvenli bir şekilde sonradan nil kontrol edebilirsiniz.

Şimdi kod sonları neden sorusuna:

Dahili olarak, hızlı for-in döngüsünü için list.generate() kullanır. Jeneratör sonlandırıldı, bu da muhtemelen kodunuzun kırılmasının nedeni.

+0

Ancak sorun, bu OP'nin istediği değil, Opsiyonel (1), Opsiyonel (2), vs. vermesidir. – matt

+0

Haklısınız. Yazdırma sadece hata ayıklama için olduğundan şüpheleniyorum ve OP açıkça nasıl açılmayı biliyor. Benim için daha ilginç olan soru, neden başarısız oldu. –