【问题标题】:Using unapply defined in traits在特征中使用 unapply 定义
【发布时间】:2022-01-24 05:36:50
【问题描述】:

我有一个特点

trait A {
    def doSomething(a: Seq[Int]): Seq[String] = {
        a.map {
            case AA(s) => s // want to use unapply defined in trait (this(AA) not allowed)
            case _ => "idc"
        }
    }
    
    def unapply(a: Int): Option[String] = getString(a)

    
    def getString(a: Int): Option[String] = {
        a match {
            case 1 => Some("one")
            case 2 => Some("two")
            case _ => None
        }
    }
}

object AA extends A
object AA2 extends A {
    override def getString(a: Int): Option[String] = {
        super.getString(a).orElse{
            a match {
                case 3 => Some("three")
                case 4 => Some("four")
                case _ => None
            }
        }
    } 
}

object MyClass {
    def main(args: Array[String]) {
        println(AA.doSomething(Seq(1,2,3,4,5))); // Output: List(one, two, idc, idc, idc)
        println(AA2.doSomething(Seq(1,2,3,4,5))); // Expect Output: List(one, two, three, four, idc) but get List(one, two, idc, idc, idc)
    }
}

这里的问题是我不能在不创建提取器对象的情况下使用 trait 中定义的 unapply。

我想使用这个 trait 覆盖不同对象中的 getString 方法。

【问题讨论】:

    标签: scala pattern-matching unapply


    【解决方案1】:

    您可以使用 self 类型来引用自己。

    trait A { self =>
      final def doSomething(a: Seq[Int]): Seq[String] =
        a.map {
          case self(s) => s
          case _       => "idc"
        }
    
      final def unapply(a: Int): Option[String] =
        getString(a)
    
      def getString(a: Int): Option[String] =
        a match {
          case 1 => Some("one")
          case 2 => Some("two")
          case _ => None
        }
    }
    

    按预期工作。


    代码运行here

    【讨论】:

      【解决方案2】:

      我使用的一个解决方案是

      trait A {
          def doSomething(a: Seq[Int]): Seq[String] = {
              a.map {
                  case Extractor(s) => s
                  case _ => "idc"
              }
          }
          
          object Extractor {
              def unapply(a: Int): Option[String] = getString(a)
          }
      
          
          def getString(a: Int): Option[String] = {
              a match {
                  case 1 => Some("one")
                  case 2 => Some("two")
                  case _ => None
              }
          }
      }
      
      object AA extends A
      object AA2 extends A {
          override def getString(a: Int): Option[String] = {
              super.getString(a).orElse{
                  a match {
                      case 3 => Some("three")
                      case 4 => Some("four")
                      case _ => None
                  }
              }
          } 
      }
      
      object MyClass {
          def main(args: Array[String]) {
              println(AA.doSomething(Seq(1,2,3,4,5))); // Output: List(one, two, idc, idc, idc)
              println(AA2.doSomething(Seq(1,2,3,4,5))); // Output: List(one, two, three, four, idc)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-02-03
        • 2014-05-06
        • 2019-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-21
        • 2014-08-13
        相关资源
        最近更新 更多