【问题标题】:Scala abstract type representing type of subclassScala 抽象类型表示子类的类型
【发布时间】:2011-07-29 09:37:43
【问题描述】:

我正在寻找一种方法来定义返回类型 T 的方法,其中 T = 子类的类型。

我知道我可以使用抽象类型来做到这一点,但不喜欢必须为每个子类重新定义 T 的开销。

一些示例代码:

object Helper {
  def help[A <: MyClass](cls: A): Option[A] = { cls.foo() map { _.asInstanceOf[A] } }
}

class MyClass {
  type T <: MyClass
  def foo(): Option[T] = Some(this.asInstanceOf[T])
}

class ChildClass extends MyClass {
   type T = ChildClass
}

可能是一种新的语言功能使这变得更容易了?或者我可以以某种方式使用 this.type 吗?对我来说重要的是我能够定义一个可以以这种方式调用 foo 的辅助类。

【问题讨论】:

    标签: scala


    【解决方案1】:

    如果您总是返回this,那么您确实可以将this.type 作为返回类型。或者你已经试过了吗?

    this.type 特别有用,例如当您想要链接对同一个对象的调用时,或者提供一个静态保证,即您将返回同一个对象(而不是副本)。例如,Scala 中的Buffers 有追加操作:+,它返回一个Buffer[A],和+=,它返回this.type。前者复制了可变序列;后者保证您更新原始对象。

    【讨论】:

    • 鉴于我需要完全按原样编写 Helper.help(使用 type 参数),您是否有机会向我指出一些可行的特定语法? this.type 与 A 不匹配?另外,请注意我需要返回 Option[this.type],并且 def foo: Option[this.type] = Some(this) 似乎无法编译。感谢您的帮助!
    • @Pandora Singleton 类型永远不会被推断出来,您必须明确指定它:Some[this.type](this)
    • 非常感谢!我遇到了另一个小故障,因为实际上我的 foo 函数实际上调用了另一个对象的静态方法 --> 如果您有见解,请在此处跟进问题 :) stackoverflow.com/questions/6886182/…
    【解决方案2】:

    要跟进 Jean-Phillippe 的回答,他正是在我写我的时候写的,下面是代码:

    trait SomeTrait {
      def foo: this.type = this
    }
    
    class UsesTrait extends SomeTrait
    
    object Main {
      def main(args: Array[String]) {
        println((new UsesTrait).foo) // prints UsesTrait@<hash value>
      }
    }
    

    【讨论】:

    • 酷,这很有帮助。这是否扩展到 Option[this.type]? def foo: Option[this.type] = Some(this) 似乎无法编译。
    • 嘿,我最终也得到了这个。考虑到它的重要性,这是记录最少的语言功能之一......
    【解决方案3】:

    我发现以下成语很有用:

    class MyClass[T] {
      self: T => 
      def foo(): Option[T] = Some(this)
    }
    
    class ChildClass extends MyClass[ChildClass]
    
    new ChildClass().foo()
    //--> Option[ChildClass] = Some(ChildClass@2487b1)
    

    【讨论】:

    • 是的,但是: • 如果要允许整个类层次结构,它必须是一个特征,并且 • 它必须在T 中是协变的。总的来说,比简单的this.type 有更多的限制,不是吗?
    • @Jean-Philippe Pellet:是的,看起来像。我正在思考它是否也有优势,但没有找到。
    猜你喜欢
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    相关资源
    最近更新 更多