[英]Scala nested optionals chaining in object
我最近开始学习scala广告,尝试使自己熟悉一个简单的演示程序。
我想检查一个单元是否所有邻居。 在Java中,可以通过以下方式完成:
public boolean hasFullNeighbourhood() {
if (top != null && bottom != null && left != null && right != null &&
top.getLeft() != null && top.getRight()
!= null && bottom.getLeft() != null
&& bottom.getRight() != null)
return true;
else
return false;
}
单元格定义为:
class Cell(
val x: Int,
val y: Int,
val left: Option[Cell],
val right: Option[Cell],
val top: Option[Cell],
val bottom: Option[Cell],
var isPainted: Boolean)
如何在Scala中定义整个社区? 我开始喜欢:
def hasFullNeighbourhood(r:Int): Boolean={
if(r ==0)
return true
if (List(top, bottom, left, right).forall(_.isDefined))
return true
else
return false
}
但是,如何访问其余部分( x.top, x.bottom, x.left, x.right
)并检查它们是否不为null /可选对我来说还是不清楚的。
我认为像top.foreach()
是可能的-但如果添加到自选列表中,如果这回不会失败none
。
我将类重新定义为案例类:
case class Cell(
val x: Int,
val y: Int,
val left: Option[Cell],
val right: Option[Cell],
val top: Option[Cell],
val bottom: Option[Cell],
var isPainted: Boolean)
这是否意味着
def isMiddleCell()={
if(List(top, bottom, left, right).forall(_.isDefined))
true
else
false
}
可以重写为:
def isMiddleCell(c: Cell) = c match {
case Cell(_, _, Some(top), Some(bottom), Some(left), Some(right), _) => true
case _ => false
}
这似乎还是有点奇怪,因为我想检查给定的单元格(如果它是一个中间单元格Cell.isMiddleCell(givenCell)
,而没有指定Cell.isMiddleCell(givenCell)
而是givenCell.isMiddleCell()
但是要实施
def hasFullNeughbourhood(radius:Int)
正确地我不需要更多声明,因为我不仅要检查直接邻居。 对我来说,仍然不清楚如何访问这些。 在Java中,我将使用x.getLeft()
并递归地使用x.getLeft().hasFullNeighbourhood(r - 1)
。
def hasFullNeighbourhood(c: Cell) = c match {
case Cell(_, _, Some(top), Some(bottom), Some(left), Some(right), _) => true
case _ => false
}
我正确理解isMiddleCell
应该实现为:
def isMiddleCell() = {
this match {
case Cell(_, _, Some(top), Some(bottom), Some(left), Some(right), _) => true
case _ => false
}
在Scala中,通常有一些好的方法可以对容器的内容执行操作:通过模式匹配进行映射或分解。 如果您不习惯使用功能编程,那么在使用Option的情况下,模式匹配更为直观。
为了使模式匹配更容易,您应该将单元格类定义为案例类。 这为您提供了模式匹配,而无需您自己实施任何操作,并且将使下一个示例更好。 对于简单的数据模型类,案例类始终是一个好主意。
def hasFullNeighbourhood(c: Cell) = c match {
case Cell(_,_,Some(top),Some(bottom),Some(left),Some(right),_) => true
case _ => false
我将变量名留在顶部,底部等等,因为您可以使用它们来对这些值进行处理。 但是由于您不需要使用此方法,因此我也可以编写_。 如果您还不知道模式匹配,请继续阅读。 没有它的Scala不好玩。
另一种方法是使用地图。 仅当您想对“容器”中的内容进行一些计算并将其放回相同类型的容器中时,这才很有趣:
val possiblyANumber1 = Some(5)
val possiblyANumber2 = Some(5)
val possiblyANumber3 = possiblyANumber1.flatMap(x => possiblyANumber2.map(y => x + y))
在此示例中,这使您可以对两个数字进行加法,而无需知道它们是否实际存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.