2011-04-14 17 views
6

Desen eşleştirmesinde bir tür silme işleminde çalışıyorum. Varsayarsak:Model eşleştirme türünde bir silme işleminin etrafında gezinme

import java.io._ 

trait Serializer[V] { 
    def save(os: OutputStream, v: V): Unit 
    def load(in: InputStream): V 
} 

trait HasSerializer[V] { def serializer: Serializer[V] } 

Nasıl bu uyarı olmadan ve asInstanceOf olmadan derlemeye alabilirsiniz:

def test[V](os: OutputStream, v: V): Unit = v match { 
    case hs: HasSerializer[V] => hs.serializer.save(os, v) 
    case _     => ??? 
} 

? test bir haritadan bir değerle çağrılır ve bir sınıf bildirimi sağlama aracı yoktur.

Herhangi bir fantezi çıkarıcı hile olabilir mi?

cevap

2

Eh soru yanlış ön şart tür var - biz bir serileştiriciden ve deserializer içine ayrı Serializer alabilir. Açıkçası, bir örneğim V, kullanım durumum serileştirme ve bu bir dönüş türü olarak V gerektirmez. Böylece

trait Serializer { def save(os: OutputStream): Unit } 

yeterli olacaktır, ve her tür o karıştırabilirsiniz Ve yapın:.

def testSer[V](os: OutputStream, v: V): Unit = v match { 
    case s: Serializer => s.save(os) 
    case _ => new ObjectOutputStream(os).writeObject(v) 
} 

Ve serisini kaldırma için, bir Ref[V] inşası ile birlikte deserializer sağlayabilir veya dayanacağını belirtti Ya ObjectInputStream üzerinden sınıf araması.

+0

Peki" her tür onu karıştırabilir " doğru, elbette. Sorun hala mevcut tipler için geçerli, diyelim ki ('Alex' örneğinde olduğu gibi) 'Int' için bir serializer sağlamak istiyoruz ... –

4

Serializer'ı bunun yerine soyut bir sınıf haline getirebilirseniz, bunu bir Manifest'i örtük bir yapıcı parametresi olarak verebilir ve bunu beton sınıfını yapım aşamasında almak için kullanın, daha sonra dinamik tip çekleri için kullanın. (Sadece farkında olarak)

import java.io._ 

abstract class Serializer[V: Manifest] { 
    def save(os: OutputStream, v: V): Unit 
    def load(in: InputStream): V 
    val clazz = manifest[V].erasure 
} 

val ser = new Serializer[Int] { 
    def save(os: OutputStream, v: Int) { 
    os.write((v.toString + "\n").getBytes) 
    } 

    def load(in: InputStream) = { 
    val line = new BufferedReader(new InputStreamReader(in)).readLine() 
    line.toInt 
    } 
} 

ser.clazz // java.lang.Class[_] = int 
+0

Ancak V örneğinin bir Serializer sağlayıp sağlamadığını nasıl öğrenebilirim? Sonunda "V" 'e basmak zorunda kalmadan, testi "test" yönteminde nasıl uygulayacağımı hala görmüyorum? –

+0

Tür sınıflarını kullanamazsınız, çünkü değerler temel olarak yazılmamışsa, bazı kayıt defteri ve arama mekanizmalarına sahip olmaktan kaçınabilirsiniz. Yine de başka bir yaklaşım görmekten mutlu olurum! –

+0

Kayıt defterine ihtiyacım yok, çünkü HasSerializer [_] 'ile karşılaştırabilir ve daha sonra HasSerializer [V]' a güvenli bir şekilde yayınlayabilirim, ancak tam olarak yapmak istemediğim şey budur. 'V', farklı ara yüzler arasında birkaç kez geçiyor, 'ClassManifest'in etrafından geçiyor, sadece bir seçenek yok, Scala' dürüstlük 'kavramıyla dürüstçe berbat ... –

İlgili konular