Scala 为什么可以';我不会写‘列表’,但我会写';I';
在下面的代码中,我可以将Scala 为什么可以';我不会写‘列表’,但我会写';I';,scala,Scala,在下面的代码中,我可以将id定义为List[I] abstract trait Repository[I,M] { def getOneById(id: List[I]): Option[M] } 但是为什么我不能在下面的代码中将id定义为List[I] abstract trait Repository[List[I],M] { def getOneById(id: List[I]): Option[M] //I get compiler error - cannot r
id
定义为List[I]
abstract trait Repository[I,M] {
def getOneById(id: List[I]): Option[M]
}
但是为什么我不能在下面的代码中将id
定义为List[I]
abstract trait Repository[List[I],M] {
def getOneById(id: List[I]): Option[M] //I get compiler error - cannot resolve I. Why?
}
应该有用。基本上,在trait定义中,您只列出typearguments,而在id的右侧,您需要指定一个类型
List
是一个类型构造函数,在您的案例中接受一个参数I
编辑:请参见中的注释链
abstract trait Repository[List[I],M] {
def getOneById(id: List[I]): Option[M]
}
List
是与类型scala.Predef.List
无关的类型参数的名称。而[List[I],M]
中的I
仅意味着该类型参数本身是一个接受单个类型参数的泛型类型。此名称I
仅在列表[I]
中可见
因此,这可以同样改写为
abstract trait Repository[F[_],M] {
def getOneById(id: F[I]): Option[M]
}
这应该可以清楚地说明为什么这个不能编译。对不起,我知道第一个可以。我试图理解为什么第二个没有,因为
List
也是一种类型,不是吗?List
是一种类型构造函数List[Int]
是一种类型。但这很挑剔。它不起作用的原因是你可以想到。。。trait Repository[I,M]
类似于def Repository
,但用于类型[I,M]
只是说Repository
接受两个类型参数I
和M
,因此表达式List[I]
在该位置没有多大意义。在作为id
函数参数的位置上,它是有意义的,因为id
必须是作为I
传递到Repository
的任何内容的列表。“表达式列表[I]在该位置上没有多大意义”它对编译器来说是完全有意义的,问题是它的意义不是我们想要的。好的,我必须修改。在吉特,我不得不问比我聪明的人。基本上,您绑定了一个名为list的类型参数*->*和它的类型参数I(与scala list无关)。然而,我是无效的,但可以这样使用trait Repository[F[I]谢谢Alexey.Undersood。
abstract trait Repository[F[_],M] {
def getOneById(id: F[I]): Option[M]
}