yue*_*ngz 9 scala subtype type-constraints
任何人都可以在下面的代码中解释子类型(<:) 为什么可以这样使用?当我们使用它?谢谢.
trait SwingApi {
type ValueChanged <: Event
val ValueChanged: {
def unapply(x: Event): Option[TextField]
}
type ButtonClicked <: Event
val ButtonClicked: {
def unapply(x: Event): Option[Button]
}
type TextField <: {
def text: String
def subscribe(r: Reaction): Unit
def unsubscribe(r: Reaction): Unit
}
type Button <: {
def subscribe(r: Reaction): Unit
def unsubscribe(r: Reaction): Unit
}
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ral 11
我知道那个代码!:)
因此<:,为了以防万一,请确保您了解其含义.A <: B意味着A必须是一个子类型B,或者换句话说,每个实例都A将是一个实例B(但反之亦然).
例如,我们知道每个java类都是<: Object(例如String <: Object).
接下来,为什么type ValueChanged <: Event.这通常在蛋糕模式中找到,但我会跳过对此的解释(课程确实提到了蛋糕模式,并提供了链接iirc).
这意味着对于任何扩展SwingApi的类型,类型ValueChanged必须是子类型Event.这使得可以Event在任何使用该类型声明的方法上调用方法ValueChanged,而无需事先知道究竟是什么类型.
这类似于下一次使用:
type TextField <: {
def text: String
def subscribe(r: Reaction): Unit
def unsubscribe(r: Reaction): Unit
}
Run Code Online (Sandbox Code Playgroud)
我们在这里声明TextField应该有那些方法,所以当我们得到类型的东西TextField(比如ValueChanged提取器返回)时,我们可以在它上面调用这些方法.我们可以写这样的代码:
trait MyStuff extends SwingApi {
def subscribeTo(event: ValueChanged) = event match {
case ValueChanged(textField) => textField.subscribe(myReaction)
}
def myReaction: Reaction
}
Run Code Online (Sandbox Code Playgroud)
在这一点上,既没有SwingApi,也不MyStuff知道类型会怎样被用于ValueChanged或TextField和,然而,他们可以在正常代码中使用它们.
关于type声明经常被忽略的一个有趣的事实是它们可以被类覆盖.也就是说,我可以这样写:
class SwingImpl extends SwingApi {
class TextField {
def text: String = ???
def subscribe(r: Reaction): Unit = ???
def unsubscribe(r: Reaction): Unit = ???
}
// etc
}
Run Code Online (Sandbox Code Playgroud)
最后,您可能想知道这是什么用途.我举一个例子.当然,您希望生产代码在屏幕上显示图形元素等等,或许,您可以编写一个单独的类,在Web服务器中实现它.但是,我认为课程利用它,您可以编写实现它的类,而不是显示这些组件的类,而是作为测试类,验证与这些组件的交互是否正确完成.
也就是说,您可以SwingImpl扩展SwingApi并在桌面上显示内容,并且SwingTest还可以扩展SwingApi,但只需让人们验证正在执行的操作.
| 归档时间: |
|
| 查看次数: |
6096 次 |
| 最近记录: |