如何检查Scala对象是A或B的实例?

时间:2021-08-16 22:01:09

I need to perform the same operation if an object passed to a method is either of acceptable types. Is it possible to eliminate the second case in the example below?

如果传递给方法的对象是可接受的类型之一,则需要执行相同的操作。是否有可能消除下面例子中的第二种情况?

obj match {
  case obj: String => print(obj)
  case obj: Int => print(obj)
}

1 个解决方案

#1


4  

Yes, it is possible, but not in every case. You can use Scalas | operator in your specific example:

是的,这是可能的,但不是所有情况都如此。您可以在特定示例中使用Scalas |操作符:

scala> ("hello": Any) match { case s @ (_: String | _: Int) => println(s)}
hello

scala> ("1": Any) match { case s @ (_: String | _: Int) => println(s)}
1

But this specific example only works because println expects an argument of type Any, which is in fact what you have here.

但是这个特定的例子只适用于println需要一个类型为Any的参数,这就是这里的参数。

Consider this example:

考虑一下这个例子:

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)}
                                                                   ^

The problem is that while there are two methods which could handle both types, the compiler can't decide which one should be called. This is because the compiler will infer type Any for s because it can be both String or Int and the compiler needs to chose their common supertype to fulfill this contract. And because there exists no method f which takes an Any you get a compilation error. In this case you need to separate the pattern:

问题是,虽然有两个方法可以处理这两种类型,但是编译器不能决定应该调用哪个类型。这是因为编译器将为s推断任何类型,因为它可以是字符串或Int,编译器需要选择它们的公共超类型来完成这个契约。因为不存在取任意值的方法f你会得到一个编译错误。在这种情况下,您需要分离模式:

scala> ("hello": Any) match { case s: String => X.f(s) case i: Int => X.f(i)}
res6: String = hello

In summary you should only combine multiple cases when they have the same type, if they don't you have to live with Any. Though, I suggest not to live with Any it is too easy to introduce typing bugs when the code changes.

总而言之,你应该只合并多个具有相同类型的案例,如果它们没有,你必须与任何一个一起生活。尽管如此,我还是建议不要在代码更改时引入输入错误太容易了。

#1


4  

Yes, it is possible, but not in every case. You can use Scalas | operator in your specific example:

是的,这是可能的,但不是所有情况都如此。您可以在特定示例中使用Scalas |操作符:

scala> ("hello": Any) match { case s @ (_: String | _: Int) => println(s)}
hello

scala> ("1": Any) match { case s @ (_: String | _: Int) => println(s)}
1

But this specific example only works because println expects an argument of type Any, which is in fact what you have here.

但是这个特定的例子只适用于println需要一个类型为Any的参数,这就是这里的参数。

Consider this example:

考虑一下这个例子:

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)}
                                                                   ^

The problem is that while there are two methods which could handle both types, the compiler can't decide which one should be called. This is because the compiler will infer type Any for s because it can be both String or Int and the compiler needs to chose their common supertype to fulfill this contract. And because there exists no method f which takes an Any you get a compilation error. In this case you need to separate the pattern:

问题是,虽然有两个方法可以处理这两种类型,但是编译器不能决定应该调用哪个类型。这是因为编译器将为s推断任何类型,因为它可以是字符串或Int,编译器需要选择它们的公共超类型来完成这个契约。因为不存在取任意值的方法f你会得到一个编译错误。在这种情况下,您需要分离模式:

scala> ("hello": Any) match { case s: String => X.f(s) case i: Int => X.f(i)}
res6: String = hello

In summary you should only combine multiple cases when they have the same type, if they don't you have to live with Any. Though, I suggest not to live with Any it is too easy to introduce typing bugs when the code changes.

总而言之,你应该只合并多个具有相同类型的案例,如果它们没有,你必须与任何一个一起生活。尽管如此,我还是建议不要在代码更改时引入输入错误太容易了。