ver*_*tti 8 types scala class map
我的游戏有
class Enemy
Run Code Online (Sandbox Code Playgroud)
谁可以改变我的人工智能/功能
trait Moving
trait VerticalMover extends Moving
trait RandomMover extends Moving
Run Code Online (Sandbox Code Playgroud)
等等.现在我需要根据特征获取预加载的东西.我想要做的是有一个Map接受所有特征,这些特征扩展了Moving作为键,然后是一些EnemyContainer作为预先加载特征相关内容的值.
但是我如何定义这样的Map以及如何格式化我的.get()以通过某个Enemy的实例来获取容器.就像是:
val myEnemy = new Enemy with RandomMover
val myDetails:EnemyContainer = enemyDetailsStore.get(myEnemy.getClass)
Run Code Online (Sandbox Code Playgroud)
Did*_*ont 11
也许你可以包装Map [Manifest,Any],确保值对应于清单键.
可能的草图.首先是一个小帮手
class Typed[A](value: A)(implicit val key: Manifest[A]) {
def toPair: (Manifest[_], Any) = (key, value)
}
object Typed {
implicit def toTyped[A: Manifest](a: A) = new Typed(a)
implicit def toTypable[A](a: A) = new {
def typedAs[T >: A : Manifest] = new Typed[T](a)(manifest[T])
}
}
Run Code Online (Sandbox Code Playgroud)
包装器本身(不是地图)
class TypedMap private(val inner: Map[Manifest[_], Any]) {
def +[A](t: Typed[A]) = new TypedMap(inner + t.toPair)
def +[A : Manifest](a: A) = new TypedMap(inner + (manifest[A] -> a))
def -[A : Manifest]() = new TypedMap(inner - manifest[A])
def apply[A : Manifest]: A = inner(manifest[A]).asInstanceOf[A]
def get[A : Manifest]: Option[A] = inner.get(manifest[A]).map(_.asInstanceOf[A])
override def toString = inner.toString
override def equals(other: Any) = other match {
case that: TypedMap => this.inner == that.inner
case _ => false
}
override def hashCode = inner.hashCode
}
object TypedMap {
val empty = new TypedMap(Map())
def apply(items: Typed[_]*) = new TypedMap(Map(items.map(_.toPair) : _*))
}
Run Code Online (Sandbox Code Playgroud)
有了这个,你可以做到
import Typed._
val repository = TypedMap("foo", 12, "bar".typedAs[Any])
Run Code Online (Sandbox Code Playgroud)
repository:TypedMap = Map(java.lang.String - > foo,Int - > 12,Any - > bar)
你用它检索元素
repository[String] // returns "foo"
repository.get[Any] // returns Some("bar")
Run Code Online (Sandbox Code Playgroud)
我认为私有构造函数应该确保_ asInstanceOf是安全的.inner可能会被公开,因为它是不可改变的.这样,丰富的界面Map将可用,但遗憾的是,不会创建另一个TypedMap.
好吧,我假设您的敌人详细信息存储类型Map[Class[_ <: Moving], EnemyDetails].我怀疑像这样的东西:
//gives a Map[Class[_ <: Moving], EnemyDetails] for all matching keys
enemyDetailsStore.filterKeys(_ isInstance myEnemy)
Run Code Online (Sandbox Code Playgroud)
要么:
//Iterable[EnemyDetails]
enemyDetailsStore collect { case (c, d) if c isInstance myEnemy => d }
Run Code Online (Sandbox Code Playgroud)
甚至只是:
//Option[EnemyDetails]
enemyDetailsStore collectFirst { case (c, d) if c isInstance myEnemy => d }
Run Code Online (Sandbox Code Playgroud)
会为你做的.这段代码唯一的"问题"是它是O(N),因为它需要遍历映射,而不是简单的查找,它可以是O(1),或O(log N)
| 归档时间: |
|
| 查看次数: |
6454 次 |
| 最近记录: |