Swift Programlama Dili Inceleme

23 minute read

Merhaba,

2019 hedeflerimden bir tanesi mobil geliştirme alanına(IOS) giriş yapmak olarak belirledim ve bunun sonucunda öğrendiklerimi, notlarımı, araştırmalarımı düzenli bir şekilde paylaşmaya çalışacağım.

Bu ilk yazıda swift diline ve dökümanlarına göz gezdirdim. Kabataslak diğer dillere benzeyen neler var, dilin sentaks yapısı nasıl, mimarı açıdan nasıl gibi sorulara yanıtlar aradım. Tabi dilin tüm özelliklerini bir makale de anlatmak çok zor. Bunun için ileri ki yazılarımda tek tek ayrıntılara gireceğim.


Bu yazıda hangi konulara değiniyorum;

  • Swift Programlama Dili Neden Ortaya Çıktı?
  • Swift Nasıl Bir Programlama Dilidir?
  • Swift Standart Kütüphanesi Neler İçeriyor?
  • Bildirim İşlemleri Nasıl Yapılıyor?
  • Swift Dilinde String ve Character
  • String Interpolation
  • Fonksiyonların Bildirimleri
  • Swift Dilinde Fonksiyon Overload Var mı?
  • Swift dilinde sabitler nelerdir?
  • Optional Türü ve Nil Sabiti
  • Swift Dilinde Tür Dönüşümleri
  • Swift Dilinde Operatörler
  • Swift dilinde Pointer var mı?
  • Swift dilinde bir nesneyi adres yoluyla fonksiyonlara aktarabilir miyiz?
  • Swift Stack ve Heap Kavramları

Swift Programlama Dili Neden Ortaya Çıktı?

  • Bu sorunun cevabını genel olarak ihtiyaç ve gelişen dünyanın, teknolojinin gerisinde kalmamak olarak verebiliriz.

  • IOS ve MacOS sistemlerin ana geliştirme dili Objective C. Fakat Objective C öğrenmenin bir maliyeti var. Objective C, C dili üzerine nesne yönelimli özellikler eklenerek oluşturulmuş bir dil. Diğer birçok nesne yönelimler diller gibi Smaltalk’tan esinlenilmiş. Bu dili öğrenmek için önce C dilinin öğrenilmesi gerekiyor. Bu da öğrenme gerisini yukarı çekiyor.

  • Apple firması bunun sonucunda daha modern ve basit öğrenilebilecek bir programlama dili arayışına girmiş. Bunun sonucunda Swift programlama dili çıkıyor. Swift dilinin geliştirilmesine Chris Lattner tarafından 2010 yılında başlanmış.

Chris Lattner

  • Swift dili yazım kolaylığı ve dizayn olarak diğer birçok programlama dilinden esinlenerek oluşturulmuş. Swift programlama dili Linux, MacOS, IOS platformları destekliyor.

Swift Nasıl Bir Programlama Dilidir?

  • Swift, C++ programlama dili gibi multi paradigm bir programlama dilidir. Bunun anlamı object oriented, functional, procedural programlama modellerini kullanarak uygulamalar geliştirebiliriz.

  • Tabi ki swift Objective C dilinden pek çok özellik almıştır.

  • Swift başta Objective-C olmak üzere Python, Haskell, Java, C# gibi dillerden güçlü gördüğü özellikleri almış. Bu nedenle diğer dillerden swift’e geçenler rahatlıkla bu dili öğrebilirler.

  • Swift açık kaynak bir programlama dilidir. [https://github.com/apple/swift]

  • Swift derlenen bir programla dilidir, gerçek makina kodları üretmektedir. Swift derleyicisi LLVM derleyici geliştirme ortamından faydalanılarak yazılmış. Bu sebeple swift uygulamaları hızlı çalışırlar.

  • Derleyici -> [https://github.com/apple/swift-llvm]

  • Swift ile yazılan kodlar LLDB ile debug edilebilir.

  • Swift Debugger and REPL -> [https://github.com/apple/swift-lldb]


Swift Standart Kütüphanesi Neler İçeriyor?

Swift programlama dilinin standart kütüphanesi sınıflar, protokoller, global fonksiyonlar, yapılar, data türleri bulunmaktadır. [https://developer.apple.com/documentation/swift/swift_standard_library]

Dökümanlarda da görüldüğü gibi çok temel fonksiyonlar ve sınıflar barındırılmaktadır.


Bildirim İşlemleri Nasıl Yapılıyor?

Swift dilinde bir değişken kullanılmadan önce derleyiciye tanıtılması gerekiyor.[Declaration]

Bildirim işlemleri birkaç farklı şekilde yapılabiliyor. [https://docs.swift.org/swift-book/ReferenceManual/Declarations.html]

1var <degiskenIsmi> = <ilkDeger>
2var <degiskenIsmi>: <tur> = <ilkDeger>
3var <degiskenIsmiListesi>: <tur>
4
5let <degikenIsmi> = <ilkDeger>
6let <degikenIsmi>: <tur> = <ilkDeger>

Tanımlama işlemleri yaparken <tür> belirtmek zorunda değiliz. Swift dilinde Type Inference yani tür çıkarımı mekanizması bulunmaktadır. Sizin yerinize turu atanan değerden bulacaktır.

Bildirim yaparken tür belirtmiyorsak değişkene İLKDEĞER vermek ZORUNLUDUR.

1var no			// HATALI, ilk deger verin
2var no2: Int32	// GECERLI
3// kodlar devam
4var no1, no2: Int	// GECERLI
5var no = 3, no2: Int, no3 = 11, w = “Istanbul”    // GECERLI

Bildirimde var ile let arasında önemli bir farklılık vardır.

  • var ile değişken bildirildiğinde sonradan değeri değiştirilebilir.
  • Ancak let ile değişken bildirildiğinde o değişken const olur. Onun değeri bir daha değiştirilemez.

Eğer let ile bildirim yaparken tür belirtirsek aşağıda 1 kere atama yapabiliyoruz. Ama ikinci atamayı kabul etmez.

1let dil: String
2
3dil = "Swift"
4dil = "C++" // Immutable value 'dil' may only be initialized once

Özel bir sebebi yok ise let ile bildirim yaparken ilkdeğer verin.


Swift Dilinde String ve Character

Swift programlama dilinde karakter tanımlamak diğer dillerde ki gibi tek tırnak, tek karakter gibi olmuyor. Örneğe bakalım;

1let s = 'a'  // Single-quoted string literal found, use '"'
2let char = "a"
3print(type(of: char))  // String
4let char1 = "'a'"
5print(type(of: char1))  // String

Karakter tanımlama için turu açık olarak Character belirtmemiz gerekiyor

1let s: Character = "a"
2print(type(of: s)) // Character

Swift dilinde tüm temel türler birer yapıdır.


String Interpolation

String içerisinde \(ifade) olarak yer alan yapıdır. Parantez içerisindeki ifade stringe dönüştürülür. Buna string interpolation denilmektedir.

1let multiplier = 3
2let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
3// message is "3 times 2.5 is 7.5"

Fonksiyonların Bildirimleri

Swift dilinde daha öncede söylediğimiz gibi multi paradigm bir dil. Yani swift dilinde C++ dilinde olduğu gibi bir sınıf içinde, yapıların içerisinde yada global düzeyde yazılabilir. [https://docs.swift.org/swift-book/LanguageGuide/Functions.html]

Swift dilinde fonksiyon bildirimi şu şekilde yapılmaktadır;

1func <fonksiyonIsmi>([parametreler]) -> <fonksiyonGeriDonusDegeriTuru>
2{
3	// fonksiyon govdesi
4}

Fonksiyon bildiriminde geri dönüş değeri yok ise -> kullanılmayabilir.

1func greet(person: String) {
2    print("Hello, \(person)!")
3}
4
5greet(person: "Dave")
6// Prints "Hello, Dave!"

Fonksiyonun tek bir geri dönüş değeri vardır fakat birden fazla değer geri döndürmenin birden fazla yolu var.

return deyimi hem fonksiyonu sonlandırmak için hem de geri dönüş değerini oluşturmak için kullanılır.

1func sumTwoNumber(no1: Int, no1: Int) -> Int
2{
3    return no1 + no2
4}

Fonksiyon geri dönüş değeri yok ise boş return kullanılabilir. return kullanmak zorunda değiliz.

1func sumTwoNumber(no1: Int, no2: Int)
2{
3    print(no1 + no2)
4
5    return
6}

Geri dönüş değeri bildirilmiş bir fonksiyonda return kullanmak zorunludur. Geriye return ile bir değer döndürmüyorsak derleyici hata verecektir.

1func sumTwoNumber(no1: Int, no1: Int) -> Int	// HATA
2{
3    // kod
4}

Fonksiyonların parametre bildiriminde parametrelerin türleri belirtmek zorunludur.

Fonksiyonların parametre değişkenleri default olarak const durumundadır, yani fonksiyonlar tarafından bunlar değiştirilemez.

1func hi(name: String)
2{
3    name = "Kerem"  // Cannot assign to value: 'name' is a 'let' constant
4}

Parametre değişkenini değiştirmek istiyorsak inout keywordunu kullanmak zorundayız.

1func hi(name: inout String)
2{
3    name = "Kerem"
4}
  • Fonksiyonların parametre değişkenlerinin hem kendi isimleri hem de etiket isimleri vardır.
  • Etiket isimleri fonksiyon çağırılırken, parametreler fonksiyon gövdesinde kullanılır. Etiketler okunabilirliği arttırmak için var.

Etiket kullanımını şu şekilde yapabiliriz:

1func <fonksiyonIsmi> (<etiketIsmi> <degiskenIsmi> : <degiskenTuru>) -> <geriDonusTuru>
2{
3	// fonksiyon gövdesi
4}
5
6func etiket_kullanimi(genislik w: Double, yükseklik h: Double) -> Double
7{
8    return w * h // Fonksiyon gövdesinde değişken isimleri var
9}
  • Swift dilinde iç içe fonksiyon bildirimi yapabiliyoruz.

Swift Dilinde Fonksiyon Overload Var mı?

  • Evet swift dilinde function overloading mekanizması bulunuyor.

Function overloading olabilmesi için aynı isimli fonksiyon ve aşağıda bulunan özelliklerden bir veya birkaçı bulunuyor olmalı.

  • Fonksiyon geri dönüş değerinin farklılığı
  • Parametre sayılarının farklı olması
  • Parametre türlerinin farklılığı
  • Etiket isimlerinin farklılığı

Derleyicinin hangi fonksiyonu çağırdığını anlama mekanizmasını (function overload resolution) C++ üzerinden anlatmıştım. İleri de bu konuyu daha ayrıntılı anlatmaya düşünüyorum. Mekanizmanın nasıl çalıştığını anlamak için su makaleye bakabilirsiniz. [Function Overloading Resolution]


Swift dilinde sabitler nelerdir?

  • Nil Literals
  • String Literals
  • Boolean Literals
  • Integer Literals
  • Floating Point Literals

Optional Türü ve Nil Sabiti

  • Swift dilinde her T türünün T? biçimi vardır. Double Double?, String String? gibi.
  • T? anlamı hem kendi türünden değer tutabilmesi hem de nil sabitini tutabilmesidir. Değişken içerisinde ki değere ulaşabilmek için unwrap etmemiz gerekir. Unwrap etmek için <T!> yani ! operatörü kullanılmaktadır.
  • ? ve ! operatörleri kendisinden önce ki değişkene BİTİŞİK olarak yazılmalı. Yoksa sentaks hatası alırsınız. (Son ek olarak kullanılır.)
  • Swift dilinde T? türü Optional türüne eşittir. Yani
1var word: String?
2var word: Optional<String>
3// iki tanim birbirine esit
4
5Optional<T>
6Optional<Wrapped>
7// Optional turu standart kutuphane de enum olarak tanimlanmis

[Optinal]


Swift Dilinde Tür Dönüşümleri

  • Swift programlama dilinde otomatik tür dönüştürme yoktur. Otomatik tür dönüştürmelerinde veri kaybı sorunu olabilir. Swift bunun önüne geçmek için dile otomatik tür dönüşümü eklememiş.

Yani Int32 tipinde bir değişkenin değerini direk Int16 türden bir değişkene atayamayız. Type casting işlemlerini yapmamız gerekiyor.

Swift Dilinde Operatörler

Swift dilinde temel operatörler (basic operators) diler dillerde ki C, C++, C#, Java, Python operatörlere çok benzemektedir.

Operatörler genellikle üç biçimde sınıflandırılırlar:

  1. İşlevlerine Göre
  2. Operand Sayılarına Göre
  3. Operatörün Konumuna Göre

Swift dökümanlarında Basic Operators ve Advanced Operator olarak ayrılmış. Advanced operatörler de Bitwise operatörleri yer alıyor.


Swift dilinde Pointer var mı?

  • C++, C# gibi dillerden de alışık olduğumuz gibi türler iki kısma ayrılıyor. Değer türleri ve referans türleri. Eğer değişken doğrudan değerin kendisini tutuyorsa değer türüne ilişkindir. Değerin bulunduğu BELLEK ADRESİNİ tutuyorsa referans türüne ilişkindir.
  • Referans türleri C dilinde ki pointer, C++ dilinde ki referanslar gibidir. Burada bahsedilen yapılar aslında aynı. C dilinde pointer kullanımı zor olduğu için, C++ diline implemente ederken notasyonel bir hile yapılarak referans adını verdikleri yapı oluşuyor. Böylece kullanımı ve anlaşılması daha kolay bir yapı oluşturulmuş oluyor. Aslında arkada planda dönen herşey pointer.
  • Swift dilinde struct, enüm türleri DEĞER türlerine ilişkindir. String, Int, Double türlerinin hepsi aslanda birer yapıdır. Bu sebepten string türden bir değişkenin karakterlerini istersek değiştirebiliriz.
  • Class, Protocols ise referans türlerine ilişkindir.

Swift dilinde bir nesneyi adres yoluyla fonksiyonlara aktarabilir miyiz?

  • Bir nesneyi adres yoluyla da fonksiyonlara aktarmak mümkündür. Bunu inout ile yapiyoruz. Fonksiyonu çağırırken değişken önüne adres alma operatörü & getirilmelidir. Bu konuda en çok verilen örnek swap işlemi.
 1
 2func swap( sayi1 n1: inout Int,  sayi2  n2: inout Int)
 3{
 4    let temp = n1
 5    n1 = n2
 6    n2 = temp
 7}
 8
 9var n1 = 10, n2 = 20
10swap(&n1, &n2)
11print("n1 = \(n1), n2 = \(n2)")  // "n1 = 20, n2 = 10\n"
12

Swift Stack ve Heap Kavramları

  • Bir fonksiyon çağırılmamış ise fonksiyon içinde yerel değişkenler henüz belleğe yüklenmemiş ve yer kaplamıyorlardır.
  • Fonksiyon çağırıldığında değişkenler belleği yüklenir, bir takım işlemler yapılır ve fonksiyon block sonunda bellekten silinirler. Her fonksiyon çağırıldığında genel davranışları böyledir.

Swift Stack Heap

  • Yerel değişkenler ve parametre değişkenleri belleğin STACK bölgesinde oluşturulur. Stack alanı prosese özgüdür. Her thread’in aynı bir stack alanı var.
  • Global değişkenler programın başında bir kere yaratılıp uygulama bitene kadar bellekte kalırlar. Belleğin DATA ve BSS denilen alanında tutulurlar.
  • Bir de process adres alanı içerisinde HEAP alanı vardır. Swift dilinde sınıf türünden nesneleri HEAP bölgesinde yaratılırlar ve bunların bellekten silinmesiyle garbage collector ilgilenir.

Swift programlama dili nesne yönelimli programlama tekniklerini destekler. Bunun ile alakalı fazla ayrıntıya girmiyorum. Bundan sonra gelecek makaleler tek konu üzerine ayrıntılı şekilde olacaktır.