[英]Scala type bounds
What is wrong with the code below? 下面的代码有什么问题? I'm getting the following complaint from the compiler on the indicated line: type arguments [Asset] do not conform to trait Worker's type parameter bounds [T <: br.Doable]
我在指定的行上从编译器收到以下抱怨:类型参数[Asset]不符合trait Worker的类型参数bounds [T <:br.Doable]
How is this so? 这是怎么回事? Worker expects a subtype of Doable, and asset extends Doable.
Worker期望子类型为Doable,资产扩展为Doable。
trait Doable
trait Worker[T<:Doable] {
def hey():String
}
case class Asset() extends Doable
case class Hey[Asset] extends Worker[Asset] { // << error here
def hey() = "You!"
}
When you declare case class Hey[Asset]
, you bind a new type variable Asset
, you do not refer to case class Asset() extends Doable
(you are shadowing the Asset
type variable). 当你声明
case class Hey[Asset]
,你绑定一个新的类型变量Asset
,你没有引用case class Asset() extends Doable
(你正在隐藏Asset
类型变量)。 Your code is equivalent to : 您的代码相当于:
case class Hey[A] extends Worker[A] {
...
}
which obviously won't work. 这显然是行不通的。
The problem is you have confused yourself by using the same value, Asset
, to refer to a case class and a type parameter. 问题是你通过使用相同的值
Asset
来引用案例类和类型参数而使自己感到困惑。
You probably intend to do something like this: 你可能打算做这样的事情:
case class Hey[T](str: String) extends Worker[Asset] {
def hey() = "You!"
}
Though it is beside the point, note that I added a parameter to Hey
because case classes without parameters have been deprecated. 虽然它不是重点,但请注意我向
Hey
添加了一个参数,因为不推荐使用不带参数的case类。
This has been asked a lot of times, and I think that the confusion can easily go away if you see the analogy between type parameters and constructor parameters, thinking about them just as different kinds of constructor parameters: type-level and value-level. 这已被问过很多次了,我认为如果你看到类型参数和构造函数参数之间的类比,将它们视为不同类型的构造函数参数:类型级别和值级别,那么混淆很容易消失。
Disclaimer Of course, this is only an analogy and it will break at a lot of different levels and there are a lot of corner cases as with anything Scala;
免责声明当然,这只是一个类比,它会在很多不同的层面上破裂,并且有许多角落案例与Scala一样; but my point here is that it can be useful
但我的观点是它可能有用
At the type level, you can think of <:
as a the equivalent of :
at the value level: 在类型级别,您可以将
<:
视为等价于:
在值级别:
class TypeParamsVsVals {
type X
type X1 <: X
class Buh[T <: X]
class Oh[T1 <: X1] extends Buh[T1]
// wait for Scala 3
// class Oh[T1 <: X1] extends Buh[T = T1]
type x
type x1 <: x
class buh(val t: x)
class oh(val t1: x1) extends buh(t = t1)
}
What I think is the main source of confusion is that at the type level there's no kind distinction between the two sides of <:
, and to make things worse you can write T
without any (no pun intended) bound, while you cannot do the same at the value level: 我认为混淆的主要原因是,在类型层面上,
<:
两面之间没有任何区别,并且为了使事情变得更糟,你可以在没有任何(没有双关语意图)约束的情况下编写T
,而你不能这样做价值水平相同:
class NoBounds[T]
// same as
class AltNoBounds[T <: Any]
// you cannot write
// class noBounds(val t)
class noBounds(val t: Any)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.