2017-03-22 6 views
3

この関数であり、それは空の文字列との別々の残りの部分を排除しない私は、引数Scalaの場合パターンマッチ誤差[文字列]

def foo(args: String*) 

の可変数を持つ関数を作成しようとしています文字列はカンマ(,)です。

私は Option[String]引数

def foo(args: Any*) = { 
    args.flatMap { 
    case str: String if str.isEmpty => None 
    case str: Option[String] if str.getOrElse("").isEmpty => None 
    case str => Some(str) 
    }.mkString(", ") 
} 

をサポートするために、この機能を拡張したとき、私は私が得た

warning: non-variable type argument String in type pattern Option[String] is unchecked since it is eliminated by erasure

そして、私は引数を渡す

foo("", "Hello", Some(""), Some("what")) 

を言って警告を得た

def foo(args: String*) = { 
    args.flatMap { 
    case str if str.isEmpty => None 
    case str => Some(str) 
    }.mkString(", ") 
} 

エラー

scala.MatchError: Some(what) (of class scala.Some) at $anonfun$makeAddress$1.apply(:12) at $anonfun$makeAddress$1.apply(:12)

どのように私もOption[String]をサポートするような関数を作成する必要がありますか?

+0

https://gist.github.com/fahadsiddiqui/b530a093a643f489a9a661606d479f30という解決策がありますが、最適な解決策があるかどうか教えてください。 –

+0

また、https://stackoverflow.com/questions/16056645/how-to-pattern-match-on-generic-type-in​​-scala – danielnixon

+0

「Any」を使用することは強いコードの匂いです。これは[Type Hierarchy ](docs.scala-lang.org/tutorials/tour/unified...)。その結果、タイプがその広さを考慮すると有用ではないので、コンパイラはあなたを助けることができません。つまり、ランタイムエラーを防ぐことはできません。 –

答えて

3

あなたはコレクトを使用し、完全オプションを避けることができます:

def foo(args: String*): String = { 
    args.collect{case s if ! s.isEmpty => s}.mkString(",") 
} 

をマップと組み合わせたフィルタの等価で収集します。

1
あなたのソリューションと同様に

def foo(args: Any*) = { 
    args.flatMap { 
    case str: String if !str.isEmpty => Option(str) 
    case Some(str:String) if !str.isEmpty => Option(str) 
    case _ => None 
    }.mkString(", ") 
} 
+0

あなたのコードには、以下のコードを使用するとバグがあります println(foo( ""、 "Hello"、Some(null)、Some( "what"))) –

+0

str)の代わりにOption(str)? –

+1

いいえ、一部の文字列(str)がパターンマッチに使用されます。問題はSome(null)!= NoneおよびOption(null)==なしです。あなたはスカラREPLで試すことができます。 –

関連する問題