我以这种方式存储错误代码及其字符串消息:
object Error {
def FileNotFound(filename: String) = Error("ERR01", s"${filename} not found")
def UserNotExist(userName: String) = Error("ERR02", s"${userName} not exist")
}
case class Error(code: String, value: String) {}
Run Code Online (Sandbox Code Playgroud)
保持这样的好处是我可以将字符串值传递给错误消息。
我正在创造它
def validate(data: SomeType): List[Error] = {
var errors = ListBuffer[Error]()
if (validation1("abc") == false) {
errors+= Error.FileNotFound("abc")
}
if (validation2("lmn") == false) {
errors+= Error.UserNotExist("lmn")
}
errors.toList
}
Run Code Online (Sandbox Code Playgroud)
我是 Scala 和函数式编程的新手。像这样编写错误代码是正确的方法吗?它是否遵循函数式编程范式?
斯卡拉:2.11
这是我的两分钱和一个完整的例子。
我假设您想以简单易用的功能风格来完成此操作,所以让我们删除可变的ListBuffer并看看如何处理它。步骤的描述在代码后面。
更新:我想指出,在您的代码中,使用ListBuffer是可以接受的,因为它不会破坏重新引用透明度。这是因为您不会在函数外部公开其可变性质,并且函数的输出仅取决于其输入。
尽管如此,如果不是出于特定原因(例如紧凑性或性能),我通常更愿意避免使用可变数据。
object StackOverflowAnswer {
/* Base type with some common fields */
class MyError( val code: String, val msg: String )
/* FileNotFound type, subtype of MyError, with its specific fields */
case class FileNotFound( filename: String ) extends MyError(
"ERR01", s"$filename not found"
)
/* UserDoesntExist type, subtype of MyError, with its specific fields */
case class UserDoesntExist( userName: String ) extends MyError(
"ERR01", s"$userName doesn't exist"
)
/*
* Validates the file. If it finds an error it returns a Some(MyError) with
* the error that's been found
* */
def checkForBadFile( data: String ): Option[MyError] =
if( data.contains("bad_file.txt") )
Some(FileNotFound("bad_file.txt"))
else
None
/*
* Validates the user. If it finds an error it returns a Some(MyError) with
* the error that's been found
* */
def checkForMissingUser( data: String ): Option[MyError] =
if( data.contains("bad_username") )
Some(UserDoesntExist("bad_username"))
else
None
/*
* Performs all the validations and returns a list with the errors.
*/
def validate( data: String ): List[MyError] = {
val fileCheck = checkForBadFile( data )
val userCheck = checkForMissingUser( data )
List( fileCheck, userCheck ).flatten
}
/* Run and test! */
def main( args: Array[String] ): Unit = {
val goodData = "This is a text"
val goodDataResult = validate( goodData ).map( _.msg )
println(s"The checks for '$goodData' returned: $goodDataResult")
val badFile = "This is a text with bad_file.txt"
val badFileResult = validate( badFile ).map( _.msg )
println(s"The checks for '$badFile' returned: $badFileResult")
val badUser = "This is a text with bad_username"
val badUserResult = validate( badUser ).map( _.msg )
println(s"The checks for '$badUser' returned: $badUserResult")
val badBoth = "This is a text with bad_file.txt and bad_username"
val badBothResult = validate( badBoth ).map( _.msg )
println(s"The checks for '$badBoth' returned: $badBothResult")
}
}
Run Code Online (Sandbox Code Playgroud)
我开始定义错误的类型结构,与您的类似。
然后我有两个函数可以对您想要的每项检查执行验证。当他们发现错误时,他们使用 Scala 的 Option 类型返回错误。如果您不熟悉 Option,可以查看此链接或进行一些谷歌搜索。
然后我有验证函数来调用并存储上述每个单项检查。最后一点是使用flatten(文档此处)“展平”List[Option[MyError]]为List[MyError],删除中间Option。
然后是向您展示一些示例的实际代码。