2017-08-24 69 views
2

以下特點區別聲明2個功能:f1和f2斯卡拉,協變和邊界:在功能

trait Test[+T] { 
    def f1[U >: T](a: U): Boolean 
    def f2[U](a: U): Boolean 
    } 

他們是一樣的嗎?如果不是,有什麼區別?

+0

好了,你可以通過任何類型的對象,以這兩種功能 - 見[這個問題](https://stackoverflow.com/q/37334674/6231376)的說明。 – TeWu

+0

謝謝@TeWu – den123

回答

1

我認爲就行爲而言它們是相同的。兩種功能都需要針對任何類型實施。但是類型與向編譯器提供更多信息以幫助您防止錯誤等一樣多,而且我可以想到一些可能比另一個更可取的陌生角落案例。例如:

class Foo 
class Bar extends Foo 

object BarChecker extends Test[Foo] { 
    def f1[U >: Foo](u: U): Boolean = { 
    if (u.isInstanceOf[Bar]) { 
     true 
    } else { 
     throw new RuntimeException("fail!") 
    } 
    } 
    def f2[U](u: U): Boolean = { 
    if (u.isInstanceOf[Bar]) { 
     true 
    } else { 
     throw new RuntimeException("fail!") 
    } 
    } 
} 

val x = BarChecker.f1[Foo](_) // can't do BarChecker.f1[Bar](_) 
x(new Bar) // true 
x(new Foo) // runtime exception 
val y = BarChecker.f2[Bar](_) 
y(new Bar) // true 
y(new Foo) // compile error 

當然你可以用解決這個問題:

val x: Bar => Boolean = BarChecker.f1[Foo](_) 

但我的觀點是不同類型的簽名可以有哪些錯誤,使用的時候有可能或有可能取得不同的效果。

+1

T.f1 [Foo](_)'中的T是什麼? – TeWu

+0

哎呀,BarChecker最初名爲T,但我(不正確/不完整)將其更改爲更具描述性。將編輯。 –

1

在執行方面,他們是一樣的。兩者都帶有U型參數,並返回布爾類型的結果。但是,就類型參數而言,它們不是。方法f1有一個lower bound類型參數但是方法f2不。

那麼,這是什麼意思? 在方法f2的情況下,您可以提供任何類型參數。在方法f1的情況下,您只能提供類型參數,其類型爲TsuperTypeT。例如:

class Foo1(name:String) 
class Foo2(name:String) extends Foo1(name) 
class Foo3(name:String) extends Foo2(name) 

class Test[+T] { 
    def f1[U >: T](a: U): Boolean = true 
    def f2[U](a: U): Boolean = true 
    } 

val obj: Test[Foo2] = new Test[Foo2] 

val foo1: Foo1 = new Foo1("1") 
val foo2: Foo2 = new Foo2("2") 
val foo3: Foo3 = new Foo3("3") 

//F2 execute on any type you provide. 
testInstance.f2[Foo1](foo1) 
testInstance.f2[Foo2](foo2) 
testInstance.f2[Foo3](foo3) 

testInstance.f1[Foo2](foo2)  //Foo2 is equal to type T. 
testInstance.f1[Foo1](foo1)  //Foo1 is supertype of T - Foo2. 
testInstance.f1[Foo3](foo3)  //Does not compile, because Foo3 is not superType of T - Foo2. 

事實上,在Scala中,在Co-variance註釋[+ T]的情況下,必須定義一個下界。以下將失敗:

class Test[+T] { 
    def f1(a: T): Boolean = true  //This will fail. 
    def f2[U](a: U): Boolean = true 
    }