Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 具有低界现场方法类型参数的不变声明类型参数_Scala - Fatal编程技术网

Scala 具有低界现场方法类型参数的不变声明类型参数

Scala 具有低界现场方法类型参数的不变声明类型参数,scala,Scala,下面是一个例子: class Test[A] { def print[B >: A](x : B): Unit = { println(x.isInstanceOf[A]) println(x.isInstanceOf[B]) } } val test = new Test[Int] test.print("string") 返回true(这意味着A、B是字符串类型) 当[B在您的示例中,约束B>:A编译的原因是编译器试图寻找满足约束的最特定类型。由于Int是您

下面是一个例子:

class Test[A] {
  def print[B >: A](x : B): Unit = {
    println(x.isInstanceOf[A])
    println(x.isInstanceOf[B])
  }
}

val test = new Test[Int]
test.print("string")
返回
true
(这意味着A、B是字符串类型)


[B在您的示例中,约束
B>:A
编译的原因是编译器试图寻找满足约束的最特定类型。由于
Int
是您的下限,
String
Int
都共享一个超级类型
Any
,编译器允许编译此示例

您必须记住的一件事是Scala在JVM上运行(至少是最常见的发行版),这意味着我们必须为泛型类型提供支持

如果我们编译您的示例并查看擦除后阶段,我们会看到:

class Test extends Object {
  def print(x: Object): Unit = {
    scala.this.Predef.println(scala.Boolean.box(x.$isInstanceOf[Object]()));
    scala.this.Predef.println(scala.Boolean.box(x.$isInstanceOf[Object]()))
  };
}
如您所见,由于类型擦除,我们实际上将
x
Object
进行了两次比较,这就是为什么您会看到
true
打印了两次

如果要检查类型是否相等,则需要提供a的隐式证据。a
TypeTag
在运行时提供类型信息。如果提供,我们可以将
typeOf
用于检查特定类型的相等性。我们需要通过上下文边界或显式通过隐式参数提供
TypeTag
(对于本例,我将使用前者):


如果要执行与[A]
相当的
x.isInstanceOf[A]
scala.reflect.ClassTag
可能比
TypeTag
更适合:

import scala.reflect.{ClassTag, classTag}
class Test[A: ClassTag] {
  def print[B >: A : ClassTag](x : B): Unit = {
    println(x match { case _: A => true; case _ => false })
    // or println(classTag[A].runtimeClass.isInstance(x))
    println(x match { case _: B => true; case _ => false })
  }
}

val test = new Test[Int]
test.print("string")
isInstanceOf
类似,上述操作使用的是
x的实际值,而不是静态类型。您可以通过调用

val test = new Test[Some[Int]]
val x: Option[Int] = Some(1)
val y: Option[Int] = None
test.print(x)
test.print(y)

使用这个和另一个答案。(但请注意,
ClassTag
不处理类型参数:
newtest[Some[String]]
将给出相同的结果).

Super!你能分享一下你是如何看到编译各个阶段的进展的吗?谢谢!!@AmitPaz你可以使用
scalac
标志来监视编译的各个阶段。Do
scalac-Xprint:all FileName.scala
如果你有问题,请随时提问。
val test = new Test[Some[Int]]
val x: Option[Int] = Some(1)
val y: Option[Int] = None
test.print(x)
test.print(y)