【问题标题】:Scala: how to force type to be providedScala:如何强制提供类型
【发布时间】:2018-02-28 10:18:30
【问题描述】:

假设我们有以下特征和类定义

trait Model extends Product
class X[T <: Model] {}

给出上面我可以创建X的实例如下。

val x = new X

编译器不会抱怨。在这种情况下推断的类型是Nothing。我想知道如何在编译时防止这种情况发生,以便在不提供显式类型(即 Model 的子类型)的情况下不允许创建 X 的实例?

【问题讨论】:

    标签: scala type-inference scala-generics


    【解决方案1】:

    class X[T &lt;: Model] {} 类定义意味着T 类型具有上限 作为Model 类型。而Nothing 是所有其余类型的子类型。这就是 Scala 编译器 没有抱怨的原因。

    class X的类型T设为逆变

    class X[-T <: Model] {}
    

    这样当你定义

    val x = new X 
    

    Scala 编译器将其视为

    x: X[Model] = X@7c9bdee9
    

    【讨论】:

    • 我喜欢这个想法,但我不确定它是否符合 OP 的预期:new X 产生了 X[Model]
    • @Juh_ 这不是 OP 想要的吗?
    • 我认为他希望明确给出类型,即你不能写new X
    • 是的,不是我想要的,但我喜欢这个主意,所以投票吧。
    【解决方案2】:

    我认为这可行:

    trait Model
    case class M() extends Model // one subclass of Model, for testing
    
    // use implicit to force T to be convertible to Model
    // which works for actual Model subclasses but not Nothing
    class X[T<:Model](implicit f: (T) => Model)
    
    new X
      error: type mismatch;
      found   : <:<[Nothing,Nothing]
      required: T => Model
    
    new X[M] // ok
    

    但是你仍然可以明确地将Nothing 作为类型参数(奇怪...):

    new X[Nothing] // ok
    

    我会选择上述方法,但另一个想法是显式传递 Model 子类的 类作为参数

    class X[T<:Model](tClass: Class[T])
    
    new X(classOf[M]) // ok
    
    new X(classOf[Nothing])
      error: type mismatch;
      found   : Class[Nothing](classOf[scala.Nothing])
      required: Class[T]
      Note: Nothing <: T, but Java-defined class Class is invariant in type T.
      You may wish to investigate a wildcard type such as `_ <: T`. (SLS 3.2.10)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-24
      • 1970-01-01
      相关资源
      最近更新 更多