Jenerikler ve Tür Parametreleri
Tür güvenliğiyle yeniden kullanılabilir bileşenler oluşturmak için genel sınıfları ve yöntemleri nasıl yazacağınızı anlayın.
Jenerikler ve Tür Parametreleri, CoddyKit'te ücretsiz bir Scala for Backend Engineering & Functional Programming dersidir. Bu, 3 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Scala for Backend Engineering & Functional Programming öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Scala for Backend Engineering & Functional Programming kursu toplamda 3 dersten oluşur.
Genel Türler Nedir?
String, Int veya özel bir nesne gibi her türden öğeyi barındırabilen bir kapsayıcı oluşturmanız gerektiğini düşünün. Genel türler olmadan her tür için ayrı bir kapsayıcı yazmanız ve bunun sonucunda tekrarlı kod oluşturmanız ya da Any gibi çok genel bir tür kullanmanız gerekirdi.
Genel türler, derleme zamanında tür güvenliğini korurken çeşitli veri türleriyle çalışabilen esnek ve yeniden kullanılabilir kod yazmanızı sağlar. Bu, farklı malzemeleri daha sonra yerleştirebileceğiniz bir taslak gibidir!
`Any` Türü Tuzağı
Türler için yer tutucu olarak Any kullanmak sorunlara yol açabilir. Her şeyi depolamanıza izin verse de belirli tür bilgilerini kaybedersiniz. Bu da çoğu zaman öğeyi özgün türüne geri dönüştürmenizi gerektirir. Bu işlem hataya açıktır ve dönüştürme yanlışsa çalışma zamanında çökmelere neden olabilir.
Bu örneği çalıştırmayı deneyin ve olası sorunları düşünün:
class ItemHolder(val item: Any)
object Main {
def main(args: Array[String]): Unit = {
val stringHolder = new ItemHolder("Hello Scala")
val numberHolder = new ItemHolder(123)
// We need to cast, and it's unsafe if we get it wrong
val retrievedString = stringHolder.item.asInstanceOf[String]
println(s"Retrieved String: $retrievedString")
// If we uncomment the line below, it compiles but will crash at runtime!
// val wrongType = numberHolder.item.asInstanceOf[String]
// println(s"Wrong Type: $wrongType")
}
}Tür Parametrelerine Giriş
Genel türler, tür parametreleri ekleyerek Any türü tuzağını çözer. Bunlar, bir sınıf örneği oluştururken veya bir yöntem çağırırken belirttiğiniz gerçek türler için yer tutucular gibidir.
Scala'da tür parametreleri, sınıf veya yöntem adından sonra köşeli parantezler ([]) kullanılarak tanımlanır ve genellikle T, A, B gibi tek büyük harflerle gösterilir. Örneğin class Box[T], T adlı tek bir tür parametresi alan genel bir Box sınıfı tanımlar.
Genel Bir Box Oluşturma
Her türden içeriği barındırabilen, Box adlı basit bir genel sınıf oluşturalım. İçeriğin türünü temsil etmek için sınıf tanımının her yerinde T kullanıldığına dikkat edin.
Bu sayede her tür için ayrı sınıflar yazmadan dizeler, tam sayılar veya başka herhangi bir tür için kutular oluşturabiliriz.
class Box[T](val content: T) {
def get: T = content
override def toString: String = s"Box($content)"
}
object Main {
def main(args: Array[String]): Unit = {
val stringBox = new Box("Scala is fun!")
val intBox = new Box(42)
val booleanBox = new Box(true)
println(stringBox)
println(intBox)
println(booleanBox)
}
}Genel Türlerle Tür Güvenliği
Genel türlerin en büyük avantajı derleme zamanında tür güvenliği sağlamasıdır. Bir Box[String] oluşturduğunuzda derleyici, bunun yalnızca dizeler içermesi gerektiğini bilir. İçine bir tam sayı koymaya veya içeriği tam sayı olarak almaya çalışırsanız derleyici hatayı hemen yakalar.
Bu, Any kullanmak gibi tür güvenliği daha düşük yaklaşımlarda ortaya çıkan birçok yaygın çalışma zamanı hatasını önler.
class Box[T](val content: T) {
def get: T = content
}
object Main {
def main(args: Array[String]): Unit = {
val myStringBox: Box[String] = new Box("CoddyKit")
val myIntBox: Box[Int] = new Box(100)
// This works, type is String
val s: String = myStringBox.get
println(s"String from box: $s")
// This works, type is Int
val i: Int = myIntBox.get
println(s"Int from box: $i")
// The compiler prevents this line from compiling:
// val wrong: String = myIntBox.get // Type mismatch error!
}
}Yöntemler İçin de Genel Türler!
Sınıflar gibi tek tek yöntemler de genel olabilir. Genel bir yöntem, yalnızca o yönteme ait tür parametreleri alabilir. Böylece tüm sınıfın genel olması gerekmeden farklı türler üzerinde çalışabilir.
Bu, çeşitli türlere uygulanabilen belirli bir işleminiz olduğunda, ancak sınıfın kendisi genel bir kapsayıcı olmadığında kullanışlıdır.
Esnek bir `printPair` Yöntemi
İşte genel bir printPair yöntemi örneği. Herhangi iki türden oluşan bir çifti yazdırabilmesini sağlayan A ve B adlı iki tür parametresi alır. Tür parametrelerinin yöntem adının hemen ardından tanımlandığına dikkat edin.
Bu, yöntemi farklı veri birleşimleri için son derece yeniden kullanılabilir hâle getirir.
object Util {
def printPair[A, B](first: A, second: B): Unit = {
println(s"Pair: ($first, $second)")
println(s"Type of first: ${first.getClass.getName}")
println(s"Type of second: ${second.getClass.getName}")
}
}
object Main {
def main(args: Array[String]): Unit = {
Util.printPair("Hello", 123)
Util.printPair(true, List(1, 2, 3))
Util.printPair(4.5, 'C')
}
}Akıllı Tür Çıkarımı
Scala'nın güçlü özelliklerinden biri tür çıkarımıdır. Genel sınıfları veya yöntemleri kullanırken çoğu zaman tür parametrelerini açıkça belirtmeniz gerekmez. Scala derleyicisi, sağladığınız bağımsız değişkenlere göre bunları belirleyecek kadar akıllıdır.
Bu, tür güvenliğinden ödün vermeden kodunuzu daha kısa ve okunması daha kolay hâle getirir.
class Container[T](val item: T) {
def getItem: T = item
}
object Main {
def main(args: Array[String]): Unit = {
// Scala infers T as String
val stringContainer = new Container("Inferred String")
println(s"Content: ${stringContainer.getItem}, Type: ${stringContainer.getItem.getClass.getName}")
// Scala infers T as Double
val doubleContainer = new Container(3.14)
println(s"Content: ${doubleContainer.getItem}, Type: ${doubleContainer.getItem.getClass.getName}")
// You can also specify explicitly, but often not needed
val explicitIntContainer: Container[Int] = new Container(500)
println(s"Content: ${explicitIntContainer.getItem}, Type: ${explicitIntContainer.getItem.getClass.getName}")
}
}Genel Türleri Sınırlarla Kısıtlama
Bazen genel bir sınıfın veya yöntemin yalnızca belirli yeteneklere sahip türlerle çalışmasını istersiniz. Örneğin sayıları toplayan bir yöntem yalnızca sayısal türleri kabul etmelidir.
Tür sınırları, tür parametresi olarak kullanılabilecek türleri kısıtlamanızı sağlar. Bir üst sınır (<:), tür parametresinin belirli bir türün alt türü olması gerektiği anlamına gelir. Örneğin [T <: Animal], T'nin Animal veya Animal'ın bir alt türü olması gerektiği anlamına gelir.
class Animal { def speak(): String = "..." }
class Dog extends Animal { override def speak(): String = "Woof!" }
class Cat extends Animal { override def speak(): String = "Meow!" }
// This box can only hold types that are Animal or its subtypes
class AnimalShelter[T <: Animal](val animal: T) {
def getAnimalSound: String = animal.speak()
}
object Main {
def main(args: Array[String]): Unit = {
val dogShelter = new AnimalShelter(new Dog())
println(s"Dog says: ${dogShelter.getAnimalSound}")
val catShelter = new AnimalShelter(new Cat())
println(s"Cat says: ${catShelter.getAnimalSound}")
// This would NOT compile because Car is not an Animal:
// class Car
// val carShelter = new AnimalShelter(new Car())
}
}Genel Sınıf Görevi
Genel türler konusunu anlayıp anlamadığınızı kontrol etme zamanı!
Aşağıdaki ifadeleri dikkatle okuyun ve Scala'daki genel sınıflar ve yöntemlerle ilgili doğru olanların tümünü seçin.
Genel Türler: Önemli Çıkarımlar
Bu derste Scala'nın esnek ve tür güvenli kod yazmak için güçlü bir özelliği olan genel türleri ele aldık.
- Genel türler, sınıfların ve yöntemlerin farklı türlerle çalışmasını sağlar.
- Gerçek türler için yer tutucu olarak tür parametrelerini (ör.
[T]) kullanırlar. - Genel türler, çalışma zamanı hatalarını önleyen derleme zamanı tür güvenliği sağlar.
- Scala'nın tür çıkarımı, genel kodu çoğu zaman kısa tutar.
- Tür sınırları (ör.
<:), tür parametrelerini belirli alt türlerle kısıtlayabilir.
Genel türleri kullanarak sağlam ve çeşitli veri türlerine uyarlanabilir yeniden kullanılabilir bileşenler yazabilir; böylece Scala kodunuzu daha güçlü ve hatalara daha az yatkın hâle getirebilirsiniz.
Sıkça Sorulan Sorular
“Jenerikler ve Tür Parametreleri” dersi ücretsiz mi?
Evet — “Jenerikler ve Tür Parametreleri” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Scala for Backend Engineering & Functional Programming kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Scala for Backend Engineering & Functional Programming kursu toplamda 3 dersten oluşur.
“Jenerikler ve Tür Parametreleri” dersinde ne öğreneceğim?
Tür güvenliğiyle yeniden kullanılabilir bileşenler oluşturmak için genel sınıfları ve yöntemleri nasıl yazacağınızı anlayın. Scala for Backend Engineering & Functional Programming ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Scala for Backend Engineering & Functional Programming öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Scala for Backend Engineering & Functional Programming, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 3 dersinin 1. dersidir.
“Jenerikler ve Tür Parametreleri” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Scala for Backend Engineering & Functional Programming dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Scala for Backend Engineering & Functional Programming dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Jenerikler ve Tür Parametreleri
- Varyans: Kovaryans ve Kontravaryans
- Tür Sınıfları ve Örtükler