我无法理解为什么编译器允许当前代码。
我使用幻像类型来保护对方法的访问。只有在特定的“状态”下才允许调用方法。
在大多数情况下,这个不变量确实是经过编译验证的。然而,有时编译器只是忽略了幻像类型所施加的约束。这感觉像是一个重大错误。我不明白什么?
我试图尽可能地简化问题。我的用例更复杂:
class Door[State <: DoorState] private {
def doorKey: Int = 1
def open[Phatom >: State <: Closed.type]: Door[Open.type] = new Door[Open.type]
def close[Phatom >: State <: Open.type]: Door[Closed.type] = new Door[Closed.type]
}
object Door {
def applyOpenDoor: Door[Open.type] = new Door[Open.type]
def applyClosedDoor: Door[Closed.type] = new Door[Closed.type]
}
sealed trait DoorState
case object Closed extends DoorState
case object Open extends DoorState
然后
val aClosedDoor = Door.applyClosedDoor
val res1 = aClosedDoor.close // does not compile. Good!
val res2 = aClosedDoor.open.close.close // does not compile. Good!
println(aClosedDoor.open.close.close) // does not compile. Good!
println(aClosedDoor.open.close.close.doorKey) // does not compile. Good!
aClosedDoor.open.close.close.doorKey == 1 // does not compile. Good!
println(aClosedDoor.open.close.close.doorKey == 1) // compiles! WTF?
正如您在上面看到的,客户端可以关闭一扇关闭的门。在我的库中,相应的行为是抛出运行时异常。(我确信异常得到了很好的保护并且无法访问)
我只能为返回布尔值的表达式复制此问题,并且当这是函数的参数时(在示例中,println
)
我不是在寻找替代解决方案,而是在寻找关于如何发生这种情况的解释?你不同意这是一个相当大的缺陷吗?或者,也许我错过了什么?
Scala version: 2.13.5
编辑
在讨论了gitter之后,我打开了错误请求@https ://github.com/scala/bug
问题似乎没有出现在 scala 3 中。