2014-11-14 45 views
3

我有多少函數對操縱資源,例如功能:Scala的選項的一些/無成語該返回單元

def loadFile(name: String): Option[String] 
def writeFile(name: String, data: String): ??? 

的loadFile目前實現使用選項的一些/無返回所得字符串但writeFile

的loadFile,如果WriteFile的失敗,我想它返回封裝在一個不錯的嘗試或選項的應答,而不是拋出一個異常或返回空值,布爾,或響應代碼。

什麼是一些推薦的最佳實踐?

def writeFile(name: String, data: String): Try(Unit) 

def writeFile(name: String, data: String): Option(Unit) 

,只是測試成功標誌?

什麼是最好的scala-thonic方法來處理這個問題?

+0

如果你不關心成功的結果(除了成功),但是關心錯誤的結果(例外),那麼我肯定會贊成'嘗試[單位]'在'選項[單位]'。 – 2014-11-14 20:20:44

+0

不要忘記'要麼',要麼! – 2014-11-14 20:35:49

+0

選項[例外]將是我的解決方案 – 2014-11-14 21:00:30

回答

3

其他的答案這裏是幾乎一樣Try[Unit],但需要一點點更多的樣板。這是一樣簡單,因爲它得到(直譯加3個字母,以你的函數定義):

def writeFile(name: String, data: String): Try[Unit] = Try { 
    // do write operation that may throw an exception 
} 

Try的巨大優勢是,它是一個單子,讓你能夠mapflatMap它(其他中事情)輕鬆地將多個Try操作合成一個。假設您需要一起執行這些操作中的3項,並返回Unit或第一個Exception

val result: Try[Unit] = for { 
    a <- writeFile(name1, data1) 
    b <- writeFile(name2, data2) 
    c <- writeFile(name3, data3) 
} yield() 

您可以匹配結果:

result match { 
    case Success(_) => println("Success!") 
    case Failure(t) => println(s"Failure! {t.getMessage}") 
} 

您也有一些其他的強大組合子功能如API docs看到。

您還可以編寫更通用的重試失敗方法,如this post的最後一段代碼所示。

1

我已經採用了過去看起來像這樣的方法。

trait Result 
case object Success extends Result 
case class Error(errorReason: String) extends Result 

def writeFile(name: String): Result 

它與模式匹配範例非常相稱。

def writeFileWithRetry(name: String)(numRetries: Int = 2): Result = { 
    writeFile(name) match { 
    case e: Error => 
     LOG.errorLog(s"Could not write $name: ${e.errorReason}") 
     if (numRetries <= 0) e else writeFileWithRetry(name)(numRetries - 1) 
    case r => r 
    } 
} 
0
def writeFile(name: String, data: String): Either[Exception, Unit] = try { 
     doWrite(name, data) 
     Right(()) 
    } catch { 
    case ex => Left(ex) 
    } 

    writeFile("foo", "bar") match { 
     case Left(ex) => println("Failed with exception: " + ex) 
     case _ => println("Success!") 
    }