2017-03-22 52 views
3

我想創建一個函數的參數Scala的情況下,模式匹配錯誤[字符串]

def foo(args: String*) 

此功能對什麼是變量數,它消除了空字符串和獨立的休息帶逗號的字符串(,)。

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

當我擴展了這一功能,支持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")) 

我錯誤

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

使用'任何'是一個強大的代碼氣味 - 它是[類型層次結構](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

另外,在你的代碼中,如果你使用下面的代碼,就會出現一個bug: println(foo(「」,「Hello」,Some(null),Some(「what」))) –

+0

不應該是Some str)而不是Option(str)? –

+1

不,一些(str)主要用於模式匹配。問題是Some(null)!= None和Option(null)== None。你可以試試scala REPL。 –