2011-07-17 63 views
5

我有兩個類,Guid和UserGuid。 Guid有一個類型的論點。 UserGuid是一個Guid的特例,它代表一個沒有類的實體(用戶),所以我將它作爲一個Guid [Any]實現。Scala中的通用伴侶對象超類型

我有幾個適用於Guid的方法,我想在兩種類型之間共享,所以我把它們放在一個超類(GuidFactory)中。然而,由於Guid是參數化的,我必須參數化GuidFactory特徵,否則生成的Guid將被參數化爲Guid [_]。

其結果是,我的同伴對象UserGuid不能編譯,抱怨說:

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

有什麼辦法,我可以分享應用GUID和UserGuid或我要重複,或用鑄造方法之間?

代碼如下。

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

的''中似乎GuidFactory'不作apply'方法感覺UserGuid。例如。 UserGuid.apply [String](「」)'應該返回什麼?根據'GuidFactory',它將具有類型'UserGuid [String]',它不存在。 –

+0

這正是問題所在,我希望它是UserGuid.apply(「1234」),而不是UserGuid.apply [String](「1234」);這應該是有道理的,因爲GuidFactory接受類型I的參數,這是Guid的子類型並且具有一個參數,並且UserGuid是Guid的子類型並提供一個參數爲Any ... –

回答

2

這是最好的,我可以建議:

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

這會解決你的問題?:

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

不,因爲UserGuid需要與Guid不同,否則它會忽略類型安全的id類的整個點... –