CodeBlanks Logo Icon CodeBlanks

Meydan okuma 2: Variance

Variance kurallarını yoklayan bir görev çözersin.

Varyans: kovaryans ve kontravaryans

Varyans, tür parametreli türlerin alt tür ilişkisini nasıl aktardığını tanımlar. Değer üreten türler kovaryandır: Producer<Dog>, Producer<Animal>'a atanabilir. Parametre tüketen türler kontravaryandır: Consumer<Animal>, Consumer<Dog>'e atanabilir.

type Producer<T> = () => T;
type Consumer<T> = (x: T) => void;

let pA: Producer<Animal>;
let pD: Producer<Dog>;
pA = pD;  // OK (kovaryans)

strictFunctionTypes açıkken fonksiyon parametreleri katı kontravaryan olur; sınıf metotları bivaryan kalır.

Uygulama Kovaryans göster

Animal sınıfı (alan name = "hayvan") ve Dog extends Animal tanımla. Producer<T> = () => T türünü yaz. pDog: Producer<Dog> değeri oluştur, sonra pAnimal: Producer<Animal>'a ata (kovaryans) ve pAnimal().name'i yazdır.

Başlangıç kodu

index.ts
// Producer<T> kovaryandır
// Animal sınıfı (name = "hayvan") ve Dog extends Animal
// pDog: Producer<Dog> oluştur, pAnimal: Producer<Animal>'a ata
// pAnimal() çağırıp name'i yazdır

Örnek çözüm

index.ts
class Animal { name = "hayvan"; }
class Dog extends Animal { bark() {} }

type Producer<T> = () => T;

const pDog: Producer<Dog> = () => new Dog();
let pAnimal: Producer<Animal>;
pAnimal = pDog;
console.log(pAnimal().name);

Beklenen çıktı

hayvan

Uygulama Kontravaryans göster

Animal sınıfı (alan name = "h") ve Dog extends Animal tanımla. Consumer<T> = (x: T) => void türünü yaz. cAnimal: Consumer<Animal> değeri console.log("yedi " + x.name) yapsın. cAnimal'ı cDog: Consumer<Dog>'e ata (kontravaryans) ve cDog(new Dog()) çağır.

Başlangıç kodu

index.ts
// Consumer<T> kontravaryandır (strictFunctionTypes açık)
// cAnimal: Consumer<Animal>, cDog: Consumer<Dog>
// cAnimal'ı cDog'a ata, sonra cDog'u yeni bir Dog ile çağır

Örnek çözüm

index.ts
class Animal { name = "h"; }
class Dog extends Animal {}

type Consumer<T> = (x: T) => void;

const cAnimal: Consumer<Animal> = (x) => { console.log("yedi " + x.name); };
let cDog: Consumer<Dog>;
cDog = cAnimal;
cDog(new Dog());

Beklenen çıktı

yedi h

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 `strictFunctionTypes` açıkken hangi atama derlenir?

index.ts
type Consumer<T> = (x: T) => void;
class Animal { name = "a"; }
class Dog extends Animal {}
let cAnimal: Consumer<Animal>;
let cDog: Consumer<Dog>;
  • Hiçbiri derlenmez
  • cAnimal = cDog;
  • cDog = cAnimal; Doğru cevap
  • cAnimal = cDog; ve cDog = cAnimal; ikisi de

Açıklama: Tüketici türler kontravaryandır; daha genel olan `Consumer<Animal>` daha özel olan `Consumer<Dog>`'e atanabilir, tersi olmaz.

2 Tüketici tanımı

Soru
// T'yi parametre olarak tüketen fonksiyon
type Consumer<T> = (x: ____) => void;
Cevap
// T'yi parametre olarak tüketen fonksiyon
type Consumer<T> = (x: T) => void;

Açıklama: Tüketici, aldığı türü parametre pozisyonunda kullanır; `(x: T) => void` tanımı kontravaryans sağlar. `any` varyans kontrolünü devre dışı bırakır.

3 Varyans kavramları

Kavram Anlamı
Kovaryans üretilen değerin alt tür ilişkisi aktarılır
Kontravaryans tüketilen parametrenin ilişkisi tersine döner
Bivaryans hem kovaryans hem kontravaryans kabul edilir
strictFunctionTypes fonksiyon parametrelerini katı yapar

İleri seviye bölümündeki tüm dersler