繁体   English   中英

模式匹配任何=>列表[任何] =>列表[长]

[英]Pattern-match against Any => List[Any] => List[Long]

使用Scala我试图模式匹配一​​个返回值类型为Any来拉出任何List[Any]和模式匹配List[Long]List[Double]

有没有更优雅的方式来做到这一点?

运行scala 2.11

case class Accumulator (
    name: Option[String],
    value: Option[Any]
)

def bar[T <: Any](value: T): Unit = {
    val listOfAny = value.asInstanceOf[List[Any]]
    val listOfTypes = listOfAny.map(x => x.getClass.getSimpleName).toSet

    listOfTypes.size match {
        case 1 => listOfTypes.head match {
            case "Long" => println("Long list")
            case "Double" => println("Double list")
            case _ => Unit
        }
        case _ => Unit //Probably throw an error log
    }
}

def foo(accumulator: Accumulator): Unit = {
    accumulator match {
        case Accumulator(_, Some(value)) => value match {
            case v if v.isInstanceOf[List[_]] => bar(v)
            case _ => Unit
        }
        case _ => Unit
    }
}


//Should print out "Long List"
foo(Accumulator(None, Some(List(1L, 2L, 3L))))
//Should print out "Double List"
foo(Accumulator(None, Some(List(1.0, 2.0, 3.0))))

编辑:

能够清理匹配稳定标识符的字符串

case class Accumulator (
    name: Option[String],
    value: Option[Any]
)

def bar[T <: Any](value: T): Unit = {
    val listOfAny = value.asInstanceOf[List[Any]]
    val listOfTypes = listOfAny.map(x => x.getClass).toSet

    listOfTypes.size match {
        case 1 => 
            val headType: Class[_] = listOfTypes.head

            // Stable identifiers
            val ClassOfLong: Class[java.lang.Long] = classOf[java.lang.Long]
            val ClassOfDouble: Class[java.lang.Double] = classOf[java.lang.Double]

            headType match {
                case ClassOfLong => 
                    val result: Long = listOfAny.asInstanceOf[List[Long]].sum
                    println(s"Long List sum: $result")
                case ClassOfDouble =>
                    val result: Double = listOfAny.asInstanceOf[List[Double]].sum
                    println(s"Double List sum: $result")
                case _ => Unit
        }
        case _ => Unit //Probably throw an error log
    }
}

def foo(accumulator: Accumulator): Unit = {
    accumulator match {
        case Accumulator(_, Some(value)) => value match {
            case v if v.isInstanceOf[List[_]] => bar(v)
            case _ => Unit
        }
        case _ => Unit
    }
}


//Should print out "Long List sum: 6"
foo(Accumulator(None, Some(List(1L, 2L, 3L))))
//Should print out "Double List sum: 6.0"
foo(Accumulator(None, Some(List(1.0, 2.0, 3.0))))

如果列表不为空且所有元素的类型相同,则可以匹配返回的对象和列表中的第一个元素。 像这样的东西

def surprise(): Any = Random.nextInt(3) match {
  case 0 => List(1L, 2L, 3L)
  case 1 => List(0.5, 1.5, 2.5)
  case _ => "foo"
}

0 to 10 foreach { _ =>
  surprise() match {
    case l @ List(_: Long, _*) =>
      println(s"Longs: $l")
    case l @ List(_: Double, _*) =>
      println(s"Doubles: $l")
    case x =>
      println(s"Something else: $x")
  }
}

输出:

"""
Something else: foo
Something else: foo
Longs: List(1, 2, 3)
Doubles: List(0.5, 1.5, 2.5)
Doubles: List(0.5, 1.5, 2.5)
Doubles: List(0.5, 1.5, 2.5)
Doubles: List(0.5, 1.5, 2.5)
Doubles: List(0.5, 1.5, 2.5)
Something else: foo
Longs: List(1, 2, 3)
Something else: foo
"""
case class Accumulator (
    name: Option[String],
    value: Option[Any]
)

def bar[T <: Any](value: T): Unit = {
    val listOfAny = value.asInstanceOf[List[Any]]
    val listOfTypes = listOfAny.map(x => x.getClass).toSet

    listOfTypes.size match {
        case 1 => 
            val headType: Class[_] = listOfTypes.head

            // Stable identifiers
            val ClassOfLong: Class[java.lang.Long] = classOf[java.lang.Long]
            val ClassOfDouble: Class[java.lang.Double] = classOf[java.lang.Double]

            headType match {
                case ClassOfLong => 
                    val result: Long = listOfAny.asInstanceOf[List[Long]].sum
                    println(s"Long List sum: $result")
                case ClassOfDouble =>
                    val result: Double = listOfAny.asInstanceOf[List[Double]].sum
                    println(s"Double List sum: $result")
                case _ => Unit
        }
        case _ => Unit //Probably throw an error log
    }
}

def foo(accumulator: Accumulator): Unit = {
    accumulator match {
        case Accumulator(_, Some(value)) => value match {
            case v if v.isInstanceOf[List[_]] => bar(v)
            case _ => Unit
        }
        case _ => Unit
    }
}


//Should print out "Long List sum: 6"
foo(Accumulator(None, Some(List(1L, 2L, 3L))))
//Should print out "Double List sum: 6.0"
foo(Accumulator(None, Some(List(1.0, 2.0, 3.0))))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM