Null safety

STEM

Flutter’da Null Safety

Herkese merhaba! Bu yazıda sizlere null safety ve Flutter’da null-safety’den bahsedeceğim.  Dart geliştirici ekibinin hazırladığı null safety hepimizin heyecanla izlediği Flutter Engage etkinliğinde duyurulan Flutter 2.0’dan itibaren kullanılabilir durumda. Peki null kavramı ne anlama gelir? Basitçe null, İngilizce’de “hiçlik” anlamına gelir. Null değerinin varlığı, bir değerin olmadığını veya değerin bilinmediğini gösterir. Ayrıca null değeri karşılaştırılamaz, yani iki null değerini karşılaştırmak yine null verecektir. Çünkü karşılaştırılacak değeriniz tam anlamıyla hiçliktir. Null safety’i daha iyi öğrenmek için biraz geçmişe gidelim. Null pointer ya da null reference, 1965’de Tom Hoare tarafından icat edildi. Kendisi 2009’daki bir konuşmasında bundan “milyar dolarlık bir hata” olarak bahsedecekti. Tom, nesne tabanlı programlama için  kapsamlı bir type system tasarlıyordu. Bütün referans kullanımlarının güvende olduğundan emin olmak için en kolay çözüm olan null pointer reference implement etti ve bunun bir sonucu olan “Null Error” doğdu. [youtube v=”ybrQvs4x0Ps”] Null Safety Nedir? Her dilde bildiğiniz gibi integer, double, string olmak üzere birçok değer alan değişken türleri vardır. Bu değişken türleri bazen null bir değer aldığında uygulamamız bu null değerleri işleyemez. Null-safety ile birlikte aslında nullable (null atanabilen) ve non-nullable (null atanamayan) değişkenleri ayırt ederek daha güçlü bir yapı elde edilir. Null Safety’nin amacı “null” değeri ortadan kaldırmak değildir. Bir değerin sadece “hiç” olmasına izin vermek, bir dilin esnek ve kullanışlı olmasına fayda sağlar. Null safety’nin gerçek amacı, hangi değişkenlerin null değer alıp alamayacağının kontrolünü geliştiricilerin eline bırakmaktır. Böylece bu değerden dolayı oluşabilecek hataların ve çökmelerin önüne geçebilirsiniz. Flutter’da null-safety’den bahsetmek gerekirse Dart 2.12.0 sürümünden önce değişkenlere null değeri atayabiliyorduk ama bu değer fonksiyonların içerisinde kullanılırsa karşımıza bir hata çıkıyor. Dart 2.12.0 sürümüyle beraber herhangi bir değişkene null bir değer atadığım durumda dart analysis’de bir hata ile karşılaşacağız. Dart’a bir değerin null olabileceğini söylemediğimiz sürece, nun-nullable (null olamaz) olarak değerlendirilir. Bu bütün değerler için varsayılandır. Flutter ekibi, geliştiricilerin kullandığı API’lardan en popülerinin non-null olduğunu fark ettiği için non-nullable varsayılan tercih edildi. Peki eski kodlarımız artık işe yaramaz mı? İstediğiniz bir anda kodlarınızı kademeli olarak null-safety’e geçirmek mümkün. Aynı projede aynı anda null-safe ve Non-Null-Safe kod kullanmanız da mümkün. Ayrıca Flutter ekibi geçişte size yardımcı olacak araçlar da sağladı. Null-safety’nin tek avantajı daha az bug almak değil, daha küçük binary’ler ve daha hızlı çalıştırma imkanı sağlamasıdır. Dart dilinde Null Safety Bu aldığımız hata Dart dilinde null safety etkinleştirdiğimizde birinci değer değişkeninin null olamayacağı anlamına gelir ve bu değerin null olup olamayacağını belirtmediğimiz sürece null değerine sahip olamaz. Bu problemleri daha kodu çalıştırmadan önce bulabilmemiz için çok yardımcı olur. Artık bir değişkenin null olup olmadığını sürekli kontrol etmenize gerek kalmaz. Kodunuzu daha güvenle yazabilirsiniz ve artık çalışırken null hataları yerine kod yazarken static hatalar alırsınız. Daha önce de bahsettiğim gibi null-safety’nin gerçek amacı, hangi değişkenlerin null değer alıp alamayacağının kontrolünü geliştiricilerin eline bırakmaktır. Peki nasıl? “Late” kelimesi, “?” ve “!” karakterlerini kullanarak Dart’da karşılaşacağımız null hatalarımıza çözüm bulabiliriz. Bunların nasıl kullanıldığını ve egzersizlerini Dart’ın kendi dokümantasyonunda da bulabilirsiniz. ? Operatörü Kullanımı Değişken türümüzün sonuna bir soru işareti (Null Aware Operator) eklemek Dart’a null değer kullanımına izin verdiğimizi söyler. O zaman bu hem kendi değişken türünde bir değer hem de null değer alabilir. Bu değişkeni nullable olarak belirlediğimiz zaman, bu değişkenden etkilenen kodları buna göre uyarlamazsanız yine hata alırsınız. Özellikle bununla ilgili Dart’ın codelab’inde bir sürü egzersiz bulunuyor. Bu egzersizler sayesinde bu özelliğe daha hakim olabilirsiniz. Late Kullanımı Değişkenimizin önüne “Late” koymamız ile Dart’a, bu değişkene değer atamadığımızı fakat ilk fırsatta değer atayacağımızı ve null yapmamasını belirtiyoruz. Bu sayede kodumuz, null gözüken değerin belirlendiği satıra kadar sorunsuzca çalışmaya devam edecektir. Burada “late” yerine “?” kullanmak da işe yarayabilir. Ancak “late” kullanmaktaki amacımız, kodun değer alana kadar sorunsuzca çalışmasını sağlarken null olmayacağından emin olmak. Ayrıca “late” başka güçlere de sahip, örneğin initializer bulunduran bir alanda “late” kullanarak bu alanı tembel hale getirebilir tam olarak bir üst düzey değişken veya statik alanda bir initializer gibi çalıştırabilirsiniz. Bu, bir alanın çalıştırılmasının maliyetli ya da gereksiz olduğu anlarda oldukça kullanışlı olabilir. Bir başka kullanım ise “late” ve “final” kombinasyonu. Bu şekilde normal bir “final” gibi anında çalıştırılması (initialize) yerine daha sonraya atayabiliyorsunuz. ! Operatörü Kullanımı Null Assertion Operator olarak da görebileceğiniz ünlem, daha önce nullable olarak belirlediğimiz değişkenin null değer alamayacağından eminseniz güvenlikten ve performanstan ödün vermeden önceden nullable olan değişkenler üzerindeki metodları daha sonra da çağırabilmenize olanak sağlar. Son olarak bunlar şimdiden göze karmaşık gelebilir, özellikle Dart’ın bu konuyla ilgili upuzun bir dokümantasyonu mevcut. Ancak hepsini özümseyip kodunuzu null-safety dünyasına adapte ettiğinizde sapasağlam bir uygulamaya ulaşmak için harcadığınız çabaya değdiğini içten içe hissedeceğinizi umuyorum. Null safety hakkında daha fazla bilgi edinmek için Understanding null safety | Dart ve CodeLab egzersizleri için Null safety codelab | Dart linklerine gidebilirsiniz.

STEM

Kotlin’de List ve Array Mantığı

Merhabalar, Kotlin temelleri serimize kaldığımız yerden devam ediyoruz. Bugünkü yazımızda Kotlin’deki list ve array mantığına değineceğiz. Kotlin tarafında bir ya da birden fazla aynı tipte veriyi tutmak için Collections yapılarını kullanırız. Fakat biz bugün Android Development Resources for Educators dokümanında anlatıldığı gibi sadece list ve arraylerden bahsedeceğiz. List List’lerde elemanlara liste içerisindeki pozisyonları yani index değerleri aracılığıyla erişiriz. Değişkenler sıralı biçimdedir ve bir öğe liste içerisinde birden fazla kez bulunabilir. Google’ın bize sunduğu dokümanda da belirtildiği gibi kurallı bir cümle list’e örnek olarak gösterilebilir. Cümle kurallı olduğu için kelimelerin sırası önemlidir ve kelimeler sıralı bir şekildedir. Kotlin’de listeler mutable (değiştirebilir) ya da read-only (salt okunur) şeklinde olabilmektedir. Read-only listeler için listOf(), mutable listeler için ise mutableListOf() ifadelerini kullanacağız. Şimdi listOf() ile ilgili bir örnek yapalım. Şehir isimlerini sıralı bir şekilde cities adlı değişkenin içinde list yardımıyla tuttuk. Kodun çıktısı şu şekildedir: [İstanbul, Tekirdağ, Ankara, İzmir] Şimdi ise mutable bir liste örneği yapalım. Bu kod bloğunda ise iki farklı çıktı aldık. İlk çıktımız yukarıda yazmış olduğumuz kod bloğunun çıktısıyla aynıdır. Aradaki tek fark listemiz mutable yani değiştirilebilir bir liste olduğu için liste içinden eleman çıkarma işlemini gerçekleştirebildik. Bu yüzden kod hata vermedi ve ikinci çıktımız şu şekilde oldu: [İstanbul, Tekirdağ, İzmir] Daha önceki yazılarımızda val anahtar kelimesiyle tanımlanan bir değerin değiştirilemeyeceğinden bahsetmiştik. Fakat burada üzerinde değişiklik yaptığımız listeyi val anahtar kelimesiyle tanımladığımız bir değere atadık. Burada dikkat edilmesi gereken nokta şudur; listenin hangi değişkene atıfta bulunduğunu değiştiremeyiz ancak listenin içeriğinde değişiklikler yapabiliriz. Aynı liste üzerinde eleman ekleme ve index değerine göre silme işlemi de yapabiliriz. Onun da örneğini verelim. Arrays Diziler aynı tipte birden çok veriyi saklamamıza olanak sağlar. Verileri kolayca sıralamak ve içlerinde arama yapmak için diziler kullanılır. Dizilerin boyutları sabittir ve elementleri (eleman ya da verileri) mutable özellik gösterir. Ayrıca dizi içinde ekleme çıkarma işlemi yapılamaz fakat dizi elemanları üzerinde güncelleme yapılabilir. Bir dizi oluşturalım ve değer ataması yapalım. Colors adında boyutu 4 olan boş bir array tanımladık ve 0. index’ine blue kelimesini atadık. Dizi oluşturmak için bu yöntem kullanılacağı gibi diğer bir yöntem olan arrayOf() da kullanılabilir. Animals adında bir dizi oluşturduk ve içine bazı hayvan isimleri yazdık. Görüldüğü üzere index değerini kullanarak dizinin istediğimiz elemanına erişebiliriz. Aynı zamanda index değerini bildiğimiz bir elemanı başka bir elemanla da değiştirebiliriz. Bonus: Null Safety Yazımızı bitirmeden Kotlin’i oldukça ilgi çekici kılan bir özellikten bahsedelim: Null safety özelliği. Kotlin’de değişkenler default olarak boş tanımlanamaz (safe call operatörü kullanımı hariç). Null referans gösteren bir kod NullPointerException hatasına neden olacaktır. Bu hata önemli bir hatadır. Kotlin’de uygulamayı çökertmeden null olabilecek değişkenleri kolayca kontrol edip bu hatayı önleyebiliriz. Safe Call Operatörü Verinin tipinden sonra kullanılan (?) işareti değişkenin boş olabileceğini belirtmek için kullanılır.   Bugün genel hatlarıyla listelere, dizilere ve Kotlin’deki NullPointerException hatasına değindik. Bir sonraki yazıda ise fonksiyonlardan bahsedeceğiz. Sonraki yazıda görüşmek üzere.    

Scroll to Top