GO Fundamentals - Generics
Generics Nedir?
Generics bir fonksiyon (function) veya veri yapısı ( data structure ) üzerinde birden çok tür ile veri girişi ve çıkışı yapmanıza olanak sağlayan özel bir fonksiyon yazım türüdür.
Neden Generics?
Normal veri türlerinde bir değişken yalnızca bir veri türüne tanımlanabiliyordu. Generics yapıları sayesinde artık bir fonksiyon yazdığımızda bu fonkisyon birden çok veri türüyle çalışabilir hale gelmektedir.
Örnek Uygulama
Şimdi aşağıda örnek bir proje olan gobyexample projesini kendi bilgisayarımda uyarlanmış halini görüyorsunuz.
.
├── 20_generics
│ ├── genericsBasic.go
│ └── genericsUsage.go
├── go.mod
└── main.go
Bu örnek projemde size klasörlere bölünmüş dosya yapısını ve go üzerinde bu klasörlerden veri çağırma yöntemini de göstermek için böyle uzun bir dosya listesi ile başladım. Şimdi 20_generics isimli klasörde yer alan genericsBasic.go isimli dosyama, generics yapılarının nasıl çalıştığını incelemek adına aşağıdaki scripti ekledim. Bu kodu hep birlikte parçalarına ayırarak inceleyelim.
package generics
import (
"cmp"
"fmt"
)
func MaxInt(a int, b int) int {
if a > b {
return a
}
return b
}
func MaxString(a string, b string) string {
if a > b {
return a
}
return b
}
func MaxFloat(a float64, b float64) float64 {
if a > b {
return a
}
return b
}
// instead of three same function with different types
// instead of comparable we are using cmp.Ordered
func MaxGenerics[T cmp.Ordered](a T, b T) T {
if a > b {
return a
}
return b
}
func ExecuteMaxGenerics() {
fmt.Println(MaxGenerics(5, 8))
fmt.Println(MaxGenerics("apple", "banana"))
fmt.Println(MaxGenerics(3.14, 2.71))
}
Şimdi bu dosyamızı yazdıktan sonra nasıl çağıracağımızı ve çalıştıracağımızı da aşağıdaki main.go dosyasında gösterelim.
package main
import
generics "gobyexample/20_generics"
)
func main() {
generics.ExecuteMaxGenerics()
}
Şimdi kodumuzu teker teker parçalarına ayıralım ve ne işe yaradığını belirtelim.
func MaxInt(a int, b int) int {
if a > b {
return a
}
return b
}
Yukarıdaki MaxInt isimli fonksiyon int veri tipinde a ve b parametrelerini alıyor. Bunlara verilen argümanlara göre int veri tipinde veri döndürüyor. Sayı değerlerinden hangisinin diğerinden daha büyük olduğunu değerlendirdikten sonra sonucu ekrana döndürüyor.
Şimdi de aynı fonksiyonun string veri tipi olan versiyonunu inceleyelim
func MaxString(a string, b string) string {
if a > b {
return a
}
return b
}
MaxString fonksiyonu da string olarak verilen değerleri büyük küçük olarak karşılaştırıp string formatında geri döndürüyor.
Son olarak da float64 veri tipi için yazılmış olan MaxFloat fonksiyonunu değerlendirelim.
func MaxFloat(a float64, b float64) float64 {
if a > b {
return a
}
return b
}
Bu fonksiyon da a ve b değerlerini float64 olarak karşılaştırıp yine bir float64 döndürür.
Fakat biz aynı işlemi her veri türü için tek tek yapmak zorunda mıyız? Bunun tek ve kısa bir yazımı yok mu? Bu sorunun yanıtı da generic fonksiyonunda gizli. Şimdi MaxGenerics isimli fonksiyonumuzu inceliyoruz.
func MaxGenerics[T cmp.Ordered](a T, b T) T {
if a > b {
return a
}
return b
}
Burada ilk olarak özel bir yazımla karşılaştık:
// generics syntax
func funcname[T any](v T) {}
Bu T isimli placeholder(ter tutucu) sayesinde buraya hangi veri türü gelirse ona göre davran komutunu sistemimize belirtiyoruz. any yazan kısım ise yapacağımız işlemin türüne göre değişiklik gösterebiliyor. Burada standart olarak comparable ifadesi yer alır fakat, MaxGenerics isimli fonksiyonumuza string veri tipini de karşılaştırmak üzere vereceğimiz için cmp.Ordered kullanarak sıralı bir liste gibi davranmasını istiyoruz.
Şimdi de fonksiyonumuzun çalışıp çalışmadığını test etmek için aşağıdaki fonksiyonumuzu yazıp test ediyoruz.
func ExecuteMaxGenerics() {
fmt.Println(MaxGenerics(5, 8)) // int
fmt.Println(MaxGenerics("apple", "banana")) //string
fmt.Println(MaxGenerics(3.14, 2.71)) // float
}
Bu kodumuzu main.go fonksiyonumuzdan çağırıp çalıştırdığımızda aşağıdaki gibi bir çıktı alıyoruz.
8
banana
3.14
Burada dikkat ederseniz string ifadeleri karşılaştırırken hangisinin daha çok karaktere sahip olduğuna bağlı olarak banana isimli argümanı döndürdü.
Sonsöz ve Değerlendirme
Bu yazımda:
- Generics ifadeleri nedir?
- Generics ifadeleri ne zaman kullanılır?
- Generics ifadelerinin yazım şekli (syntax) nasıldır?
gibi sorulara temel seviyede yanıtlar verdim. Konu ile ilgili daha detaylı bilgi edinmek isteyenler aşağıdaki linkleri de inceleyebilirler.
- https://go.dev/blog/intro-generics
- https://www.geeksforgeeks.org/go-language/generics-in-golang/
- https://go.dev/doc/tutorial/generics
Şimdilik bu yazının sonuna geldik. Yeni yazılarda görüşmek üzere...
Allah'a emanet olun.