繁体   English   中英

什么是何时使用Scala的forSome关键字?

[英]What is and when to use Scala's forSome keyword?

List[T] forSome {type T}List[T forSome {type T}]什么List[T forSome {type T}] 我如何用“英语”阅读它们? 我应该如何神交 forSome关键字? forSome一些实际用途是forSome 什么是有用的实用和复杂的简单T forSome {type T}用法?

这里有很多问题,其中大部分已经在上面评论中链接的答案中得到了相当彻底的解决,所以我会回答你更具体的第一个问题。

List[T] forSome { type T }List[T forSome { type T }]之间没有真正有意义的区别,但我们可以看到以下两种类型之间的区别:

class Foo[A]

type Outer = List[Foo[T]] forSome { type T }
type Inner = List[Foo[T] forSome { type T }]

我们可以将第一个读作“ T的foos列表,对于某些类型T ”。 整个列表中只有一个T 第二,在另一方面,可以理解为“FOOS的列表,其中每个foo是的T一些T ”。

换句话说,如果我们有一个outer: Outer列表outer: Outer ,我们可以说“存在一些类型T ,使得outerT的foos列表”,其中对于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[_] )。 在大多数情况下这是可能的。 如果您的边缘情况不可能,请重构您的代码或放宽您的类型限制。

如何阅读“forSome”(以非正式的方式)

通常当您使用通用API时,API会保证您可以使用您提供的任何类型(最多一些给定的约束)。 因此,当您使用List[T] ,List API会保证它可以与提供的任何类型T 使用

对于forSome (所谓的存在量化类型参数),它是相反的。 API将提供一种类型(不是你),它保证你,它将使用它提供给你的这种类型。 语义是,具体对象会给你一些类型为T东西。 同一个对象也会接受它为您提供的内容。 但没有其他对象可以使用这些T s,没有其他对象可以为您提供T类型的东西。

“存在量化”的概念是:存在(至少)一种类型T (在实现中)以履行API的合同。 但我不会告诉你它是哪种类型。

forSome可以读取类似:对于某些类型的T的API合同成立。 但对于所有类型的T都不一定如此。 因此,当您提供某种类型的T (而不是在API的实现中隐藏的类型)时,编译器无法保证您获得了正确的T 所以它会抛出一个类型错误。

适用于您的示例

因此,当您在API中看到List[T] forSome {type T}时,您可以这样阅读:API将为您提供一些未知类型TList 它很乐意接受这个列表,它将与它一起使用。 但它不会告诉你, T是什么。 但至少你知道,列表中的所有元素都是相同的类型T

第二个有点棘手。 API再次为您提供一个List 它会使用某种类型的T而不是告诉你T是什么。 但是可以自由地为每个元素选择不同的类型。 真实世界的API会为T建立一些约束,因此它实际上可以使用列表的元素。

结论

当您编写API时, forSome很有用,其中每个对象代表API的实现。 每个实现都将为您提供一些对象,并将接受这些对象。 但是你既不能混合不同实现的对象,也不能自己创建对象。 相反,您必须始终使用相应的API函数来获取可与该API一起使用的一些对象。 forSome可以实现非常严格的封装。 您可以阅读forSome通过以下方式:

对于某些类型,API合约折叠为true。 但你不知道它适用于哪种类型。 因此,您无法提供自己的类型,也无法创建自己的对象。 您必须使用通过使用forSome的API提供的那些。

这非常非正式,在某些极端情况下甚至可能是错误的。 但它应该帮助你理解这个概念。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM