gpt4 book ai didi

scala - 与 Scala 中的存在类型混淆

转载 作者:行者123 更新时间:2023-12-04 02:23:56 25 4
gpt4 key购买 nike

我一直在努力理解 scala 中的存在类型,但无法弄明白。这是我的测试代码:

scala> val a: Array[T] forSome {type T} = Array(1,2.2,"3")
a: Array[_] = Array(1, 2.2, 3)

scala> val b: Array[T forSome {type T}] = Array(1,2.2,"3")
b: Array[T forSome { type T }] = Array(1, 2.2, 3)

scala> a(0)
res35: Any = 1

scala> b(0)
res36: Any = 1

scala> a(0) = "x"
<console>:10: error: type mismatch;
found : String("x")
required: T
a(0) = "x"
^

scala> b(0) = "x"

有人告诉我,Array[T] forSome {type T} 表示任何类型的数组,例如 Array[Int]、Array[String] 等。Array[T forSome { type T}] 表示 Array[Any]。但是根据我测试代码的结果,我看不出这个区别,而且编译错误信息也很困惑。 required: T 是什么意思?如果有人能给出详细的解释,我将不胜感激,谢谢!

最佳答案

I was told that Array[T] forSome {type T} means any type of Array such as Array[Int], Array[String], etc.

没错。您可能会惊讶地发现值 Array(1,2.2,"3")被接受为 Array[T] forSome {type T} 类型的值, 即使 Array(1,2.2,"3")显然不是 Array[Int] 类型的值也不Array[String] .要了解发生了什么,让我们询问 Scala 它为 Array(1,2.2,"3") 推断出什么类型:

scala> val x = Array(1,2.2,"3")
x: Array[Any] = Array(1, 2.2, 3)

啊哈!所以有一个类型 T , 即 Any ,所以 x类型为 Array[T] .这就是为什么 Array(1,2.2,"3")被接受为 Array[T] forSome {type T} 类型的值.

Array[T forSome {type T}] means Array[Any]

也正确。类型<type expression involving T> forSome {type T}是所有类型的父类(super class)型,其中 <type expression involving T>在特定的 T 处实例化.所以Array[T] forSome {type T}Array[Int] 的父类(super class)型, Array[String]等。自T forSome {type T}Int 的父类(super class)型, String等,T forSome {type T}是所有类型的父类(super class)型,又名 Any .

scala> a(0)
res35: Any = 1

您可能想知道为什么结果的类型为 Any , 不是 T .与以下比较:

scala> (a(0), a(1))
res0: (T, T) forSome { type T } = (1,2.2)

如您所见,Array[T] 的元素类型确实是T .只是当我们只从数组中取一个元素时,它的类型是T forSome { type T } , 简化为 Any .

scala> b(0)
res36: Any = 1

这次输入 Any非常值得期待,因为 Array[T forSome {type T}] 的元素类型是T forSome {type T} , 又名 Any .

请注意,由于 forSome在括号内,一对元素的类型...

scala>  (b(0), b(1))
res1: (Any, Any) = (1,2.2)

...是(T forSome {type T}, T forSome {type T}) , 又名 (Any, Any) .

scala> a(0) = "x"
<console>:10: error: type mismatch;
found : String("x")
required: T
a(0) = "x"
^

您分配给 Array[T] 的值的类型必须是 T 的子类型.我们知道值 a有它的T实例化为 Any ,但是在类型检查时,重要的不是值的实际类型,而是它声明的类型。并且是 String T 的子类型?不,因为 a可能是 Array[Int]和一个 String不能放入 Array[Int] .

scala> b(0) = "x"
scala> b
res2: Array[T forSome { type T }] = Array(x, 2.2, 3)

您分配给 Array[T forSome {type T}] 的值的类型必须是 T forSome {type T} 的子类型又名 Any .是String Any 的子类型?是的,所以赋值成功。

关于存在的最后一件事:类型推断在 T 时效果最好只需实例化一次。之前我们看到 (a(0), a(1))产生了一对具有相同(未知)类型的元素。我真的很惊讶这有效。在以下非常相似的示例中,a(0)a(1)也应该具有相同的类型,因此赋值应该成功,但实际上没有。

scala> a(0) = a(1)
<console>:12: error: type mismatch;
found : (some other)T(in value a)
required: T(in value a)
a(0) = a(1)
^

为了向 Scala 表明这样的赋值是类型安全的,我们可以将它包装在一个适用于任何 Array[T] 的函数中。 :

scala> def modifyArray[T](arr: Array[T]) =
| arr(0) = arr(1)
modifyArray: [T](arr: Array[T])Unit

我们现在可以通过将函数应用于 a 来执行分配,这次确实成功了。

scala> modifyArray(a)

scala> a
res3: Array[_] = Array(2.2, 2.2, 3)

关于scala - 与 Scala 中的存在类型混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24646416/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com