Scala:与 Option[Foo] 和 Foo 的参数进行模式匹配
Scala : Pattern matching with Option[Foo] and parameter of Foo
如何重写以下内容以使其更多'Scala way'或只使用一个匹配项?
case class Foo(bar: Any)
val fooOpt = Some(Foo("bar as String"))
def isValid(p: Any) = p match {
case _ @ (_: String | _: Int) => true
case _ => false
}
//Is it possible to check for the type of bar directly in this if statement?
fooOpt match {
case Some(f) if isValid(f.bar) => doSomething
case _ => doSomethingElse
}
一种替代方法是使用 isInstanceOf。
fooOpt match {
case Some(f) if f.bar.isInstanceOf[String] => doSomething
case Some(f) if f.bar.isInstanceOf[Int] => doSomething //could also rewrite to use just one case
case _ => doSomethingElse
}
还有其他方法吗?
这一切都可以在一个大的模式匹配中完成:
fooOpt match {
case Some(Foo(_: Int | _: String)) => doSomething
case _ => doSomethingElse
}
如果你想得到 Int
或 String
,只需拆分 case
:
fooOpt match {
case Some(Foo(i: Int)) => doSomething
case Some(Foo(s: String)) => doSomething
case _ => doSomethingElse
}
Is there other way?
虽然一个大模式匹配的解决方案有效(如果你真的不能将 bar
更改为比 Any
更具体的任何内容,则可以使用),但它不是一个合适的 'Scala way' 如果您可以控制 Foo
.
,则通常可以处理这种情况
更好的方法是使 Foo 通用:
case class Foo[T](bar: T)
并且有一个通用的 doSomething
,如果它可以与任何特定的 T
一起使用:
def doSomething[T](foo: Foo[T]): SomeType = ???
或者为不同的可能 T
使用不同的版本,如果它对它们有不同的反应:
def doSomethingWithString(foo: Foo[String]): SomeType = ???
def doSomethingWithInt(foo: Foo[Int]): SomeType = ???
然后就可以这样使用了:
val fooOpt = Some(Foo("bar as String"))
fooOpt.map(doSomething).orElse(doSomethingElse)
或者像这样:
val fooOptString = Some(Foo("bar as String"))
fooOptString.map(doSomethingWithString).orElse(doSomethingElse)
val fooOptInt = Some(Foo(1))
fooOptInt.map(doSomethingWithInt).orElse(doSomethingElse)
因此,在这种情况下,编译器会为您检查类型,回答:
Is it possible to check for the type of bar directly?
在许多情况下,您可以完全避免使用模式匹配,使用 map
、orElse
等方法并正确输入。这可能是这个问题的答案:
could also rewrite to use just one case
如何重写以下内容以使其更多'Scala way'或只使用一个匹配项?
case class Foo(bar: Any)
val fooOpt = Some(Foo("bar as String"))
def isValid(p: Any) = p match {
case _ @ (_: String | _: Int) => true
case _ => false
}
//Is it possible to check for the type of bar directly in this if statement?
fooOpt match {
case Some(f) if isValid(f.bar) => doSomething
case _ => doSomethingElse
}
一种替代方法是使用 isInstanceOf。
fooOpt match {
case Some(f) if f.bar.isInstanceOf[String] => doSomething
case Some(f) if f.bar.isInstanceOf[Int] => doSomething //could also rewrite to use just one case
case _ => doSomethingElse
}
还有其他方法吗?
这一切都可以在一个大的模式匹配中完成:
fooOpt match {
case Some(Foo(_: Int | _: String)) => doSomething
case _ => doSomethingElse
}
如果你想得到 Int
或 String
,只需拆分 case
:
fooOpt match {
case Some(Foo(i: Int)) => doSomething
case Some(Foo(s: String)) => doSomething
case _ => doSomethingElse
}
Is there other way?
虽然一个大模式匹配的解决方案有效(如果你真的不能将 bar
更改为比 Any
更具体的任何内容,则可以使用),但它不是一个合适的 'Scala way' 如果您可以控制 Foo
.
更好的方法是使 Foo 通用:
case class Foo[T](bar: T)
并且有一个通用的 doSomething
,如果它可以与任何特定的 T
一起使用:
def doSomething[T](foo: Foo[T]): SomeType = ???
或者为不同的可能 T
使用不同的版本,如果它对它们有不同的反应:
def doSomethingWithString(foo: Foo[String]): SomeType = ???
def doSomethingWithInt(foo: Foo[Int]): SomeType = ???
然后就可以这样使用了:
val fooOpt = Some(Foo("bar as String"))
fooOpt.map(doSomething).orElse(doSomethingElse)
或者像这样:
val fooOptString = Some(Foo("bar as String"))
fooOptString.map(doSomethingWithString).orElse(doSomethingElse)
val fooOptInt = Some(Foo(1))
fooOptInt.map(doSomethingWithInt).orElse(doSomethingElse)
因此,在这种情况下,编译器会为您检查类型,回答:
Is it possible to check for the type of bar directly?
在许多情况下,您可以完全避免使用模式匹配,使用 map
、orElse
等方法并正确输入。这可能是这个问题的答案:
could also rewrite to use just one case