Fonksiyonlar Türünden Değişkenlerin Bildirilmesi

Fonksiyonlar da bellekte ardışıl byte toplulukları biçiminde bulunmaktadır. Onların da adresleri vardır. Örneğin aşağıda iki parametresinin toplamına geri dönen add isimli bir fonksiyonun IA32’deki sembolik makine dili karşılığını görüyorsunuz:

add:
push     ebp
mov     ebp, esp
mov     eax, [ebp + 8]
add     eax, [ebp + 12]
ret

Bir fonksiyonun yalnızca ismi (parantezler olmadan) onun bellekteki adresi anlamına gelir. Örneğin:

func add(a: Int, _ b: Int) -> Int
{
return a + b
}

Burada add ismi bu fonksiyonun bellekteki başlangıç adresi anlamına gelir. Fonksiyonu çağırırken kullandığımız parantezler ise “o adresteki fonksiyonu çağır” anlamına gelmektedir. Örneğin:

result = add(10, 20)

Burada add adresinden başlayan fonksiyon çağrılmış ve onun geri dönüş değeri result değişkenine atanmıştır.

Swift’te bir fonksiyonu tutabilecek bir değişken bildirilebilir. Bu açıdan fonksiyon türünden değişkenler de birinci sınıf vatandaş (first class citizen) statüsündedir. Fonksiyonu tutabilecek değişkenlerin türleri aşağıdaki gibi oluşturulmaktadır:

([tür listesi]) ->

Geri dönüş değeri olmayan fonksiyonların türleri ise şöyle belirtilir:

([tür listesi) -> ()

ya da:

([tür listesi) -> Void

Aslında Void sözcüğü zaten aşağıdaki gibi typealias yapılmıştır:

typealias Void = ()

Yani Void demekle () demek tamamen aynı anlamdadır (typealias’lar sonraki konularda ele alınmaktadır).

Fonksiyon türünden bir değişkene ancak parametre türleri ve geri dönüş değeri aynı olan fonksiyonların ya da metotların adresleri atanabilir.

Örneğin:

f bir fonksiyonu tutan değişiken olsun. f değişkeninin tuttuğu fonksiyon yine f(…) ifadesi ile çağrılmaktadır. Örneğin:

result = f(10)
print(result)               // 100

Swift’te fonksiyon türleri kategori olarak referans türlerine ilişkindir. Yani bir fonksiyon türünden değişken bir fonksiyonun adresini tutar. Yukarıdaki örnekte f foo fonksiyonunun adresini tutmaktadır. Bundan sonra “bir değişkenin bir fonksiyonu tuttuğundan” söz edildiğinde onun adresini tuttuğu anlaşılmalıdır.

Aynı türden iki fonksiyon değişkeni birbirine atandığında aslında bunların içerisindeki adresler birbirlerine atanmaktadır.

Böylesi işlemlerin C ve C++’ta fonksiyon göstericileri (pointer to functions) ile C#’ta da delegeler (delegates) ile yapıldığını anımsayınız.

Bir fonkisyon değişkeni yapı ya da sınıfların içerisindeki metotların da adreslerini tutabilir. Bu durumda bizim ilgili değişkene sınıf ya da yapı değişkeni ile metot ismini nokta operatörü ile birleştirerek vermemiz gerekir. (Bu kısmın C#’taki delegelere çok benzediğine dikkat ediniz). Örneğin:

Benzer biçimde statik metotlar da fonksiyon değişkenlerine sınıf ismi belirtilerek atanmalıdır:

Bir fonksiyonun parametre değişkeni bir fonksiyon türünden olabilir. Örneğin:

Array yapısının sort isimli metodu bizden bir karşılaştırma fonksiyonu alır. Sıraya dizme sırasında dizinin iki elemanını bu karşılaştırma fonksiyonuna sokarak duruma göre yer değiştirme uygular. Karşılaştırma fonkiyonunun parametrik yapısı şöyledir:

cmp(a: T, b: T) -> Bool

Burada T dizinin türünü belirtiyor. Eğer biz diziyi küçükten büyüğe sıraya dizecekseksek ilk parametre ikinci parametreden küçükse true değerine, değilse false değerine geri dönmeliyiz. Örneğin:

Örneğin:

Array yapısının sort metodu MutableCollectionType arayüzünden gelmektedir. Böyle bir sort fonksiyonunu “kabarcık sıralaması (bubble sort)” algoritmasıyla aşağıdaki gibi yazabiliriz:

Bir fonksiyonunun geri dönüş değeri de bir fonksiyon türünden olabilir. Yani fonksiyon bize geri dönüş değeri olarak bir fonksiyon verebilir. Örneğin:

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir