【问题标题】:Lower type bound on Scala field in mutable, covariant class?可变协变类中Scala字段的下限类型?
【发布时间】:2012-08-08 06:34:30
【问题描述】:

我想创建一个可变的协变类,所以我需要添加一个绑定到 setter 方法的较低类型。但是我也想让setter方法设置一个字段,所以我猜这个字段需要绑定相同的类型?

class Thing[+F](initialValue: F) {

    private[this] var secondValue: Option[G >: F] = None

    def setSecondValue[G >: F](v: G) = {
        this.secondValue = Some(v)
     }
}

该方法编译良好。但是名为 secondValue 的字段根本无法编译,并显示错误消息:

    Multiple markers at this line
        - ']' expected but '>:' found.
        - not found: type G

我需要做什么?

【问题讨论】:

    标签: scala covariance


    【解决方案1】:

    @mhs 的回答是对的。

    你也可以使用通配符语法(如在java中),其含义完全相同:

    scala> :paste
    // Entering paste mode (ctrl-D to finish)
    
    class Thing[+F](initialValue: F) {
      private[this] var secondValue: Option[_ >: F] = None
    
      def setSecondValue[G >: F](v: G) = {
        this.secondValue = Some(v)
      }
    
      def printSecondValue() = println(secondValue)
    }
    
    // Exiting paste mode, now interpreting.
    
    defined class Thing
    
    scala> val t = new Thing(Vector("first"))
    t: Thing[scala.collection.immutable.Vector[java.lang.String]] = Thing@1099257
    
    scala> t.printSecondValue()
    None
    
    scala> t.setSecondValue(Seq("second"))
    
    scala> t.printSecondValue()
    Some(List(second))
    

    【讨论】:

    • 嗯,我觉得我接受得太快了。这似乎是一个更优雅的解决方案。
    【解决方案2】:

    您需要forSome 构造,它将G 作为存在类型引入:

    class Thing[+F](initialValue: F) {
      private[this] var secondValue: Option[G] forSome { type G >: F} = None
    
      def setSecondValue[G >: F](v: G) = {
        this.secondValue = Some(v)
      }
    }
    

    secondValue 的原始代码中,G 是凭空抽出来的,也就是说,它没有被正确引入。在setSecondValue 的情况下,用户(或编译器)在调用站点绑定G,但对于一个不是选项的字段(特别是因为你的字段是私有的)。阅读更多关于forSome 和Scala 中的存在类型hereherehere

    【讨论】:

    • 完美 - 做我想要的。我尝试在该方法上使用 forSome 并且它也有效: def setSecondAroma(secondAroma: G forSome {type G>: F}) = ...
    • @JohnSmith 我不知道与仅使用常规类型参数 G 相比,在 setSecondValue 中使用 forSome G 是否有任何(不利)优势。如果您知道/发现,请在此处发布。
    • 注意,字段中输入G与此处方法中输入G无关。
    猜你喜欢
    • 2020-03-29
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2015-04-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    相关资源
    最近更新 更多