Elde etmek istediğim şey,Scala'daki dinamik mixin - mümkün mü?
def dynamix[A, B](a: A): A with B
için düzgün bir uygulamaya sahip olmaktır B nin ne olduğunu bilebilirim, fakat A'nın ne olduğunu bilmiyorum (fakat eğer B kendinden bir tipse, o zaman bazı kısıtlamalar ekleyebilirim) A). Scala derleyici yukarıdaki imzayla mutludur, ancak uygulamanın nasıl görüneceğini henüz anlamadım - eğer mümkün ise.
Aklıma gelen bazı seçenekler:
- Yansıma/dinamik proxy kullanma.
- En basit durum: A, Java düzeyindeki bir arabirimdir + B'yi başlatabilir ve kendi türü yoktur. Sanırım çok zor olmayacaktı (bazı kötü, beklenmedik problemler yaşamadığım sürece):
yeni bir B (b) oluşturmak, ayrıca hem A hem de B'yi uygulayan bir proxy oluşturmak ve hem a hem de b. . - Eğer B örneklenemezse, hala bir alt sınıfı oluşturabilir ve yukarıda açıklandığı gibi yapar. Kendine ait bir türü varsa, muhtemelen burada ve burada bazı delegasyonlara ihtiyacım var, ama yine de işe yarayabilir.
- Peki ya A beton tipi ve bunun için uygun bir arayüz bulamıyorum?
- Daha fazla sorunla karşılaşabilir miyim (örneğin, doğrusallaştırma ile ilgili bir şey veya Java birlikte çalışabilirliğine yardımcı olan özel yapılar)?
- En basit durum: A, Java düzeyindeki bir arabirimdir + B'yi başlatabilir ve kendi türü yoktur. Sanırım çok zor olmayacaktı (bazı kötü, beklenmedik problemler yaşamadığım sürece):
- Bir mixin yerine bir tür sargı kullanarak ve B [A] ile geri dönülürken, b'ye erişilebilir.
Ne yazık ki, bu durumda arayanın yuvalama işleminin nasıl yapıldığını bilmesi gerekecek, bu da karıştırma/sarma işleminin birkaç kez yapıldığında (D [C [B [A]]]) olması gerektiği gibi oldukça rahatsız edici olabilir. Gerekli işlevselliğe erişmek için doğru yuvalama seviyesini bulun, bu yüzden bir çözüm olarak düşünmüyorum. - Derleyici eklentisini uygulama. Onunla sıfır deneyimim var ama bağırsak hislerim önemsiz değil. Bence Kevin Wright'ın autoproxy eklentisi biraz benzer bir hedefe sahip, ama benim problemim için yeterli değil (henüz?).
Çalışabilecek başka fikirleriniz var mı? Hangi yolu önerirsiniz? Ne tür "zorluklar" beklemek?
Ya da unutmam gerekiyor, çünkü mevcut Scala kısıtlamaları ile mümkün değil mi?
Sorunumun ardındaki niyet: İş akışım olduğunu söyle, ama çok katı değil. Bazı adımlar sabit bir düzene sahiptir, ancak diğerleri yoktur, ama sonunda bunların hepsi (ya da daha fazla işlem için gerekli olan) yapılmalıdır.
Biraz daha somut örnek: Bir A'm var, B ve C'yi ekleyebilirim. İlk önce hangisinin yapıldığını umursamıyorum, ama sonunda C ile birlikte bir A'ya ihtiyacım var
Yorum: Groovy hakkında çok fazla bilgim yok ama SO this question kadar patladı ve sanırım En azından kavramsal olarak istediğim kadar ya da çok aynı.
başka bir yaklaşım (canlı eğer yeterince iyice düşünmediğini bilmek): Bir 'Dynamix içinde Wrap [A, B]' (veya Dynamix [A, Dynamix [B, C]] 'yi iç içe geçirin ve istemci kodunu bilişsel olarak boşaltmak için örtüşmeyle açın. Her yuvalama derinliği tanımlanmalıdır (keyfi derinlik yoktur). Dezavantajlı: Kendinden tür kısıtlamaları zorlamıyor ya da türler arası etkileşime kendiliğinden tipler üzerinden izin vermiyor. İyi hile için –
+1, ama yine de en azından bir problemle karşılaşacağım hissine sahibim: Sonunda C veya Dynamix ile bir A'nın B'yi isteyeceğini nasıl belirleyeceğim [A, Dynamix [B, C] ] ama karıştırma emrini umursamıyorum? Dynamix [A, Dynamix [C, B]] ile de mutlu olurum ve bence bu tür bir kısıtlama bulmak çok kolay olmayacaktır (özellikle karıştırılacak birçok özellik var). Yine de, yorumunuzu beğendim, bunun için teşekkürler. –
olası bir kopyası [Dinamik olarak bir özellik karıştırma] (http://stackoverflow.com/questions/10373318/mixing-in-a-trait-dynamically) –