scala Any 类型的表达式不符合预期的 type_$1

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37860513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 08:23:25  来源:igfitidea点击:

Expression of type Any doesn't conform to expected type_$1

scala

提问by Daryl

I have problems with undestanding Scala's type system.

我无法理解 Scala 的类型系统。

class A[T](var value: T)
class B[T](val a: A[T], var newValue: T)

val list = new MutableList[B[_]]()
val a: A[Int] = new A(10)
val b: B[Int] = new B(a, 11)
list += b

val someB = list.head
someB.a.value = someB.newValue

And after compile i see the error:

编译后我看到错误:

Error:(12, 24) type mismatch;
found   : A$A36.this.someB.newValue.type (with underlying type _)
required: _
someB.a.value = someB.newValue
                      ^

Both someB.a.valueand someB.newValuehave the same type but Scala's compiler actually doesn't think so. How this error can be fixed ?

双方someB.a.valuesomeB.newValue具有相同的类型,但Scala的编译器实际上并不这么认为。如何修复此错误?

采纳答案by Alexey Romanov

Don't expect the compiler to figure out two existentials are the same, even if they clearly have to be. Workarounds:

不要指望编译器会发现两个存在项是相同的,即使它们显然必须是相同的。解决方法:

  1. Use a type variable pattern:

    list.head match {
      case someB: B[a] => someB.a.value = someB.newValue
    }
    
  2. Extract a method:

    def setValue[A](b: B[A]) = b.a.value = b.newValue
    setValue(someB)
    
  1. 使用类型变量模式:

    list.head match {
      case someB: B[a] => someB.a.value = someB.newValue
    }
    
  2. 提取方法:

    def setValue[A](b: B[A]) = b.a.value = b.newValue
    setValue(someB)
    

回答by Daryl

One of solutions I have found is to eliminate usage of existential type with abstract types.

我发现的解决方案之一是消除对抽象类型的存在类型的使用。

class A[T](var value: T)
abstract class B {
  type T
  val a: A[T]
  val newValue: T
}

val list = new mutable.MutableList[B]()
val aa = new A(10)
val b = new B {
  type T = Int
  val a = aa
  val newValue = 11
}
list += b

val someB = list.head
someB.a.value = someB.newValue