Scala 类型边界 =:=
Scala type bounds =:=
编译时:
implicit class Container[T](val value:T) extends AnyVal{
def addInt(x:Int)(implicit ev:T=:=Int) = value+x
}
这抱怨类型不匹配,预期 T
,实际 Int
,就好像它忽略了类型绑定。
implicit class Container[T](val value:T=>Int) extends AnyVal{
def addInt(x:Int)(implicit ev:T=:=Int) = value(x)
}
为什么?
哦,问题可能出在函数的反方差上。这现在有效:
implicit class Container[T](val value:T=>Int) extends AnyVal{
def addInt(x:Int)(implicit ev:Int<:<T) = value(x)
}
实际上,您的类型约束是倒退的。 T =:= Int
提供了 T
是 Int
的隐含证据,但 不完全 Int
是 T
。如果您查看声明 if =:=
,您会发现它只有一种方式:
sealed abstract class =:=[From, To] extends (From => To) with Serializable
您的第一个示例有效,因为 value
是 T
,并且约束是 T =:= Int
,它隐式地将 T
转换为 Int
。但是对于第二个例子,我们需要喂一个T
到value: T => Int
,所以我们需要另一个方向
这个有效:
implicit class Container[T](val value: T => Int) extends AnyVal {
def addInt(x: Int)(implicit ev: Int =:= T) = value(x)
}
你的第二个例子使用 Int <:< T
的原因也是因为 <:<
提供了从 Int => T
.
的隐式转换
编译时:
implicit class Container[T](val value:T) extends AnyVal{
def addInt(x:Int)(implicit ev:T=:=Int) = value+x
}
这抱怨类型不匹配,预期 T
,实际 Int
,就好像它忽略了类型绑定。
implicit class Container[T](val value:T=>Int) extends AnyVal{
def addInt(x:Int)(implicit ev:T=:=Int) = value(x)
}
为什么?
哦,问题可能出在函数的反方差上。这现在有效:
implicit class Container[T](val value:T=>Int) extends AnyVal{
def addInt(x:Int)(implicit ev:Int<:<T) = value(x)
}
实际上,您的类型约束是倒退的。 T =:= Int
提供了 T
是 Int
的隐含证据,但 不完全 Int
是 T
。如果您查看声明 if =:=
,您会发现它只有一种方式:
sealed abstract class =:=[From, To] extends (From => To) with Serializable
您的第一个示例有效,因为 value
是 T
,并且约束是 T =:= Int
,它隐式地将 T
转换为 Int
。但是对于第二个例子,我们需要喂一个T
到value: T => Int
,所以我们需要另一个方向
这个有效:
implicit class Container[T](val value: T => Int) extends AnyVal {
def addInt(x: Int)(implicit ev: Int =:= T) = value(x)
}
你的第二个例子使用 Int <:< T
的原因也是因为 <:<
提供了从 Int => T
.