我最近开始学习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
}
答案 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
语法只是函数的简写,扩展如下:
_