Scala'da 'type' anahtar kelimesinin ne yaptığını anlama


144

Scala için yeniyim ve typeanahtar kelime hakkında pek bir şey bulamadım . Aşağıdaki ifadenin ne anlama geldiğini anlamaya çalışıyorum:

type FunctorType = (LocalDate, HolidayCalendar, Int, Boolean) => LocalDate

FunctorType bir tür takma addır, ama ne anlama geliyor?

Yanıtlar:


148

Evet, tür takma adı FunctorType yalnızca

(LocalDate, HolidayCalendar, Int, Boolean) => LocalDate

Tür takma adları genellikle kodun geri kalanını basit tutmak için kullanılır: artık yazabilirsiniz

def doSomeThing(f: FunctorType)

derleyici tarafından yorumlanacaktır.

def doSomeThing(f: (LocalDate, HolidayCalendar, Int, Boolean) => LocalDate)

Bu, örneğin diğer türlerde tanımlanan tuples veya işlevler gibi birçok özel türün tanımlanmasını önlemeye yardımcı olur.

İçin birçok başka ilginç kullanım durumları da vardır type, örneğin anlatıldığı gibi, bu bölümde ait Scala Programlama .


198

Aslında typeScala'daki anahtar kelime, karmaşık bir türü daha kısa bir isme takmaktan çok daha fazlasını yapabilir. Tip üyelerini tanıtır .

Bildiğiniz gibi, bir sınıfın saha üyeleri ve yöntem üyeleri olabilir. Scala ayrıca bir sınıfın tür üyesi olmasını da sağlar.

Sizin özel durumunuz type, aslında, daha kısa kod yazmanıza izin veren bir takma ad sunmaktır. Tür denetimi gerçekleştirildiğinde, tür sistemi diğer adı gerçek türle değiştirir.

Ama bunun gibi bir şey de olabilir

trait Base {
  type T

  def method: T
}

class Implementation extends Base {
  type T = Int

  def method: T = 42
}

Bir sınıfın diğer üyeleri gibi, yazım üyeleri de soyut olabilir (yalnızca değerlerinin gerçekte ne olduğunu belirtmezsiniz) ve uygulamalarda geçersiz kılınabilir.

Tür üyeleri, jeneriklerle uygulayabileceğiniz şeylerin çoğu soyut tür üyelere çevrilebildiğinden, çift jenerik olarak görülebilir.

Yani evet, takma ad için kullanılabilirler, ancak bunları sadece bununla sınırlamayın, çünkü Scala'nın tip sisteminin güçlü bir özelliği.

Daha fazla ayrıntı için lütfen bu mükemmel cevaba bakın:

Scala: Soyut Türler ve Jenerikler


44
Sınıf içinde yazı kullanmanın bir takma ad yerine bir yazım üyesi oluşturduğunu hatırlamak önemlidir. Bu nedenle, yalnızca bir tür takma adına ihtiyacınız varsa, bunu tamamlayıcı nesnede tanımlayın.
Rüdiger Klaehn

9

Roland Ewald'ın cevabını beğendim, çünkü tür takma adı çok basit bir kullanım durumu ile tanımladı ve daha ayrıntılı olarak çok güzel bir öğretici tanıttı. Ancak, bu üyeler adlı yazıya başka bir kullanım durumu eklendiğinden, çok sevdiğim en pratik kullanım durumundan bahsetmek istiyorum: (bu bölüm buradan alınır) :)

Özet Türü:

type T

Yukarıdaki T, kullanılacak olan bu tipin henüz bilinmediğini ve somut alt sınıfa bağlı olarak tanımlanacağını söylüyor. Programlama kavramlarını her zaman anlamanın en iyi yolu bir örnek sunmaktır: Aşağıdaki senaryolara sahip olduğunuzu varsayalım:

Tip Soyutlama Olmadan

Burada derleme hatası alırsınız, çünkü inek ve kaplan sınıflarındaki yemek yöntemi, Animal sınıfındaki eat yöntemini geçersiz kılmaz, çünkü parametre türleri farklıdır. Sınıfta Çimen, Sınıfta Et vs Kaplanda Sınıfta Gıda Süper sınıf olan ve tüm alt sınıfların uyması gerekir.

Şimdi soyutlamaya geri dönelim, aşağıdaki şema ile ve basitçe bir tür soyutlama ekleyerek, alt sınıfın kendisine göre girişin türünü tanımlayabilirsiniz.

Soyut Tip ile

Şimdi aşağıdaki kodlara bakın:

  val cow1: Cow = new Cow
  val cow2: Cow = new Cow

  cow1 eat new cow1.SuitableFood
  cow2 eat new cow1.SuitableFood

  val tiger: Tiger = new Tiger
  cow1 eat new tiger.SuitableFood // Compiler error

Derleyici mutlu ve tasarımımızı geliştiriyoruz. İnekimizi inekle besleyebiliriz.UygunYemek ve derleyici, Tiger'a uygun yiyeceklerle ineği beslememizi engeller. Peki ya inek1 UygunGıda ve inek2 SuitabeFood türü arasında fark yaratmak istersek. Başka bir deyişle, bazı senaryolarda, türe ulaştığımız yolun (elbette nesne aracılığıyla) temelde olması çok yararlı olacaktır. Skala'daki gelişmiş özellikler sayesinde şunlar mümkündür:

Yola bağlı türler: Scala nesneleri üye olarak türlere sahip olabilir. Türün anlamı, ona erişmek için kullandığınız yola bağlıdır. Yol, bir nesneye (sınıfın bir örneği olarak) referansla belirlenir. Bu senaryoyu uygulamak için İnek içindeki Çim sınıfını tanımlamanız gerekir, yani İnek dış sınıf ve Çim iç sınıftır. Yapı şöyle olacak:

  class Cow extends Animal {
    class Grass extends Food
    type SuitableFood = Grass
    override def eat(food: this.SuitableFood): Unit = {}
  }

  class Tiger extends Animal {
    class Meat extends Food
    type SuitableFood = Meat
    override def eat(food: this.SuitableFood): Unit = {}
  }

Şimdi bu kodu derlemeye çalışırsanız:

  1. val cow1: Cow = new Cow
  2. val cow2: Cow = new Cow

  3. cow1 eat new cow1.SuitableFood
  4. cow2 eat new cow1.SuitableFood // compilation error

4. satırda bir hata göreceksiniz çünkü Çim artık bir İnek iç sınıfıdır, bu nedenle bir Çim örneği oluşturmak için bir inek nesnesine ihtiyacımız vardır ve bu inek nesnesi yolu belirler. Böylece 2 inek nesnesi 2 farklı yol ortaya çıkarır. Bu senaryoda, cow2 sadece bunun için yaratılmış yiyecekleri yemek istiyor. Yani:

cow2 eat new cow2.SuitableFood

Şimdi herkes mutlu :-)


5

Diğer ad olarak "tür" ifadesinin nasıl kullanılacağını görmek için bir örnek:

type Action = () => Unit

Yukarıdaki tanım, Eylem'i boş bir parametre listesi alan ve Birim döndüren yordam türlerinin (yöntemlerin) diğer adı olarak tanımlar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.