2015-09-04 62 views
1

我有很多的模式匹配代碼如下所示:如果某些Foo的比賽中,Bar一個Some返回,否則None,並且有很多Foos和長構造函數Bars。例如:要從模式匹配中返回Option,請使用Try?

y match { 
    case Foo1(z) => Some(Bar1(z)) 
    case Foo2(z) => Some(Bar2(z)) 
    case Foo3(z) => Some(Bar3(z)) 
    case Foo4(z) => Some(Bar4(z)) 
    case _ => None 
} 

在實際的代碼中,箭頭右側的構造函數更復雜,並且有更多的情況。現在

,爲了擺脫重複的選項構造函數(Some),我可以這樣做:

Try( 
    y match { 
    case Foo1(z) => Bar1(z) 
    case Foo2(z) => Bar2(z) 
    case Foo3(z) => Bar3(z) 
    case Foo4(z) => Bar4(z) 
    } 
).toOption 

這看起來顯著清潔劑給我,並從語義的角度來看,這是合理的,因爲case _實際上是不應該發生的情況,因此將其視爲例外似乎是合理的。請注意,這是重複性的Somes錯誤我,而不是最後case

我的問題是,是否有一些(例如表現)懲罰後一種方法,我不知道。

回答

9

第二個版本的可讀性較差,而且不太正確*。使用Try沒有太大的意義,如果你只是想拋棄錯誤NoneTry只有那裏捕捉匹配錯誤,並將它們轉換爲None,但你可以用case _ => None這樣做。

Try會有稍微更多的開銷環繞,但不夠重要。正確性和可讀性應該是第一位的。

如果你真的不想有額外的情況下,可以考慮在Option包裝y和使用collect

Option(y) collect { 
    case Foo1(z) => Bar1(z) 
    case Foo2(z) => Bar2(z) 
    case Foo3(z) => Bar3(z) 
    case Foo4(z) => Bar4(z) 
} 

Option使用collect將包裝的情況下,在部分功能是在Some中定義,任何不匹配的情況將變爲None


*通過正確,我的意思是被廣泛接受的使用Try

+0

我的重點是可讀性(這不像聽起來那麼客觀),它是額外的一些我覺得分散注意力的東西,而不是最後一種情況。你的版本會處理無與倫比的情況嗎?如果是這樣,我覺得它是一個非常好的解決方案。我看到你關於Try的觀點。 – DCS

+0

我關於可讀性的觀點是,在'Try'中包裝'match'會掩蓋它的目的,是的。我會更詳細地編輯。 –