scala - 为什么 scala 无法从 2 个函数推断通配符类型?

标签 scala generics type-inference unbounded-wildcard

我定义了以下函数:

import org.apache.spark.sql.catalyst.{ScalaReflection}

import ScalaReflection.universe
import universe.TypeTag

def scalaTypesFor(dataType: DataType): Set[TypeTag[_]] = ...

def scalaTypeOpt: Option[TypeTag[_]] = ...

val catalystType = ...
scalaTypeOpt.map(v => Set(v))
      .getOrElse{
        val default = scalaTypesFor(catalystType)
        default
      }

在这种情况下,scalaTypesFor 和 scalaTypeOpt 都期望生成带有通配符参数的 TypeTag,它们应该具有相同的类型。但是,编译器给了我以下错误:

Error:(29, 51) inferred type arguments [scala.collection.immutable.Set[_117] forSome { type _$2; type _117 >: org.apache.spark.sql.catalyst.ScalaReflection.universe.TypeTag[_$2] <: org.apache.spark.sql.catalyst.ScalaReflection.universe.TypeTag[_] }] do not conform to method getOrElse's type parameter bounds [B >: scala.collection.immutable.Set[org.apache.spark.sql.catalyst.ScalaReflection.universe.TypeTag[_$2]] forSome { type _$2 }]
    val effective = scalaTypeOpt.map(v => Set(v)).getOrElse{
                                                  ^

类型推断有什么问题以及如何修复它?

最佳答案

我认为问题在于你有两种未知类型_并且不能保证它们兼容。另外,scala 中的不可变集合是不正确的不变性(在人们开始评论之前,已经有很多讨论,最后的结论是,实际上,没有真正根本的原因让它们不协变),因此这往往会产生烦人的结果还有打字问题。

没有编译器可供测试,但您可以尝试一些方法

  1. (不太可能起作用)将 Set 的类型归因于 Set[TypeTag[_]](v)
  2. 更改您的代码,以便允许编译器捕获未知类型并向自己证明它是相同的类型:

    def scalaTypesFor[T](dataType: DataType): Set[TypeTag[T]] = ???
    
    def scalaTypeOpt[T]: Option[TypeTag[T]] = ???
    
    def xform[T] = {
       val catalystType = ???
       scalaTypeOpt[T].map(v => Set(v))
          .getOrElse{
           val default = scalaTypesFor[T](catalystType)
           default
         }
     }
    

或者如果你可以将它们设为本地定义

    def xform[T] = {
       def scalaTypesFor(dataType: DataType): Set[TypeTag[T]] = ???
       def scalaTypeOpt: Option[TypeTag[T]] = ???

       val catalystType = ???
       scalaTypeOpt.map(v => Set(v))
          .getOrElse{
           val default = scalaTypesFor(catalystType)
           default
         }
     }

关于scala - 为什么 scala 无法从 2 个函数推断通配符类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38043008/

相关文章:

scala - 无法理解 Scala 中的类型错误

scala - LDA 交叉验证评估器

generics - 如何在 rust 中使用通用数组 crate 初始化通用数组?

c# - 如何在具有良好调用语法的 LINQ 中实现 NotOfType<T>?

Haskell:鼓励 GHC 推断正确的中间类型

generics - 无法解析具有类型约束的简单 F# 运行时泛型函数

scala - 如何在 sbt 0.13 中使用 sbt-scalabuff 插件?

java - 实现重复性作业,每秒重复次数不超过一次

java - Java 中 vararg 的性能影响

c# - 泛型类型推断不考虑多态性