2011-07-17 26 views
5

Tengo dos clases, Guid y UserGuid. Guid tiene un argumento de tipo. UserGuid es un caso especial de Guid que representa una entidad (Usuario) para la que no hay clase, así que lo he implementado como Guid [Cualquiera].Supertipo genérico de objeto complementario en Scala

Tengo varios métodos de aplicación para Guid que me gustaría compartir entre los dos tipos, así que los puse en una superclase (GuidFactory). Sin embargo, como Guid está parametrizado, tengo que parametrizar el rasgo GuidFactory; de lo contrario, el Guid resultante se parametrizará como Guid [_].

Como resultado, mi compañero objeto UserGuid no compila, quejándose de que:

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

¿Hay alguna manera de poder compartir el GUID y métodos entre UserGuid o tengo que duplicar o utilizar la fundición se aplican?

El código a continuación.

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

Los métodos de '' apply' en GuidFactory' no parecen hacer sentido para 'UserGuid'. P.ej. ¿Qué debe devolver 'UserGuid.apply [String] (" ")'? De acuerdo con 'GuidFactory', tendría el tipo' UserGuid [String] ', que no existe. –

+0

que es exactamente el problema, quiero que sea UserGuid.apply ("1234"), no UserGuid.apply [String] ("1234"); lo cual debería tener sentido, ya que GuidFactory toma un parámetro de tipo I, que es un subtipo de Guid y tiene un parámetro, y UserGuid es un subtipo de Guid y proporciona un parámetro como Cualquiera ... –

Respuesta

2

Esto es lo mejor que puedo sugerir:

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

Sería esto resuelve el problema ?:

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

No, ya que UserGuid necesita ser distinto de Guid, de lo contrario, se pierde el objetivo de una clase de identificación de tipo seguro ... –

Cuestiones relacionadas