2017-01-13 11 views
0

次のコードを "Scala way"にしたり、マッチさせたりするには、どのように書き換えることができますか?Scala:Option [Foo]とFooのパラメータとのパターンマッチング

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 
} 

他にもありますか?

答えて

1

これは、すべて一つの大きなパターンマッチで行うことができます

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 
} 
+0

乾杯を使用するように書き換えることができます!完璧な意味合いを持つ。そこにいくつかの簡単で簡単な解決策があるという気持ちがありました!ありがとう – Bruno

+0

btw、Fooに複数のパラメータがあった場合、それらをすべて記述することなく 'bar'をどのように選択しますか? – Bruno

+0

@Bruno他のパラメータにはアンダースコアパターンを使用してください。だから 'Some(Foo(i:Int、_、_))'のようなものは、さらに2つのパラメータを 'Foo'に追加します。 – Alec

1

が他のあり方法?

一つの大きなパッテンマッチ作品とソリューション(とあなたが本当にAnyより具体的なものにbarを変更することができない場合に使用することができます)、それはこのような状況に対処するための適切な「Scalaの道」ではないが、一般的にはFooを支配している場合です。

良い方法はfooがジェネリックにするために、次のようになります。

case class Foo[T](bar: T) 

そして、それは特定のTで動作することができれば、一般的なdoSomethingのいずれかを持っている:

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) 

、この場合には、コンパイラはに答え、あなたのための型をチェックしますバーのタイプを直接確認することは可能ですか?

そして、多くの状況で、あなたは適切なタイピングを持つなどmaporElse、などの方法を使用して、全くパターンマッチの使用を避けることができます。これは、このための答えかもしれません:

もちょうど1ケース

関連する問題