如果传递给方法的对象是可接受的类型,我需要执行相同的操作。是否可以消除下面例子中的第二种情况?
obj match {
case obj: String => print(obj)
case obj: Int => print(obj)
}
答案 0 :(得分:4)
是的,这是可能的,但不是在所有情况下都是如此。您可以在特定示例中使用Scalas |
运算符:
scala> ("hello": Any) match { case s @ (_: String | _: Int) => println(s)}
hello
scala> ("1": Any) match { case s @ (_: String | _: Int) => println(s)}
1
但是这个具体的例子只能起作用,因为println
期望一个Any
类型的参数,这实际上就是你在这里所拥有的。
考虑这个例子:
scala> object X {def f(i: Int) = i.toString; def f(s: String) = s}
defined object X
scala> ("": Any) match { case s @ (_: String | _: Int) => X.f(s)}
<console>:9: error: overloaded method value f with alternatives:
(s: String)String <and>
(i: Int)String
cannot be applied to (Any)
("": Any) match { case s @ (_: String | _: Int) => X.f(s)}
^
问题是虽然有两种方法可以处理这两种类型,但编译器无法决定应该调用哪种类型。这是因为编译器将推断Any
的类型s
,因为它可以是String
或Int
,并且编译器需要选择它们的公共超类型来完成此契约。并且因为不存在采用f
的方法Any
,所以会出现编译错误。在这种情况下,您需要分离模式:
scala> ("hello": Any) match { case s: String => X.f(s) case i: Int => X.f(i)}
res6: String = hello
总之,如果他们不必与Any
生活在一起,那么他们应该只将多个案例组合在一起。虽然,我建议不要使用Any
,但在代码更改时引入输入错误太容易了。