Scala访问字段

时间:2016-02-10 21:03:02

标签: scala

我最近开始学习scala并偶然发现了一个试图“打印”细胞的问题:

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 paint(radius: Int) = {
    println("Printing")

    if (radius == 0)
      isPainted = true
    else {
      isPainted = true
      top.isPainted = true
      bottom.isPainted = true
      left.isPainted = true
      right.isPainted = true

为什么这些相邻的细胞

      top.left.paint(r - 1)
      top.right.paint(r - 1)
      bottom.left.paint(r - 1)
      bottom.right.paint(r - 1)

无法访问?

    }
  }

如何访问顶部,底部,左侧,右侧单元格?

编辑:

谢谢你的回答。 一个附加问题:

如何检查单元格x周围的所有单元格是否都设置为true? 不幸的是,我的尝试不起作用。

def isMiddleCell()={
    if(List(top, bottom, left, right).forall(_.Some))
      true
    else
      false
  }

1 个答案:

答案 0 :(得分:2)

这样做

  bottom.isPainted = true

您实际上需要修改Option

中的值
  bottom.foreach(_.isPainted = true)

要访问嵌套Option,您应该使用flatMap,所以

top.left.paint(r - 1)

应该是

top.flatMap(_.left).foreach(_.paint(r - 1))

你基本上想要产生副作用,如果存在值则执行一些代码。为此,idomatic解决方案是foreach,它正是这样做的。

要浏览其邻居为Option的单元格,flatMap是最简单的解决方案。 top的类型为Option[Cell]。如果您想获取其中的值并从中提取left,您可以考虑map

top.map(_.left)

此表达式的类型为Option[Option[Cell]],这就是flatMap在这里有用的原因,它会展平嵌套的选项并为您提供[Option[Cell]],其中包含您的顶级邻居的左邻居单元格是否存在。现在,有了这个,您可以像前面的例子一样foreach

要解释您发布此代码的评论:

top.getOrElse("No top neighbour").isPainted = true

这可能不起作用,因为如果它存在,它将为您提供Cell,否则它将为您提供String,它为您提供类型的表达式(我认为){{1} (所以最常见的超类型)没有名为Serializable的字段。当您使用isPainted时,通常需要将对象的表达式放在getOrElse内。但无论如何Option在你的例子中似乎并不是最有用的东西。

修改

要回答后续问题,检查值存在的方法是getOrElse

isDefined

def isMiddleCell = List(top, bottom, left, right).forall(_.isDefined) 是一种类型。 Some语法只是函数的简写,扩展如下:

_