ProgramlamaTypeScript mimarı

TypeScript'te operator overloading nasıl gerçekleştirilir, bu doğrudan mümkün mü ve dolaylı yolları nedir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

TypeScript, doğrudan operator overloading'i desteklememektedir — bu davranışı yalnızca fonksiyonlar/sınıflar düzeyinde taklit etmek mümkündür, çünkü JavaScript (ve TypeScript'in JS'ye transpirasyonu) kullanıcı tanımlı türler için standart operatörlerin (+, *, - vb.) davranışını değiştirme olanağını sağlamaz.

Konuya dair tarih: C++ veya C# gibi dillerde nesnelerle çalışırken operatörler için kendine özgü davranışlar belirleme imkanı vardır. Ancak TypeScript (ve JavaScript) böyle bir olanağa sahip değildir, çünkü sonuçta çıkan kod, operatörlerin iç türlerle sıkı bir şekilde bağlı olduğu sıradan bir JS kodudur.

Sorun: Soyut varlıkları (örn. vektörler, matrisler, para birimleri vb.) içeren sınıflar geliştirirken, bu varlıklarla operatörler aracılığıyla rahatça çalışmak gerekebilir. TypeScript'te bunu yerel olarak yapmayı sağlayacak bir sözdizimi yoktur.

Çözüm: Operator overloading'i taklit etmek için açıklayıcı isimlerle metotlar (add, mul, sub) oluşturulur, bazen statik metotlar veya yardımcı fonksiyonlar kullanılır. Ayrıca, türlerin açık bir şekilde dönüştürülmesi için valueOf metodu uygulanabilir, ancak bu, tüm operatörlerin tam olarak yüklenmesi için yeterli değildir ve bu çözüm yalnızca bazı operatörler için temel değerler üzerinde çalışır.

Kod örneği:

class Vector2D { constructor(public x: number, public y: number) {} add(v: Vector2D): Vector2D { return new Vector2D(this.x + v.x, this.y + v.y); } } const v1 = new Vector2D(1, 2); const v2 = new Vector2D(3, 4); const result = v1.add(v2); // Vector2D { x: 4, y: 6 }

Anahtar özellikler:

  • Yerleşik operator overloading desteği yok
  • Açıkça tanımlanmış metotlar (add, sub) kullanılır
  • valueOf metodu yalnızca bazı operatörler için, sınırlı bir şekilde çalışır

Aldatıcı sorular.

valueOf/toString tanımlanırsa, + operatör yüklemesi sınıflar için çalışır mı?

Hayır. valueOf yalnızca bir türün temel bir değere dönüştürülmesi aşamasında etkilidir. + operatörleri (örneğin, string birleştirme veya sayıları toplama) bu beklenmedik sonuçlar verebilir, diğer operatörler ayarlanamaz.

class Currency { constructor(private amount: number) {} valueOf() { return this.amount; } } const c1 = new Currency(10); const c2 = new Currency(5); console.log(c1 + c2); // 15, ama bu bir Currency objesi değil!

TypeScript'te operatorleri yüklemek için Proxy kullanmak mümkün mü?

Hayır. Proxy, özelliklere ve metotlara erişimi yakalamayı sağlar, ancak operatörlerin (+, * vb.) kullanımını değil, yalnızca yerleşik türlerle çalışır.

Bir arayüz veya type içinde bir operatörü "yüklemek" mümkün mü?

Hayır. Arayüzlerde yalnızca metotlar ve fonksiyon imzaları tanımlanabilir, operatör yüklemeleri C#'da olduğu gibi tanımlanamaz (operator+)

Tipik hatalar ve anti-patranlar

  • operator+(a, b) gibi fonksiyonlar yazmaya çalışmak ve bunların çalışacağını ummak
  • İş mantığı uygulamak için valueOf kullanmak (valueOf'un şablon metodu, kodu belirsizleştirir)
  • Bir sınıfta temel değeri değiştirmek ve sınıfın mantığını birleştirmek

Gerçek hayattan bir örnek

Negatif durum

Geliştirici, sınıf Currency'ye valueOf ekleyerek sayısal bir temsil almak ve matematiksel işlemleri doğrudan gerçekleştirmek istedi (currency1 + currency2). Sonuç olarak anlam kayboldu; toplamanın sonucu basit bir sayıydı, bir para birimi objesi değil, dönen değerin türünü takip etmek imkansız hale geldi.

Artılar:

  • Kısa ifadeler (currency1 + currency2)
  • Temel işlemlerde daha az kod

Eksiler:

  • Tür güvenliği kayboluyor
  • Dönen nesneyi kontrol etme imkansızlığı
  • Karmaşık hata ayıklama

Pozitif durum

Vector sınıfında yeni bir Vector döndüren bir add metodu uygulanmıştır. Kesin bir türlendirme vardır, belirsizlik yoktur.

Artılar:

  • Katı türlendirme
  • İşlemlerin güvenliği
  • Bakım kolaylığı

Eksiler:

  • v1 + v2 yazmanın imkansızlığı, yalnızca v1.add(v2) yazmak
  • operator overloading olan dillerden biraz daha karmaşık bir yazım