Scala类型参数括号
我知道trait Foo[T]意味着Scala类型参数括号,scala,Scala,我知道trait Foo[T]意味着T是一种参数化类型。 但有时我会看到trait Foo[T1,T2],或者trait Foo[T1,T2,R],我在一个类型括号中找不到任何地方描述多个类型的含义,你能告诉我这种情况下的用法吗?根据我的推测,Foo[T1,T2]的意思是,它定义了两个类型参数,它不必取T1并返回T2 当我今天阅读文档时,我再次发现自己对这个问题感到困惑。文件中说: BodyParser[A]基本上是一个迭代者[Array[Byte],A],意思是 它接收字节块(只要web浏览器
T
是一种参数化类型。
但有时我会看到trait Foo[T1,T2]
,或者trait Foo[T1,T2,R]
,我在一个类型括号中找不到任何地方描述多个类型的含义,你能告诉我这种情况下的用法吗?根据我的推测,Foo[T1,T2]的意思是,它定义了两个类型参数,它不必取T1
并返回T2
当我今天阅读文档时,我再次发现自己对这个问题感到困惑。文件中说:
BodyParser[A]基本上是一个迭代者[Array[Byte],A],意思是
它接收字节块(只要web浏览器上传一些字节)
数据),并计算类型a的值作为结果
这个解释听起来像是,类型括号内的第二个类型参数是返回类型
我还记得trait function 2[-T1,-T2,+R]扩展AnyRef
意味着一个函数,它接受T1
和T2
,返回R
他们为什么把返回类型放在括号里?这是否意味着括号中的最后一个参数都是返回类型?或者他们只是为返回类型定义了一个新的类型R?他们的角色有点类似于类中的类型(即多类型参数),因为traits毕竟是类(没有任何构造函数),意味着作为mixin添加到其他类中 以下是具有多个参数的Trait的示例: 考虑一个抽象类表,它实现了从键a类型到值B类型的映射。
该类有一个方法集,用于在表中输入新的键/值对,还有一个方法get,返回与给定键匹配的可选值。
最后,还有一个类似get的应用方法,不同的是,如果未为给定键定义表,它将返回给定的默认值。这个类的实现如下 下面是Table类的一个具体实现 这里有一个特性,它阻止并发访问它的get和set操作 父类 请注意,
SynchronizedTable
不会将参数传递给它的超类Table
,
即使表
定义了一个形式参数。还要注意,
SynchronizedTable
的get和set方法中的超级调用静态地引用类表中的抽象方法。这是合法的,只要调用方法标记为抽象覆盖(§5.2)
最后,下面的mixin组合使用
字符串作为键,整数作为值,默认值为0:
对象MyTable
从SynchronizedTable
继承其get和set方法
这些方法中的超级调用被重新绑定以引用列表表
中的相应实现,这是中同步表
的实际超类型
MyTable
类型括号内的多个类型意味着对多个类型进行类型参数化。例如
trait Pair[A, B]
这是一对值,一个值的类型为a
,另一个值的类型为B
更新:
我认为您对类型参数的语义解释得太多了。由多个参数参数化的类型仅此而已。特定类型参数在类型参数列表中的位置并不使其具有任何特殊性。具体来说,类型参数列表中的最后一个参数不需要代表“返回类型”
您引用的play框架中的句子解释了这个特定类型的类型参数的语义。它不能推广到其他类型。函数
类型也是如此:这里最后一个类型参数恰好表示“返回类型”。但是,对于其他类型,情况并不一定如此。上面的类型对[A,B]
就是这样一个例子。这里B
是该对的第二个组件的类型。这里根本没有“返回类型”的概念
参数化类型的类型参数可以出现在参数化类型定义中可能出现“常规”类型的任何位置。也就是说,类型参数只是类型的名称,只有当参数化类型本身被实例化时,这些类型才绑定到实际类型
考虑类元组的以下定义:
class Tuple[A, B](a: A, b: B)
它被实例化为Int和String的元组类型,如下所示:
type TupleIntString = Tuple[Int, String]
这与
class TupleIntString(a: Int, b: String)
有关官方来源,请查看。特别是第1节第3.4节“基本类型和构件定义”。第四个要点是:“参数化类型C[T_1,…,T_n]的基本类型是类型C的基本类型,其中类型参数a_i of C的每次出现都被相应的参数类型T_i所取代。”我认为你的问题实际上可以分为三个独立的问题:
类/特征等的多个类型参数是什么?
一个典型的例子是从一种类型的对象映射到另一种类型的对象。如果希望键的类型不同于值的类型,但同时保持这两种类型,则需要两个类型参数。因此,Map[a,B]接受泛型类型a的键并映射到泛型类型B的值。想要从书签到页面的映射的用户会将其声明为Map[Bookmark,Page]。只有一个类型参数不允许这种区别
根据我的推测,Foo[T1,T2]的意思是,它定义了两个类型参数,它不必是取T1并返回T2
不,所有类型参数都是相等的公民,尽管它们对函数对象具有相同的含义。见下文
这些+/-是什么?
它们限制了类型参数可以绑定到的内容。本教程有一个
trait Pair[A, B]
class Tuple[A, B](a: A, b: B)
type TupleIntString = Tuple[Int, String]
class TupleIntString(a: Int, b: String)
class List[+A] {
..
def map[B](f: (A) ⇒ B): List[B]
}