Kotlin 101: Değişken Tipleri ve Dönüşümleri

Recep Fırıncıoğlu
5 min readFeb 2, 2020

--

Merhabalar,

Bu yazıda değişkenler, değişken tipleri ve aralarındaki dönüşümler hakkında konuşacağız. Ardından bu tipleri Kotlin’de nasıl kullandığımızı görüp ufak örneklerle görsel hafızamıza dokunduktan sonra kapanışı yapacağım.

Değişkenler en basit tanımı ile çeşitli verileri depolamak için kullanılan saklama kapları olarak düşünülebilir. Bu kaplara dilediğimiz tipte veriyi, ki bu tiplere değineceğiz, kap taşmadığı sürece koyabiliriz. Elbette her yemeği aynı kaba koymamız mümkün değil, yemeğe göre seçilen kabımız da değişecektir.

Ne mi demek istiyorum ?

Şöyle düşünelim, mutfağa girdik ve en sevdiğimiz yemekten bir tencere pişirdik, burnumuza mis gibi kokusu geliyor… Elbette bunu işe, okula götürmek istiyoruz değil mi ? Ama gelin görün ki bütün tencereyi götürebilmemiz mümkün değil fakat ben bunu ufak bir saklama kabına koyarsam tadımlık dahi olsa yanımda taşıyabilirim ya da dilersem biraz daha büyük bir kap ile daha fazla miktarda yemeği yanıma alır ve günün en tatlı dakilarını en sevdiğim yemeğimle geçirebilirim.

İşin hikaye kısmını atlattıysanız hadi şimdi biraz daha derine inelim. Değişkenler atandıkları tipe bağlı olarak bellekte farklı biçimlerde tutulur ve bu tipler birbirinden farklı boyutlara sahiptir. Hatırlayın her yemeği aynı kaba koyamıyorduk.

Günlerce, belki haftalarca üzerinde çalıştığımız kodlar, günün sonunda bir veriyi işleyip sonucu kullanıcıya sunmak için tasarlanır. Bu esnada işlenen veriler kullanıcıdan alınabileceği gibi doğrudan bellekte tutulan değerler de kullanılabilir. Tanımladığımız her bir tipin bellek üzerinde belirlenmiş bir boyutu vardır ve bu veriler belirttiğimiz tiplere ait alanlarda depolanırlar.

Çok sayıda öğrencinin girdiği bir sınav hayal edelim. Dersin öğretmeni sınav sonuçlarını, puanları baz alarak sıralamak istiyor. Peki listenin içereceği veriler sadece notlar mı olacak ? Elbette hayır, listedeki notların kime ait olduğunu da belirtmesi gerekir. Tabi her öğrencinin bir de öğrenci numarası olduğunu düşünürsek listede öğrenci numaralarının da bulunması mantıklı olabilir.

Notları ve öğrenci numaralarını sayısal değişkenlerin tutulduğu bir veri tipinde, isimleri ise sözel, metinlerin tutulduğu bir veri tipinde saklamamız gerekecek.

Aşağıdaki listede farklı veri tiplerini, bunların bellekte kapladığı alanı ve değer aralığını inceleyebilirsiniz.

Değişken Tanımlama

Kotlin’de değişken tanımlamalar iki farklı anahtar kelime ile yapılıyor;

val: Bu anahtar kelime “value” kelimesinden gelmektedir ve sabit değer tanımlamak için kullanılır. Val değişkenler, daha sonra kod akışı içerisinde değiştirilemezler.

var: Bu anahtar kelime “variable” kelimesinden gelmektedir ve tanımlanan değerler kod içerisinde daha sonradan değiştirilebilir, güncellenebilir.

Şimdi önemli bir noktanın altını çizelim, kodunuzu yazmaya başlarken kullanacağınız değişkenleri mümkün olduğunca val olarak tanımlamaya gayret etmelisiniz. Değişmez objelerin kullanımı kodu en doğru şekline bir adım daha yaklaştırır ve istenmeyen rastgele değişikliklerden kaçınmanızı sağlar. Program akışında bir yerde değere müdahale edilmesi gerekiyorsa zaten kullandığınız IDE sizi bunun hakkında uyaracaktır.

Aşağıda bir öğrenci ismi, notu ve öğrenci numarasının tanımlanabilmesi için iki farklı metodu görüyorsunuz. İlk durumda değişkenlerin değerleri ile birlikte tiplerini de veriyoruz.

Fakat Kotlin’in tatlı yanlarına merhaba deme vaktiniz geldi. Bir sonraki örnekte göreceğiniz gibi gibi aynı tanımlamaları değişken tipi belirtmeden de yapabiliyoruz. Nasıl mı ? Kotlin girdiğiniz değere uygun olan tipe verinizi kendisi atayabiliyor. Yani, “Panik yok!”

Her iki örnekte de değişkenlere aynı değerler aynı tipte atanmıştır.

Fakat bazı durumlarda maksimum performansı alabilmek, bellekte gereksiz yer tutmamak adına değişkene değer ataması yapılırken dogru degisken tipini kullanmak önemlidir. Çünkü siz aksini belirtmediğiniz ve yukarıdaki listede belirtilen değer aralığını aşmadığınız sürece, Kotlin girdiğiniz tüm sayısal veri tiplerini “Int” olarak sınıflandıracaktır. Int tipinin değer aralığını aştığınızda veriyi “Long” tipinde tutulacaktır.

Yani siz val number1 = 15 ve val number2 = 9999 şeklinde iki değişken tanımladığınızda sayısal değerleri arasında ne kadar fark olursa olsun bellekte her iki değişken de ayrı ayrı 32bit bir sayı ile ifade edilecektir. Oysa listeye göz attığımızda number1 değişkeni için byte, number2 değişkeni için ise short tipinde değişkenler kullanmamızın yeterli olduğunu göreceksiniz. Dolayısıyla değişken atamalarımızı aşağıdaki gibi yaparsak bellek alanını daha verimli kullanmış olacaksınız. Bu durumda number1 değişkeni için 8bit, number2 değişkeni için 16bit boyutunda bir alan ayırmış olduk.

Yukarıdaki hikayede bahsettiğim tadımlık yemeği küçük bir saklama kabında yanımızda taşımamız da buna benziyor. Ben koca bir tencereyi de yanıma alabilirdim fakat küçük bir saklama kabına ihtiyaç duyduğum kadarını koymak benim için yeterli ve daha verimli.

Belleği verimli kullanabilmek adına değişkenlerimizi optimum verimi sağlayabilecek olan tiplerde tanımlamış olduk.

Aşağıda ise kullanabileceğimiz tiplerin kullanım şekilleri ile bir listesi bulunmakta. Görüleceği üzere Long degiskenler icin sayinin sonuna “L” ve Float değişkenler için “F” ya da “f” konularak deger atamasi yapilabilir. Özellikle float ve double veri tipleri aritmatik işlemlerde sıklıkla karşımıza çıkacak. Bunlar dışında hexadecimal, binary sayılar ve ayrıca karakterleri temsil eden char ile birlikte kontrol yapılarında da içli dışlı olacağımız, sadece true ve false değerlerini alabilen, boolean ifadelerimiz de tanımlanabiliyor.

Çok büyük ya da uzun sayıların tanımlamaları yapılırken daha okunaklı olması adına “_” karakteri kullanılabilir. Hemen yeşillendirelim.

Şurada biraz da dizilere (arrays) değinelim öyleyse. Dizilerde diğer veri tipleri gibi aslında, sadece birden fazla veriyi bir arada tutmak için kullanılıyorlar. Hatta bu verilerin aynı tipte olmasına bile gerek yok.

Aynı tip değerleri tutması istenen diziler arrayOf() anahtar kelimesi ile tanımlanırlar. Birbirinden farklı tipleri içeren bir dizi tanımlamak için arrayOf<Any>() şeklinde bir tanımlama kullanılabilir. Bunun dışındaarrayOfNulls<Type>() ile verilen değer kadar null eleman içeren bir dizi tanımlanabilir.

Not: Bir dizinin boyutunu diziyi oluşturduktan sonra değiştiremiyoruz. Böyle bir şey ile karşılaşırsanız burdan listOf() metoduna göz atmanızı öneririm. Şimdilik bu yazı içerisinde bu konuya değinmeyeceğim.

Tip Dönüşümleri (Type Conversion)

Tip dönüşümleri adından da anlaşılacağı gibi bir veri tipindeki değişkeni başka bir veri tipine dönüştürmeyi ifade etmektedir. Bu konuda Kotlin’de bilmemiz gereken minik bir püf nokta mevcut; Implicit ve Explicit.

Java ile münasebetiniz olduysa, Java’nın küçük veri tiplerinden büyük olanlara implicit conversation desteği olduğunu biliyorsunuzdur. Int tipinde bir değişken long tipine dönüştürülebiliyordu.

Java’da implicit dönüştürme işlemi — Başarılı

Fakat Kotlin implicit tip dönüşümünü desteklemiyor. Yani int bir değişkeni long tipine yukarıdaki Java örneğinde gösterdiğim gibi atayamıyoruz. Aşağıda bunun gerçekleşemediğini görebiliyoruz.

Kotlin’de implicit dönüştürme işlemi — Başarısız

Kotlin’de veri tipleri arasındaki dönüşümleri yardımcı explicit fonksiyonları kullanarak yapıyoruz, nasıl mı?

Kotlin’de explicit dönüştürme işlemi

Tip dönüştürme işlemlerinde aşağıdaki yardımcı fonksiyonlar kullanılabilir.

toByte(), toShort(), toInt(), toLong(), toFLoat(), toDouble(), toChar()

Not: Boolean tipine dönüşüm yapmak için yardımcı fonksiyonumuz yok.

Öyleyse tip dönüşümlerini içeren örnek bir kod bloğu yazalım.

Program çıktısı aşağıdaki gibi olacaktır.

Yazıyı şimdilik burada sonlandırıyorum. Devamında “Kontrol Yapıları” başlığı altında; if, if else, while, for, when yapılarından bahsedeceğim.

--

--