2011-07-17 8 views
5

Mam dwie klasy: Guid i UserGuid. Guid ma jeden argument typu. UserGuid jest szczególnym przypadkiem Guid'a, który reprezentuje encję (User), dla której nie ma klasy, więc zaimplementowałem ją jako Guid [Any].Ogólna supezyjność obiektu towarzyszącego w Scali

Mam kilka metod stosowania Guid, które chciałbym podzielić między dwa typy, więc umieszczam je w superklasie (GuidFactory). Ponieważ jednak Guid jest sparametryzowany, muszę sparametryzować cechę GuidFactory, w przeciwnym razie wynikowy Guid będzie sparametryzowany jako Guid [_].

W efekcie mój towarzysz obiekt UserGuid nie kompiluje, twierdząc, że:

error: com.wixpress.framework.scala.UserGuid takes no type parameters, expected: one object UserGuid extends GuidFactory[UserGuid]

Czy jest jakiś sposób mogę podzielić apply metod między GUID i UserGuid czy muszę powielać je lub użyj odlew?

Kod następuje.

abstract class TypeSafeId[I, T](val id: I) extends Serializable  
class Guid[T](override val id: String) extends TypeSafeId[String, T](id) 
class UserGuid(override val id: String) extends Guid[Any](id) 

trait GuidFactory[I[A] <: Guid[A]] { 
    def apply[T](id: String): I[T] 
    def apply[T](id: UUID): I[T] = apply(id.toString) 
    def apply[T](ms: Long, ls: Long): I[T] = apply(new UUID(ms, ls)) 
    def apply[T](bytes: Array[Byte]):I[T] = apply(UUID.nameUUIDFromBytes(bytes)) 
    def random[T] = apply[T](UUID.randomUUID()) 
} 

object Guid extends GuidFactory[Guid] { 
    override def apply[T](id: String) = new Guid[T](id) 
} 

object UserGuid extends GuidFactory[UserGuid] { 
    override def apply(id: String) = new UserGuid(id) 
} 
+0

W 'apply' metody' GuidFactory' nie wydaje się, aby sens dla 'UserGuid'. Na przykład. co powinno "UserGuid.apply [String] (" ")' return? Zgodnie z 'GuidFactory', miałby on typ' UserGuid [String] ', który nie istnieje. –

+0

, który jest dokładnie problem, chcę, aby był UserGuid.apply ("1234"), a nie UserGuid.apply [String] ("1234"); co powinno mieć sens, ponieważ GuidFactory przyjmuje parametr typu I, który jest podtypem Guida i ma jeden parametr, a UserGuid jest podtypem Guida i dostarcza jeden parametr jako Dowolny ... –

Odpowiedz

2

To jest najlepsze, co mogę zasugerować:

import java.util.UUID 
abstract class TypeSafeId[I, T](val id: I) extends Serializable 
class Guid[T](override val id: String) extends TypeSafeId[String, T](id) 
class UserGuid(override val id: String) extends Guid[Any](id) 

trait GuidFactory[G] { 
    def apply(id: String): G 
    def apply(id: UUID): G = apply(id.toString) 
    def apply(ms: Long, ls: Long): G = apply(new UUID(ms, ls)) 
    def apply(bytes: Array[Byte]): G = apply(UUID.nameUUIDFromBytes(bytes)) 
    def random = apply(UUID.randomUUID()) 
} 

object Guid { 
    def apply[T] = new GuidFactory[Guid[T]] { 
    def apply(id: String) = new Guid[T](id) 
    } 
} 

object UserGuid extends GuidFactory[UserGuid] { 
    override def apply(id: String) = new UserGuid(id) 
} 

val guid1 = Guid[String]("123") 
1

Czy to rozwiąże problem ?:

package guid 
import java.util.UUID 

abstract class TypeSafeId[I, T](val id: I) extends Serializable  
class Guid[T](override val id: String) extends TypeSafeId[String, T](id) 
class UserGuid(override val id: String) extends Guid[Nothing](id) 

trait GuidFactory[I[A] <: Guid[A]] { 
    def apply[T](id: String): I[T] 
    def apply[T](id: UUID): I[T] = apply(id.toString) 
    def apply[T](ms: Long, ls: Long): I[T] = apply(new UUID(ms, ls)) 
    def apply[T](bytes: Array[Byte]):I[T] = apply(UUID.nameUUIDFromBytes(bytes)) 
    def random[T] = apply[T](UUID.randomUUID()) 
} 

object Guid extends GuidFactory[Guid] { 
    override def apply[T](id: String) = new Guid[T](id) 
} 

//object UserGuid extends GuidFactory[UserGuid] { 
// override def apply(id: String) = new UserGuid(id) 
//} 

object Test { 
    val guid1 = Guid[String]("123") 
    val guid2 = Guid.random[List[Any]] 
    val userguid = Guid("123") 
    val userguid2 = Guid.random 
} 
+0

Nie, ponieważ UserGuid musi być różni się od Guida, w przeciwnym razie pomija cały punkt klasy bezpiecznej dla typu ... –