2016-08-14 70 views
2

看着scala.Option[T]来源我发现了下面的隐式参数声明implicit ev: Null <:< A1。尝试它自己A <:<SomeType参数声明

class Test[T](val i: Int){ 
    def test(p: T <:< Option[Int]) = 1 
} 

我发现p看起来像一个Function1。它有apply,andThen等方法。会有什么区别,如果我们写:

class TestMatch[T](val i: Int){ 
    def test(p: T <:< Option[Int]) = //.. 
    def test2(p: T => Option[Int]) = //... 
} 

是否存在的testtest2 singatures之间的一些主要区别?这个例子beahves是这样的:

tm.test2(x => { //fine 
    println(x) 
    Some(x) 
}) 

tm.test(x => { //Compile error 
    println(x) 
    Some(x) 
}) 

我也试过这样:

tm.test(x <:< { //Compile error 
    println(x) 
    Some(x) 
}) 

,但它也不能工作。如何使用test

回答

3

我发现p看起来像一个Function1

<:<被定义为:

sealed abstract class <:<[-From, +To] extends (From => To) with Serializable 

这是派生的Function1[From, To],而这也正是你看到applyandThen来从。 <:<表示通用参数类型约束,其中TOption[Int]的子类型。

通常,<:<旨在被用作类型约束这迫使一个隐式证据是在范围:

A <:< B证人即AB一个亚型的实例。 要求A <:< B类型的隐式参数对广义约束A <: B进行编码。


但不能你解释谁创造这种隐含<:<参数? 它从哪里来的?我猜编译器知道有关<:<,知道 做什么用它

在你的榜样,没有创建隐含的证据。您只需使用<:<作为类型,而不是一个约束。如果你想创建一个,你需要通过声明暗示自己做:

def greaterThan[T](x: T, y: T)(implicit ev: T <:< Ordered[T]): Boolean = x > y 
+0

但是我该如何使用'test'?有没有办法调用它? – stella

+0

但是'<:<'是一个函数。它在'Predef'中被定义为''封闭的抽象类<:<[ - From,+ To] extends Serializable' – Kolmar

+0

@Kolmar仍然不会使'p'成为Function1。它只意味着约束使用中缀表示法,它实际上定义为'<:<[T,Option [Int]]' –

1

他们有不同的语义。在test中,您声明TOption[Int]的子类型。在test2没有这样的约束。

+0

那么如何调用'test2'?我应该通过什么作为参数来编译它? – stella

相关问题