什么是以及何时使用Scala';什么是关键词?
对于某些{type T}的什么是以及何时使用Scala';什么是关键词?,scala,types,existential-type,Scala,Types,Existential Type,对于某些{type T}的List[T]和对于某些{type T}的List[T]之间有什么区别?我如何用“英语”阅读它们?我应该如何搜索某些关键字的?对于某些,有哪些实际用途?对于某些{type T}用法,有哪些实用且比简单的T更复杂的问题?这里有很多问题,其中大多数问题在上面评论中链接的答案中已经得到了非常彻底的解决,因此我将回答您更具体的第一个问题 对于某些{type T},List[T]与List[T对于某些{type T}]之间没有真正意义上的区别,但我们可以看到以下两种类型之间的区别
List[T]和对于某些{type T}
的List[T]之间有什么区别?我如何用“英语”阅读它们?我应该如何搜索某些关键字的?对于某些
,有哪些实际用途?对于某些{type T}
用法,有哪些实用且比简单的T更复杂的问题?这里有很多问题,其中大多数问题在上面评论中链接的答案中已经得到了非常彻底的解决,因此我将回答您更具体的第一个问题
对于某些{type T}
,List[T]与List[T对于某些{type T}]
之间没有真正意义上的区别,但我们可以看到以下两种类型之间的区别:
class Foo[A]
type Outer = List[Foo[T]] forSome { type T }
type Inner = List[Foo[T] forSome { type T }]
我们可以将第一个理解为“对于某些类型的T
,一个T
的foo列表”。整个列表只有一个T
。另一方面,第二个可以理解为“一个foo列表,其中对于某些T
,每个foo都是T
”
换句话说,如果我们有一个列表outer:outer
,我们可以说“存在一些类型T
,因此outer
是一个T
的foo列表”,其中对于类型Inner
的列表,我们只能这样说“对于列表中的每个元素,都存在一些T
,因此该元素是T
的foo”。后者较弱,它告诉我们的列表信息较少
例如,如果我们有以下两个列表:
val inner: Inner = List(new Foo[Char], new Foo[Int])
val outer: Outer = List(new Foo[Char], new Foo[Int])
第一个将很好地编译,对于某些T
,列表中的每个元素都是Foo[T]
。第二个不会编译,因为没有一些T
,因此列表中的每个元素都是Foo[T]
注意:(更新2016-12-08)根据Martin Odersky在ScalaX 2016上的演讲,forSome关键字很可能会随着Scala 2.13或2.14而消失。用路径相关类型或匿名类型属性(A[\u]
)替换它。这在大多数情况下都是可能的。如果您的边缘情况不可能实现,请重构代码或放宽类型限制
如何阅读“forSome”(以非正式的方式)
通常,当您使用通用API时,API会向您保证,它将与您提供的任何类型一起工作(不超过某些给定的约束)。因此,当您使用List[T]
时,List API会向您保证它将与您提供的任何类型T
一起工作
对于某些
(所谓的存在量化类型参数),则相反。API将提供一个类型(而不是您)它向你保证,它将使用它提供给你的类型。语义是,一个具体的对象将给你T
类型的东西。同一个对象也会接受它提供给你的东西。但是没有其他对象可以使用这些T
类型,也没有其他对象可以为你提供T
类型的东西。
“存在量化”的思想是:存在(至少)一种类型T
(在实现中)来实现API的契约。但我不会告诉您它是哪种类型
对于某些
可以理解为类似的内容:对于某些类型的T
,API合同适用。但并非所有类型的T
都适用。因此,当您提供某些类型的T
时(而不是API实现中隐藏的类型),编译器无法保证您得到正确的T
。因此它将抛出类型错误
适用于你的例子
所以当你看到一些{type T}的List[T]
在API中,您可以这样阅读:API将为您提供某种未知类型的列表T
。它将很高兴地接受此列表并使用它。但它不会告诉您T
是什么。但您至少知道,列表中的所有元素都是相同类型的T
第二个有点棘手。API将再次为您提供一个列表。它将使用某种类型T
,而不会告诉您T
是什么。但是它可以为每个元素自由选择不同的类型。现实世界的API将为T
建立一些约束,因此它实际上可以与列表中的元素
结论
forSome
在编写API时非常有用,其中每个对象都代表API的一个实现。每个实现都将为您提供一些对象,并将接受这些对象。但是您既不能混合来自不同实现的对象,也不能自己创建对象。相反,您必须始终使用相应的响应API函数以获取一些将与该API一起使用的对象。forSome
支持一种非常严格的封装。您可以通过以下方式读取forSome
:
API合同对某些类型是正确的,但你不知道具体是什么类型
它适用于哪些类型。因此,您不能提供自己的类型和
您不能创建自己的对象。您必须使用提供的对象
通过对某些
使用的API
这是一个非常非正式的问题,在某些情况下甚至可能是错误的。但它应该有助于你探索这个概念。看看这个,然后从info
tab解决了更一般的“什么是存在主义类型?”问题。我认为理解它的唯一方法(不必花几周的时间阅读文章)就是用关键字编写一个方法,然后尝试实现并使用它。这可能不是最好的方法,但我认为没有更好的方法。问题是关于摸索。无论如何,我最近注意到,2.7.1规范中的更改日志附录显示了如何修复List[List[\u]]也不管怎样,当一个有文字的人用一些文字介入时,这很好。>用路径依赖类型替换它路径依赖类型无法避免exis