gpt4 book ai didi

scala - scala中 `type`和 `#`关键字的调查

转载 作者:行者123 更新时间:2023-12-04 01:54:49 24 4
gpt4 key购买 nike

有人可以解释type关键字和 #运算符在scala中工作以及如何使用它?
请看例子。

//Example1
scala> type t1 = Option.type
defined type alias t1

//Shouldn't this work since previous example simply works?
scala> type t2 = String.type
<console>:7: error: type mismatch;
found : String.type
required: AnyRef
type t2 = String.type
^

//lets define custom trait T
scala> trait T
defined trait T

//... and obtain it's type like in Example1.
//Shouldn't this work since previous Example1 simply works?
scala> type t3 = T.type
<console>:7: error: not found: value T
type t3 = T.type
^

//Lets define some value of type T
scala> val v4 = new T{}
v4: T = $anon$1@5c3e8c76

//and obtain it's type (works)
scala> type t4 = v4.type
defined type alias t4

//this doesn't work
scala> type t4_1 = (new T{}).type
<console>:1: error: identifier expected but 'new' found.
type t4_1 = (new T{}).type

//as well as this (doesn't work)
scala> type t5 = "abc".type
<console>:1: error: identifier expected but string literal found.
type t5 = "abc".type
^

//but this compiles well
scala> val v6 = "abc"
v6: String = abc

scala> type t6 = v6.type
defined type alias t6


//lets create some values of created types:
scala> type t1 = Option.type
defined type alias t1

scala> val v1_1 = Some(10)
v1_1: Some[Int] = Some(10)

scala> type t7 = v1_1.type
defined type alias t7

scala> val v7:t7 = null
v7: t7 = null

scala> val v7_1:t7 = v1_1
v7_1: t7 = Some(10)

scala> val v7_2:t7 = Some(10)
<console>:9: error: type mismatch;
found : Some[Int]
required: t7
(which expands to) v1_1.type
val v7_2:t7 = Some(10)
^


//next let's try # operator

scala> class X[A,B](a:A,b:B)
defined class X

//doesn't work
scala> type xa = X[A,B]#A
<console>:8: error: not found: type A
type xa = X[A,B]#A
^
<console>:8: error: not found: type B
type xa = X[A,B]#A
^

//but such approach works:
scala> trait X2[C]{
type A
type B
val c:C
}
defined trait X2

scala> type xa2_1 = X2[String]#A
defined type alias xa2_1

scala> type xa2_2[M] = X2[M]#A
defined type alias xa2_2

最佳答案

首先,您对 type 的问题:

类型声明的右侧必须是具有稳定路径的类型的名称。因此,一个一个地举出你的例子:

type t1 = Option.type

t1 是 Option 类型的别名。对象,而不是 Option类(class)。
type t2 = String.type

这是一个错误,因为没有 String目的。这个错误有点奇怪,因为 String 是一个 Java 类,因此在不同的规则下运行(因为 Java 类从来没有同伴)。
type t3 = T.type

同上。这次错误更清楚了,因为 T 是一个 Scala 类,所以编译器可以明确地说“T 没有用类型命名对象”
type t4 = v4.type

这是由 val v4 命名的对象的单例类型。 .它不引用任何类型 T 的实例,甚至不引用由您的 new T{} 创建的匿名类的任何实例。表达。它指的是仅由 v4 表示的类型和 null ,即它们是该类型唯一允许的值。
type t4_1 = (new T{}).type

这是非法的,因为你使用的类型必须是一个稳定的标识符(粗略地说,一个其引用永远不会改变的标识符——如果标识符的完整路径只包含包的名称, object s , 和 val s,它是稳定的)。
type t5 = "abc".type

同上。
type t6 = v6.type
v6是一个稳定的标识符。 t6是仅由名称 v6 引用的特定 String 实例所包含的类型(和 null )。
type v6 = v1_1.type

再次,单例类型。
val v7: t7 = null
nullt7 类型的有效值
val v7_1:t7 = v1_1

这个特殊的对象也是如此。
val v7_2:t7 = Some(10)

但这是一个不同的对象(即使它是 ==v7 ,它不是 eq 到它),因此不是这种类型的成员。

现在约 # :
class X[A,B](a:A,b:B)
AB是类型参数。他们不能在类外被提及。您可以将它们视为具有 private[this] 的抽象类型别名。能见度,虽然这不是很准确。
type xa = X[A,B]#A

所以是的,不可见。
type xa2_1 = X2[String]#A

从此 A引用公共(public)类型别名,可以在类外通过名称引用。请注意,这种特殊情况非常无用,因为您对这种类型一无所知。如果你的特质 X2有一个返回 A 类型值的方法,你可以做类似的事情
val aFromX2: xa2_1 = x2instance.methodThatReturnsAnA

..但是你不能用它做任何其他事情,甚至将它传递回 X2[String] 的实例因为不能保证这两个 A s 指的是同一类型!另一方面,如果你有一个具体的实例,你可以这样做:
def passAroundA(x2instance: X2[String]) {
type x2a = x2instance.A // note dot, not #
val a: x2a = x2instance.methodThatReturnsAnA
x2instance.methodThatTakesAnA(a)
}

在这种情况下它可以工作,因为即使我们不知道 A 是什么实际上,我们知道这两种方法使用相同的类型——无论是固定在 x2instance的 build 。

关于scala - scala中 `type`和 `#`关键字的调查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12959438/

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