Fre*_*ind 11 type-systems scala existential-type
我正在阅读文章"Scala中的存在类型",并找到了一些我无法理解的东西:
Array[T] forSome { type T; }
Array[T forSome { type T; }]
Run Code Online (Sandbox Code Playgroud)
它们看起来几乎相同,但它们实际上是非常不同的.第一个是所有数组的类型,无论它们的类型参数如何.第二个是Array [Any].
为什么他们如此不同,尤其是,为什么第二个意味着Array[Any]什么呢?
Did*_*ont 10
更改括号的位置可能会改变很多意义,这一点不足为奇.有点像你切换∃和∀
第一个意思是:有一些类型T,这是一个Array[T].所以这是满足的Array[String],Array[Int]等等.数组是同质的,但我们不知道哪种类型.
第二个意思是:对于数组的每个元素,都有一些类型T,这样元素就是类型T.这根本没有约束,所以它只是Array[Any].forSome如果您这样做,那么在方括号内部可能很有用
Array[Set[T] forSome {type T}]
Run Code Online (Sandbox Code Playgroud)
这意味着数组的元素都是集合,但在同一个数组中可能同时存在一组Int和一组字符串.
关于Rich Oliver关于类型擦除的评论:这主要是编译时间的事情,它们确实不同.在第一种情况下,它是一个我们不知道的元素类型的数组.所以我们不能这样做a(0) = 1,因为它可能是一个很好的Array[String].相反,对于第二种类型,它是a Array[Any],而a(0)= 1就可以了.
不同之处在于类型系统何时决定T是什么.
也许最好的答案是,尝试在某些代码中使用这两种类型,看看会发生什么,并试图找出原因.但我会首先尝试解释一些类型理论.在这种情况下:
Array[T forSome { type T; }]
Run Code Online (Sandbox Code Playgroud)
其中forSome是内部[]支架,其本身的每个元素只是必须以某种方式所解释的T forSome { type T; }.好的,所以Inta T是某种类型的T,所以你可以把一个Int放在数组中.A String也T适用于某种类型T,并且因为选择forSome一次只适用于一个元素,所以你可以说这T是String时间而不是Int,所以你可以把它String放在数组中,即使它已经包含了一个Int.
另一方面,虽然我们可以T独立地选择数组的任何元素,但是已经选择了数组本身的类型:它是可以容纳任何东西的数组类型.它不能是一个Array[Int]或一个Array[String].
但在这种情况下:
Array[T] forSome { type T; }
Run Code Online (Sandbox Code Playgroud)
在T阵列外只决定一次类型.该数组实际上可以是Array[Int],和Array[String],或Array[Any].但是一旦T选择了类型,数组的所有元素都必须与该类型一致.
好的,现在让我们尝试一些代码.这是一个例子:
scala> var a = Array(1,2);
a: Array[Int] = Array(1, 2)
scala> def first(z : Array[T] forSome { type T }) = z(0);
first: (z: Array[_])Any
scala> def firstany(z : Array[T forSome { type T }]) = z(0);
firstany: (z: Array[T forSome { type T }])Any
scala> first(a);
res0: Any = 1
scala> firstany(a);
error: type mismatch;
found : Array[Int]
required: Array[T forSome { type T }]
firstany(a);
^
Run Code Online (Sandbox Code Playgroud)
为什么错误?因为数组a具有类型Array[Int],它只能包含类型的东西Int.这肯定是一个Array[T] forSome {type T},因为所有类型系统需要做的是选择Int作为类型T.因此first(a)可以.但如上所述,一个Array[T forSome { type T }]不能是一个Array[Int],所以firstany(a)是一个错误.
但是以下是可以的,因为a Array[Any]是Array[T forSome { type T }]:
scala> var b = Array(1, "x");
b: Array[Any] = Array(1, x)
scala> firstany(b);
res1: Any = 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
432 次 |
| 最近记录: |