Optional, daha önce Objective-C’de olmayan bir kavram ve Swift’in en önemli parçalarından biri.
Sadece object tipinde değişkenler için geçerli olup Structure, enum gibi tiplerde uygulanamaz.
Temel olarak bir optional değişkenin değerinin olup olmadığı üzerinde işlem yapmadan belirli değildir. Optional bir değişken tanımlamak için, değişkenin tipinin yanına “?” koymak yeterlidir.
Örnekle biraz daha açıklamaya çalışayım. Aşağıda bir String değeri tanımladım. Bu değeri Int tipine dönüştürmek istiyorum.
let numberStr = "1234"
let numberInt = Int(numberStr)
Compiler yukarı işlemin çıktısı Int? olarak döner. Yani optional bir değer.
Bu noktada compiler bizim verdiğimiz “1234” değerini tam olarak Int değerine dönüştürebilir. Ancak “Merhaba” gibi değeri dönüştüremeyeceği için hata verip çalışmayı durdurur. İşte optional kavramı sayesinde uygulamanın hata vermesinin önüne geçilmiş olur. “Merhaba” için yukarıdaki işlemin sonucunda numberInt değişkeninin değeri nil olur.
Aşağıdaki tanımlamalar içinde otomatik olarak değer nil atanır.
var name: String?
Ufak bir hatırlatma yapmak gerekiyor. Swift’teki nil ile Objective-C’deki nil kavramı aynı değil. Objective-C’de nil, hafızada olmayan bir objeye yönlenen bir pointer olarak görev yapar. Swift’te ise pointer değildir. Sadece ilgili değişkenin bir değerinin olmadığını gösterir.
Optional bir değişkenin değerinin olup olmadığını anlamak için If koşulunu kullanabiliriz.
Doğrudan değişkenin değerini nil ile karşılaştırmak yeterli.
if numberInt != nil {
print(“numberInt bir int değişkeni taşıyor”)
}
Yukarıda tanımladığım name değişkeni optional olduğundan, bir struct veya class içinde property olarak kullanıldığından init sırasında mutlaka değer atama zorunluluğu bulunmuyor. Compiler otomatik olarak değeri nil olarak atar.
Optional Binding
Optional Binding ile bir optional değişkenin değer taşıyıp taşımadığına bakabilir, eğer taşıyorsa onu geçici bir değişkene atayıp kullanabiliriz. Optional Binding, if ve while kontrolleri ile değeri olup olmadığı tespit edilir.
Örnekle anlatayım.
if geciciDegisken = optionalDegisken { // }
Optional Binding ile güvenli olarak tip değişimi de yapmakta mümkün.
Burada optionalDegisken’in bir değeri varsa otomatik olarak geciciDegisken’e atanıp mevcut scope için kullanmamıza imkan verecek.
var number = "1234"
if let convertedNumber = Int(number) {
print(convertedNumber)
} else {
print(number)
}
Burada eğer number değişkeni Int’e döndürülebilirse 1234, döndürülemez ise String olarak “1234” çıktısı elde ederiz.
Örneği okumak istersek:
“number” değişkenini Int tipine değiştirmeye çalış. Değiştirebilirsen onu “convertedNumber” olarak ata ve kullanabileyim. Değiştirmez isen sorun yok 🙂
Benzer kontrolü aynı anda birçok değişken için yapabiliriz.
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
// "4 < 42 < 100”
Örneğe bakıp “Burada optional olarak tanımlanan bir değeri kontrol etmedik. Sadece değişkenleri Int’e çeviriyoruz. Neden böyle bir fark var?” diye sorabilirsiniz.
Cevabı basit. Int() işlemi sonucu optional bir değer döndürür.
Özetle, Optional kavramı, bir değişkenin “değersiz” olarak tanımlanabilmesine imkan tanır. if kontrolü ile değeri olup olmadığına bakılır. Bazı durumlarda programımızın yapısı içinde bir değişkeni Optional olarak tanımlasakta, aslında program çalışırken o değişkenin her zaman bir değeri olacağına emin olduğumuz durumlar olabilir. Bu durumda her seferinde if ile kontrol etmektense daha kısa bir yol ile tanımlama yapmak mümkün.
Tanımlama için değişkenin yanına “?” yerine “!” koymak yeterli. Çoğunlukla class initialization ile alakalı olduğundan üzerinde şu an durmayacağım.
Bu yazıdaki örnekler için oluşturduğum playground dosyasına bakabilirsiniz.
https://github.com/behrank/SwiftDersleri
iyi okumalar.
Leave a Reply