结构类型

时间:2011-06-10 16:23:31

标签: scala

我发现自我是一个非常有趣的事实。例如,我写道:

type A = { val st: Set[Any]
           val start: Set[Any]
           val Sigma : Set[Char]
           def tr(f: (Tuple2[Any, Any])=>Boolean): Set[Any]
             }
class Fon {
          val st: Set[Any]
          val start: Set[Any]
          val Sigma : Set[Char]
          def tr(f: (Tuple2[Any, Any])=>Boolean): Set[Any] = Set(out)
          def out: String = "is just example"
}
val a: A = new Fon
a.tr(f(Tuple2('a',0)))

但如果我会尝试调用a.out - 我得到一个错误,A类型不存在'out' 发生了什么,这是如何工作的? 感谢。

3 个答案:

答案 0 :(得分:5)

由于您已定义A.out类型,因此没有A这样的方法。因此,当您尝试在类型为out的对象上调用名为A的方法时,编译器会正确地告诉您不存在此类方法。

顺便说一下,这与结构类型无关 - 如果你使A成为一个特征并且Fon扩展了它,那么你会遇到完全相同的问题。而且,这就是静态类型系统的工作原理 - 编译器无法保证您的代码是类型安全的,因此它不会编译它。

如果您想调用out方法,则需要通过Fon变量引用该对象:

val a: Fon = new Fon
println(a.out) // works fine, since a is guaranteed to be a Fon and thus have the method

答案 1 :(得分:1)

基本上,它允许您使用一个对象(Fon),因为它是另一个(A),因为它们具有相同的功能。

由于out不是A的功能,编译器不允许您继续。

答案 2 :(得分:0)

类型A是抽象类或特征。它的成员变量和方法都是抽象的。

type A = {val st: Set[Any]
    val start: Set[Any]
    val Sigma: Set[Char]
    def tr(f: (Tuple2[Any, Any]) => Boolean): Set[Any]
  }

Fon是一个具体的类,只需实现类型A所有抽象成员。

class Fon {
    val st: Set[Any] = null
    val start: Set[Any] = null
    val Sigma: Set[Char] = null

    def tr(f: (Tuple2[Any, Any]) => Boolean): Set[Any] = Set(out)

    def out: String = "is just example"
  }

因此,您可以定义变量,类型为A,具体实例为Fon

val a: A = new Fon
  println(a.tr(_ => false)) // Set(is just example)

额外:     f: (Tuple2[Any, Any]) => Boolean是一个抽象的高阶函数作为参数, 所以,如果你想调用方法tr,a.tr(f(Tuple2('a',0)))调用模式不能解析符号f。 f: (Tuple2[Any, Any]) => Boolean只获取一个参数,并返回布尔值。 所以(_ => false)是一个具体的工具。