在我的项目中,我使用Seq[Drone]来跟踪世界上的无人机。这是一个功能性项目,所以世界和无人机都是案例类的价值。
在世界的process()方法中,返回一个新的World实例,其中包含该序列的转换版本,并且由于它是无序的,因此不能保证无人机以相同的顺序返回。这是为初步实施而设计的。
但是,现在是实现ID系统的时候了,这样就可以单独地为它们分配操作(例如"d1移动到(4,6)")。这意味着无人机需要以一种保存“订单”的方式存储。
我花了一些时间想出了几种方法,但首先,建立了ID的实际工作方式。
ID行为
Drone类型没有ID --这是一个仅由World给出的概念。备选案文1:纯元组
我的Seq[Drone]将成为Vector[(Int, Drone)]。无人机的引用将从world.drones(n)改为world.drones(n)._2,这有很多原因。ID将由world.drones(n)._1访问。
选项2:类型别名元组
我会将名为D的类型添加到(Int, Drone)中,并将Seq[Drone]更改为Vector[D]。这与选项1有相似的问题,我相信,虽然我没有太多的经验,类型别名。
备选方案3:案例类
我会制作一些类似case class D(id: Int, drone: Drone)的东西,并将Seq[Drone]转换成Vector[D]作为选项2。它的优点是提供了更好的调用(d.id和d.drone,而不是元组元素语法),并且可以几乎完全相同地使用元组(D(1, Drone()) vs (1, Drone()) --这是单个字符的区别)。
因此,我的问题是:选项3在这里是一个合适的解决方案吗?如果是的话,我将来会遇到什么样的问题?(我设想做一些工作来清理电话,但除此之外,什么也没有。)如果没有,我可以探索哪些途径来找到更合适的东西?
发布于 2017-11-01 04:10:01
你的三个选择几乎是一样的。二元组实际上只是一个名为Tuple2的案例类,其中Scala添加了一些语法糖,这样您就可以编写(a, b)而不是Tuple2(a,b)。因此,考虑到这些选项,我会选择选项3,因为有更多的描述性方法名称。事实上,由于这个原因,元组经常被禁止使用。
然而,还有另一种可能性,使用Map[Int, Drone]。这将为您提供您需要的一些功能(包括通过id和唯一性检查快速查找),并在不需要定义自己的新类型的情况下完成相同的任务。
例如,可以将添加无人机定义为:
def addDrone(drones: Map[Int, Drone], newDrone : Drone): Map[Int, Drone] = {
val id = (0 until drones.size).find(!drones.contains(_)).getOrElse(drones.size)
drones + (id -> newDrone)
}释放id就像将其从地图中移除一样简单。
https://stackoverflow.com/questions/47046469
复制相似问题