Scala derleyicisi neden mühürsüz sınıflar / özellikler için kalıp eşleştirme uyarısı veremiyor?


10

Bir kullanırsanız un mühürlü traitveya abstract classScala ve sonra kullanım desen eşleştirme, acaba mevcuttur bu özellik / sınıfın ne mümkün uygulamalar bu özel PatternMatch derlenmesi sırasında derleyici bilmiyor? Yani, eğer olursa, o kadar olsa bile desen maç uyarıları veremedim trait/ abstract classo tipleri hangi bildiği için kapalı değil verebilir tüm olası bağımlılıkları / ithalat kontrol ederek, kullanılabilir?

Eğer varsa Option[A]ve ben sadece için eşleşen desen var Some[A]ama değil için None, derleyici şikayet edecek, çünkü Optionmühürlü.

Derleyici bunu bilemez / çözemezse, neden yapamaz? Ve eğer derleyici (teorik olarak) bunu yapabilirse, Scala'da kullanılmamasının nedenleri nelerdir? Bu tür davranışları destekleyen başka diller var mı?


Ne istediğini belli değil. Eşleşme ifadesi tüm olası girişleri kapsamıyorsa, derleyicinin bir uyarı vermesini ister misiniz? Belki bir örnek sorunuzu daha açık hale getirebilir.
kdgregory

2
Herhangi biri yeni bir alt sınıf getirebilirse, desen eşleşmesi hiçbir zaman kapsamlı olamaz. Örneğin bazı soyut sınıf üretmek Fooalt sınıfları ile A, Bve C, ve desen maçların hepsi sadece bu üç maç. DDesen eşleşmelerini patlatacak yeni bir alt sınıf eklememi hiçbir şey engellemiyor .
Doval

@kdgregory Evet, anladın. Daha açık hale getirmek için bir örnek ekledim.
valenterry

3
Tüm ithalatları kontrol etmek, olası tüm alt sınıfları keşfetmek için yeterli değildir. Başka bir alt sınıf, daha sonra çalışma zamanı sırasında yüklenecek ayrı bir sınıf dosyasında bildirilebilir java.lang.ClassLoader.
amon

Yanıtlar:


17

Bir sınıfın tüm alt sınıflarını hesaplamaya Sınıf Hiyerarşi Analizi denir ve dinamik kod yüklemesi olan bir dilde statik CHA yapmak Durdurma Sorunu'nu çözmeye eşdeğerdir.

Ayrıca, Scala'nın amaçlarından biri bağımsız modüllerin ayrı olarak derlenmesi ve konuşlandırılmasıdır, bu nedenle derleyici bir sınıfın başka bir modülde alt sınıfta olup olmadığını bilemez, çünkü asla birden fazla modüle bakmaz. (Sonuçta, bir modül sisteminizde mevcut olmadan başka bir modülün arayüzüne karşı derleyebilirsiniz!) Bu yüzden sealedtüm alt sınıfların aynı derleme biriminde tanımlanmasını gerektirir.

JVM'lerin C ++ derleyicileriyle bu kadar olumlu rekabet etmesinin nedenlerinden biri de budur: C ++ derleyicileri genellikle statik derleyicilerdir, bu nedenle genel olarak bir yöntemin geçersiz olup olmadığını anlayamazlar ve bu nedenle satır içi yapamazlar. JVM'ler OTOH, tipik olarak dinamik derleyicilerdir, bir yöntemin geçersiz olup olmadığını anlamak için CHA yapmaları gerekmez, çalışma zamanında Sınıf Hiyerarşisine bakabilirler. Ve programın yürütülmesinin sonraki bir noktasında, daha önce orada olmayan yeni bir alt sınıf gelirse bile, büyük bir anlaşma yok, sadece kod parçasını satır içi olmadan derleyin.

Not: bunların hepsi sadece Scala için geçerlidir. JVM'nin hiçbir fikri yoktur sealed, bu yüzden başka bir JVM dilinden sealedsınıfları alt sınıflara ayırmak mümkündür , çünkü bunu başka bir dile iletmenin bir yolu yoktur. Mülkiyet kaydedilir açıklama, ancak diğer dilde derleyiciler açıkçası dikkate bu ek açıklamaları yapmayız.sealedScalaSig


3

Olabilir (en azından derleme zamanında bilinen bütün sınıflar için), sadece pahalı yapılabilir. Artımlı derlemeyi tamamen yok edersiniz, çünkü bir kalıp eşleşmesi içeren her şeyin, başka bir dosya her değiştiğinde etkili bir şekilde yeniden derlenmesi gerekir.

Ve ne satın alıyorsunuz? Yeni bir türetilmiş sınıf eklendiğinde sık sık değiştirilmesi gereken kalıp eşleşmeleri yazmak için bir kod kokusu. Bu açık / kapalı prensibinin ihlalidir . Kalıtım yöntemini doğru kullanın ve bu tür kalıp eşleşmeleri yazmanıza gerek kalmaz. Ve evet, açık / kapalı prensibi sınıf temelli kalıtım olmadan fonksiyonel diller için de geçerlidir. Aslında, yazım sınıfları, çoklu yöntemler ve yalnızca düz üst düzey işlevler gibi özellikler arasında, işlevsel diller modifikasyon olmadan uzantıyı çok daha kolay hale getirir.


1
It can be done (at least for all classes known at compile time), it's just expensive.Ancak program% 100 bağımsız değilse (örn. Harici .jardosyalara bağlıdır ), s'den birinden derlendikten sonra yeni bir alt sınıfa gizlice giremez misiniz jar? Böylece derleyici size "Kalıp eşleşmeleriniz artık çok kapsamlı, ancak bağımlılıklarınızdan herhangi biri değişirse bu durum değişebilir" diyebilirdi.
Doval

Dolayısıyla feragat. Uygulamada, harici veya başka bir bağımlılık üzerinde kapsamlı bir eşleşmeye ihtiyaç duyacak kadar sıkı bir şekilde bağlanmış olsaydınız, yine de yeniden derlemek istersiniz.
Karl Bielefeldt

@Doval Daha sonra bir tür temsilci seçmeli ve çağrılan sınıfın ne yapacağına karar vermesine ve kontrolü tersine çevirmesine izin vermelisiniz. OOP bunun için kastedildi. Bunu istemiyorsanız, o zaman mevcut sorununuz var.
Kızak

@ArtB Kontrolün delegasyonunun veya ters çevrilmesinin bununla ne ilgisi olduğunu göremiyorum.
Doval

Dışarıdan ekleyebilen kişilerle çalışmasını istiyorsanız, sınıfı arayın ve mantığı bu sınıflara taşıyın.
Kızak
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.