2012-08-07 23 views
11

Tür parametresi yerine soyut bir tür kullanmak istiyorum. Benim jenerik sınıflar Yapıcıdascala sınıfı kurucular ve soyut tipler

, ben jenerik tipte bir parametre olsun istiyorum, ama kod derleme değil:

class SomeOtherClass(val s: S){ 
    type S 
} 

scala derleyici hatası "bulunamadı: tip S" olduğu

Ben soyut bir tip yerine bir tür parametresini kullanırsanız

, o zaman çalışır: bir yapmak istiyorsanız

class SomeClass[T](val t: T){ 
    //... 
} 

mu scala kuvvet beni, soyut bir tip yerine bir tür parametresi kullanmak kurucudaki jenerik parametre?

Bunu yapmanın başka bir yolu var mı?

cevap

3

Bu durumda jenerik tür parametrelerini kullanmak zorunda kalıyorsunuz. Sınıfın dışındaki türü bildirerek çalışabilir, ancak daha sonra sarıcıyı ve sonra nesneyi başlatmanız gerekir ve çok çabuk çirkinleşir.

trait FooDef { 
    type T 
    class Foo(val x: T) 
} 
val ifd = new FooDef { type T = Int } 
val ifoo = new ifd.Foo(5) 
val sfd = new FooDef { type T = String } 
val sfoo = new sfd.Foo("hi") 
def intFoos(f: fd.Foo forSome { val fd: FooDef {type T = Int} }) = f.x + 1 
0

Derleyici, orada hangi tür kullanması gerektiğini nasıl bilmelidir? Ya türünü doğrudan belirtmeniz gerekir, bu çok anlamlı olmaz veya jenerik kullanmaz. Çalıştırmanın bir yolu var, ama size yardımcı olacağını düşünmüyorum.

class SomeClass(s: SomeClass#S) { 
    type S 
} 

Ancak SomeClass # S tanımlanmadığı gibi, bunun bir örneği yoktur.

+0

Yeteri kadar komik, bu yeni 'newClass (5.asInstanceOf [SomeClass # S]) {type S = Int}' örneklerini oluşturmanıza izin verecektir. Hiçbir güvenlik olmadığına dikkat ediniz, S hala dökümde tanımsızdır. – Kaito

+0

Temel olarak doğru yapmak için diğer iki cevaba bakmam gerekiyor mu? –

+0

@AntKutschera evet. – Nicolas

0

Belki de böyle bir şey ister misin? Bu şekilde, her biri Foo s için farklı bir değere sahip AbstractFooFactory çoklu örneklere sahip olabilirsiniz.

trait AbstractFooFactory { 
    type S 
    def makeFoo(s:S):Foo 
    class Foo(val s:S) {} 
} 

object StringFooFactory extends AbstractFooFactory { 
    override type S = String 
    override def makeFoo(s:String) = new Foo(s) 
} 

val b = StringFooFactory.makeFoo("bar") 
val s:String = b.s 
1

Soyut tür belirtilmemişse, sınıfınızın soyut olması gerekir. Yani hiç parametreye ihtiyacınız yok. soyut tip eşdeğer olacaktır:

kullanım yerinde sonra
abstract class SomeOtherClass { 
    type S 
    val s: S 
} 

: parametre olmadan

val x = new SomeOtherClass { 
    type S = String 
    val s = "abc" 
} 

, burada soyut sınıf bir özellik eşdeğerdir. Bir özelliği kullanmaktan daha iyidir, çünkü daha az kısıtlayıcıdır (yalnızca bir ana sınıfı genişletebilirsiniz).

İlgili konular