繁体   English   中英

Scala嵌套对象中的可选链

[英]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
  }

EDIT2

我正确理解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.

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