Scala模式匹配与Option [Any]混淆 [英] Scala pattern matching confusion with Option[Any]

查看:202
本文介绍了Scala模式匹配与Option [Any]混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下Scala代码。

I have the following Scala code.

import scala.actors.Actor

object Alice extends Actor {
  this.start
  def act{
    loop{
      react {
        case "Hello" => sender ! "Hi"
        case i:Int => sender ! 0
      }
    }
  }
}
object Test {
  def test = {
    (Alice !? (100, "Hello")) match {
      case i:Some[Int] => println ("Int received "+i)
      case s:Some[String] => println ("String received "+s)
      case _ =>
    }
    (Alice !? (100, 1)) match {
      case i:Some[Int] => println ("Int received "+i)
      case s:Some[String] => println ("String received "+s)
      case _ =>
    }
  }
}

执行<$ c $之后c> Test.test ,我得到输出:

scala> Test.test
Int received Some(Hi)
Int received Some(0)

我期望输出

String received Some(Hi)
Int received Some(0)

解释是什么?

作为第二个问题,我得到如下的未选中警告:

As a second question, I get unchecked warnings with the above as follows:

C:\scalac -unchecked a.scala
a.scala:17: warning: non variable type-argument Int in type pattern Some[Int] is unchecked since it is eliminated by erasure
      case i:Some[Int] => println ("Int received "+i)
             ^
a.scala:18: warning: non variable type-argument String in type pattern Some[String] is unchecked since it is eliminated by erasure
      case s:Some[String] => println ("String received "+s)
             ^
a.scala:22: warning: non variable type-argument Int in type pattern Some[Int] is unchecked since it is eliminated by erasure
      case i:Some[Int] => println ("Int received "+i)
             ^
a.scala:23: warning: non variable type-argument String in type pattern Some[String] is unchecked since it is eliminated by erasure
      case s:Some[String] => println ("String received "+s)
             ^
four warnings found

如何避免警告?

编辑:谢谢您的建议。 Daniel的想法很好,但似乎不适用于泛型类型,如下面的示例

Thanks for the suggestions. Daniel's idea is nice but does not seem to work with generic types, as in the example below

def test[T] = (Alice !? (100, "Hello")) match { 
   case Some(i: Int) => println ("Int received "+i) 
   case Some(t: T) => println ("T received ") 
   case _ =>  
}

遇到以下 error 警告: warning:类型模式T中的抽象类型T未选中,因为它已通过擦除消除了。

推荐答案

这是由于类型擦除引起的。 JVM不知道任何类型参数,除了数组上。因此,Scala代码无法检查 Option Option [Int] 还是 Option [String] -该信息已被删除。

This is due to type-erasure. The JVM does not know of any type parameter, except on arrays. Because of that, Scala code can't check whether an Option is an Option[Int] or an Option[String] -- that information has been erased.

您可以通过以下方式修复代码:

You could fix your code this way, though:

object Test {
  def test = {
    (Alice !? (100, "Hello")) match {
      case Some(i: Int) => println ("Int received "+i)
      case Some(s: String) => println ("String received "+s)
      case _ =>
    }
    (Alice !? (100, 1)) match {
      case Some(i: Int) => println ("Int received "+i)
      case Some(s: String) => println ("String received "+s)
      case _ =>
    }
  }
}

这样您就不会测试 Option 的类型是什么,但是其内容的类型是什么-假设有任何内容。 将落入默认情况。

This way you are not testing what the type of Option is, but what the type of its contents are -- assuming there is any content. A None will fall through to the default case.

这篇关于Scala模式匹配与Option [Any]混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆