4

我是 Scala 和 funcprog 的新手。

我有一段代码(你们中的一些人可能认识它):

    trait SwingApi {

      type ValueChanged <: Event

      val ValueChanged: {
        def unapply(x: Event): Option[TextField]
      }
      ...
     }

我不明白 val ValueChanged: {...} 是什么。

从这篇文章中我了解到

type ValueChanged <: Event

val ValueChanged: {
            def unapply(x: Event): Option[TextField]
          }

是两个不相关的东西,因为它们位于不同的命名空间等中,而 ValueChanged类型是Event的抽象子类型。

好,然后我尝试使用 Scala 工作表:

type myString <: String

 val myString: {
    def myfunc(x: String): String
  }

它告诉我一个错误“只有类可以有声明和未定义的成员”......这不是一个类似的结构吗?

最后,问题是:

  • 代码的val ValueChanged部分中的ValueChanged是什么?

  • 它真的与ValueChanged <: Event 类型无关吗

  • 这个语法是什么意思:

    val myVal:{def func{x:T}:T}

? 这里的值的名称、类型和实际值是什么?

谢谢!

4

1 回答 1

7
{def unapply(x: Event): Option[TextField]}

是一个结构类型,这意味着它接受任何具有 unapply 方法的对象,其中事件作为参数,Option[TextField] 作为返回值。它最常用于类似于 Duck 类型,例如:

def foo(canQuack: {def quack(): Unit}) = {
  canQuack.quack()
}
object Bar{
   def quack(): Unit = print("quack")
}
object Baz{
   def bark(): Unit = print("bark")
}
foo(Bar) //works
foo(Baz) //compile error

所以

type StructuralType = {def unapply(x: Event): Option[TextField]}
val ValueChanged: StructuralType

声明一个名为 ValueChanged 且类型为 StructuralType 的 val,但不分配任何值,这仅在 trait 或抽象类中才有意义,这就是您的示例不起作用的原因。

所以呢

trait SwingApi {
...
  val ValueChanged: {
    def unapply(x: Event): Option[TextField]
  }
...
}

意味着特征 SwingApi 只能应用于具有名为 ValueChanged 的​​ val 的对象/类,并且分配给它的任何值都有一个 unapply 方法

trait SwingApi {
  val ValueChanged: {
    def unapply(x: Event): Option[TextField]
  }
}
//works:
object Bar extends SwingApi{
  val ValueChanged = {
    def unapply(x: Event): Option[TextField] = None
  }
}
//compile error:
object Baz extends SwingApi{
  val ValueChanged = {
    //wrong name
    def foo(x: Event): Option[TextField] = None
  }
}
//compile error:
object Baz2 extends SwingApi{
  val ValueChanged = {
    //wrong input/output type
    def unapply(): Unit = {}
  }
}

所有代码未经测试

于 2015-05-17T07:17:01.220 回答