Scala 基于类型的无形状Id生成器
我想实现一个基于类型的id生成器,我可以这样调用它:Scala 基于类型的无形状Id生成器,scala,shapeless,hlist,Scala,Shapeless,Hlist,我想实现一个基于类型的id生成器,我可以这样调用它: val nextPersonId = idGen.id[Person] 我希望IdGen成为一种特质(如果可能): trait-IdGen[L好的,这是一个基于字符串的版本,它可能在许多角落的情况下存在bug,并且要求实现者以提供隐式类型标签的形式生成样板文件: import shapeless._ import scala.collection.mutable import scala.reflect.runtime.universe.
val nextPersonId = idGen.id[Person]
我希望IdGen成为一种特质(如果可能):
trait-IdGen[L好的,这是一个基于字符串的版本,它可能在许多角落的情况下存在bug,并且要求实现者以提供隐式类型标签的形式生成样板文件:
import shapeless._
import scala.collection.mutable
import scala.reflect.runtime.universe._
trait IdGen[L <: HList] {
implicit val ltag: TypeTag[L]
private val idGens = mutable.Map(typeTag[L].toString.split("""::\[""").toList.tail.map(_.split(""",shapeless""")(0) -> 0L): _*)
def id[T: TypeTag] = {
val t = typeOf[T].toString
val id = idGens(t)
idGens(t) = id + 1L
id
}
}
看到更好的实现将非常有趣。我不确定您在这里要做什么。是否希望编译器为您增加ID?是否希望编译器仅强制使用某个ID生成器?如果您希望在运行时生成ID,则前者是不可能的,因为ID的数量太多生成的可能会根据控制流发生变化。根据您试图执行的操作,控制流可能不需要无形状。@badcook我将使用对L的typeTag的toString解析来写一个答案,希望它会变得更清晰:)
import shapeless._
import scala.collection.mutable
import scala.reflect.runtime.universe._
trait IdGen[L <: HList] {
implicit val ltag: TypeTag[L]
private val idGens = mutable.Map(typeTag[L].toString.split("""::\[""").toList.tail.map(_.split(""",shapeless""")(0) -> 0L): _*)
def id[T: TypeTag] = {
val t = typeOf[T].toString
val id = idGens(t)
idGens(t) = id + 1L
id
}
}
import java.util.NoSuchElementException
import org.junit.{Assert, Test}
import shapeless._
import reflect.runtime.universe._
class Person
class Booking
class Charge
class MyDao(implicit val ltag: TypeTag[Person :: Booking :: HNil]) extends IdGen[Person :: Booking :: HNil]
class Testy {
val myDao = new MyDao
@Test(expected = classOf[NoSuchElementException])
def test {
Assert.assertEquals(0L, myDao.id[Person])
Assert.assertEquals(1L, myDao.id[Person])
Assert.assertEquals(0L, myDao.id[Booking])
myDao.id[Charge]
}
}