这个Scala示例中的子类型函数是什么?

时间:2016-05-03 03:06:06

标签: scala

我正在通过Martin Odersky的Scala-by-example(2014)阅读。 在页61上,表示从String类型到Int类型的函数被表示 作为特征Function1 [String,Int]的实例。其中Function1定义为:

trait Function1[-A,+B] {def apply(x: A): B}

还有进一步的说法

  

S => T是S'=> T'的子类型,条件是S'是S的子类型,T是T'的子类型。

他使用以下代码示例: val f: (AnyRef => Int) = x => x.hashCode() val g: (String => Int) = f g("abc")

所以这是我的问题。 由于String是AnyRef的子类型,我假设在此示例中f表示g的子类型。那是对的吗? 如果是这样,请解释该决定中的逻辑。

2 个答案:

答案 0 :(得分:3)

如果VU的子类型,则V可以位于U可以的任何位置。

如果您有AnyRef => Int,可以在任何时候使用String => Int吗?是! StringAnyRef,因此您可以将其传入。

因此,AnyRef => IntString => Int的子类型。这种关系(从正常情况下是“向后”)通过说函数在其参数中是逆变来描述。

那说实例 fg不一定有任何关系。但他们的类型确实如此。

答案 1 :(得分:0)

f和g函数,函数具有类型方差,允许类型参数的子类型和超类型:http://docs.scala-lang.org/tutorials/tour/variances.html

在scala终端中运行以下代码将为您提供与运行示例相同的结果。

g被声明为类型(AnyRef => Int)的函数,它将函数实现为:

val f = new Function[AnyRef /*or any supertype*/,Int /*or any subType type*/] {
   def apply(x: AnyRef): Int = x.hashCode()
}

它被定义为一个函数,它接受AnyRef类型的参数,返回Int

然后将

g定义为接收String并返回Int的函数。它设置为等于f,因此它变为:

val g = new Function[String /*Supertype of AnyRef*/, Int] {
    def apply(x: String): Int = x.hashCode()
}

虽然在这种情况下g不是新功能。 g只是f的另一个参考。基本上,g被强制转换为Function[String, Int]

编辑:由于AnyVal是Int的子类型,您也可以这样做:

val gg: (String => AnyVal) = f