Scala对象中的嵌套选项链接

Scala对象中的嵌套选项链接,scala,pattern-matching,Scala,Pattern Matching,我最近开始学习scala广告,试图熟悉一个简单的演示程序 我想检查一个牢房是否有所有的邻居。在java中,这可以通过以下方式实现: public boolean hasFullNeighbourhood() { if (top != null && bottom != null && left != null && right != null && top.getLeft() != null &am

我最近开始学习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
)并检查它们是否为空/可选

我认为类似于
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)
,而是指定
givenCell.isMiddleCell()

然而,实施

def hasFullNeughbourhood(radius:Int)
正确地说,我不需要更多的语句,因为我不想只检查近邻。对我来说,目前还不清楚如何访问这些。在java中,我将使用
x.getLeft()
和递归地
x.getLeft().hasfullNeighborhood(r-1)

编辑2 我是否正确理解
isMiddleCell
应实现为:

  def isMiddleCell() = {
    this match {
      case Cell(_, _, Some(top), Some(bottom), Some(left), Some(right), _) => true
      case _ => false
    }

在Scala中对容器内容执行操作通常有很多好方法:通过模式匹配进行映射或分解。如果您不习惯函数式编程,则在选项中,模式匹配更直观

为了使模式匹配更容易,您应该将单元类定义为case类。这使您无需自己实现任何东西就可以进行模式匹配,并将使下一个示例变得更好。对于简单的数据模型类,Case类总是一个好主意

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))

在本例中,这允许您对两个数字进行加法,而不知道它们是否确实存在。

感谢您的精彩解释。请你再解释一下
它们是用来代替
x,y的吗?请看编辑。我仍然需要一些解释:)是的,基本上你可以嵌套这些模式来描述你想要的结构。当你想访问某个东西的内容时,你可以在那里放一个变量名,如果你不关心内容,你可以放一个。变量名可以是任意名称,它们不必与参数名或类似的名称相对应。
val possiblyANumber1 = Some(5)
val possiblyANumber2 = Some(5)
val possiblyANumber3 = possiblyANumber1.flatMap(x => possiblyANumber2.map(y => x + y))