简体   繁体   English

Scala 中的通用伴侣 object 超类型

[英]Generic companion object supertype in Scala

I have two classes, Guid and UserGuid.我有两个类,Guid 和 UserGuid。 Guid has one type argument. Guid 有一个类型参数。 UserGuid is a special case of Guid that represent an entity (User) for which there is no class, so I've implemented it as a Guid[Any]. UserGuid 是 Guid 的一个特例,它代表一个没有 class 的实体(用户),所以我将它实现为 Guid[Any]。

I have several apply methods for Guid which I would like to share between the two types, so I put them in a superclass (GuidFactory).我有几个适用于 Guid 的方法,我想在这两种类型之间共享,所以我把它们放在一个超类(GuidFactory)中。 However, since Guid is parameterized I have to parameterize the GuidFactory trait, otherwise the resulting Guid will be parameterized as Guid[_].但是,由于 Guid 是参数化的,我必须参数化 GuidFactory 特征,否则生成的 Guid 将被参数化为 Guid[_]。

As a result, my companion object UserGuid does not compile, complaining that:结果,我的同伴 object UserGuid 没有编译,抱怨说:

error: com.wixpress.framework.scala.UserGuid takes no type parameters, expected: one object UserGuid extends GuidFactory[UserGuid]错误:com.wixpress.framework.scala.UserGuid 没有类型参数,预期:一个 object UserGuid 扩展 GuidFactory[UserGuid]

Is there any way I can share the apply methods between Guid and UserGuid or must I duplicate them or use casting?有什么方法可以在 Guid 和 UserGuid 之间共享应用方法,还是必须复制它们或使用强制转换?

Code follows.代码如下。

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)
}

This is the best I can suggest:这是我能建议的最好的:

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")

Would this solve your 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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM