2011-06-10 25 views
1

我發現自己是一個非常有趣的事實。例如我已經寫道:結構型

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型已經不存在的「出」 什麼發生在此,如何工作? 謝謝。

+3

此錯誤代碼不正確。至少,'Set [out]'和'Tuple ['a',0]'是不正確的,因爲正在使用[]'而不是'()'。另外,這與結構類型沒有任何關係 - 如果你使用'val a:AnyRef = new Fon;它會抱怨所有相同的。 – 2011-06-10 20:53:36

+0

也許我不明白的東西,但你可以做以下事情:'type A = {def out:String}; class AA {def def:String = out2; def out2 =「out2」; val a:A =新的AA; a.out' - 結果'String = out2' – dvigal 2011-06-11 05:04:40

+0

@lisasha你的例子中缺少'}'。我在'out2'的定義之後假設。無論如何,這是一個問題還是一個陳述?如果有問題,那麼是的。如果一個聲明,那麼我不明白你想要做的點。你期望它失敗嗎?如果是這樣,爲什麼? – 2011-06-11 18:45:51

回答

5

由於您如何定義A類型,因此沒有這樣的方法,如A.out。因此,當您嘗試在A類型的對象上調用名爲out的方法時,編譯器會正確告訴您沒有此類方法。

順便說一下,這與結構分型無關 - 如果您已使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 
+0

事實上,我們可以擁有的所有幽默都是正式定義的類型和類或單例,一般來說 - 將表示它的實現對象。可能是這樣,不是很好......我想知道編譯器如何以及爲什麼允許這種方法 - 在方法tr中使用「out」方法,並推斷出類Fon是類型A. – dvigal 2011-06-10 16:54:20

1

基本上它允許你使用一個對象(Fon),因爲它是另一個(A)授予他們具有相同的功能。

由於out不是A的功能,編譯器不會讓您繼續。

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,而具體的實例是鳳

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)是一個具體的實現。