(Scala) 我是否正确使用了选项? [英] (Scala) Am I using Options correctly?
问题描述
我目前正在研究我的函数式编程 - 我对它相当陌生.我在这里正确使用选项吗?我目前对自己的技能感到非常不安全.我希望我的代码尽可能安全 - 任何人都可以指出我在这里做错了什么还是没有那么糟糕?我的代码在这里非常简单:
I'm currently working on my functional programming - I am fairly new to it. Am i using Options correctly here? I feel pretty insecure on my skills currently. I want my code to be as safe as possible - Can any one point out what am I doing wrong here or is it not that bad? My code is pretty straight forward here:
def main(args: Array[String]): Unit =
{
val file = "myFile.txt"
val myGame = Game(file) //I have my game that returns an Option here
if(myGame.isDefined) //Check if I indeed past a .txt file
{
val solutions = myGame.get.getAllSolutions() //This returns options as well
if(solutions.isDefined) //Is it possible to solve the puzzle(crossword)
{
for(i <- solutions.get){ //print all solutions to the crossword
i.solvedCrossword foreach println
}
}
}
}
-谢谢!!^^
推荐答案
根据经验,您可以将 Option
视为 Java 空指针的替代品.也就是说,如果您可能想在 Java 中使用 null
,在 Scala 中使用 Option
通常是有意义的.
As a rule of thumb, you can think of Option
as a replacement for Java's null pointer. That is, in cases where you might want to use null
in Java, it often makes sense to use Option
in Scala.
您的 Game()
函数使用 None
来表示错误.所以你并没有真正使用它作为 null
的替代品(至少我认为等效的 Java 方法在那里返回 null
而不是抛出一个例外),但作为例外的替代品.这不是 Option
的好用法,因为它会丢失错误信息:您无法再区分文件不存在、文件格式错误或其他类型的错误.
Your Game()
function uses None
to represent errors. So you're not really using it as a replacement for null
(at least I'd consider it poor practice for an equivalent Java method to return null
there instead of throwing an exception), but as a replacement for exceptions. That's not a good use of Option
because it loses error information: you can no longer differentiate between the file not existing, the file being in the wrong format or other types of errors.
相反,您应该使用 Either
.Either
由情况 Left
和 Right
组成,其中 Right
就像 Option
Some
,但Left
与None
的不同之处在于它也接受一个参数.在这里,该参数可用于存储有关错误的信息.因此,您可以创建一个包含可能的错误类型的案例类,并将其用作 Left
的参数.或者,如果您从不需要以不同方式处理错误,而只是将它们呈现给用户,您可以使用带有错误消息的字符串作为 Left
的参数,而不是案例类.
Instead you should use Either
. Either
consists of the cases Left
and Right
where Right
is like Option
's Some
, but Left
differs from None
in that it also takes an argument. Here that argument can be used to store information about the error. So you can create a case class containing the possible types of errors and use that as an argument to Left
. Or, if you never need to handle the errors differently, but just present them to the user, you can use a string with the error message as the argument to Left
instead of case classes.
在getAllSolutions
中,您只是使用None
作为空列表的替代.这是不必要的,因为空列表不需要替换.当没有解决方案时,只返回一个空列表是完全没问题的.
In getAllSolutions
you're just using None
as a replacement for the empty list. That's unnecessary because the empty list needs no replacement. It's perfectly fine to just return an empty list when there are no solutions.
当涉及到与 Option
的交互时,您使用的是 isDefined
+ get
,这有点反模式.get
可以用作快捷方式,如果您知道您拥有的选项从不None
,但通常应避免使用.isDefined
一般只用于需要知道选项是否包含值,但不需要知道值的情况.
When it comes to interacting with the Option
s, you're using isDefined
+ get
, which is a bit of an anti pattern. get
can be used as a shortcut if you know that the option you have is never None
, but should generally be avoided. isDefined
should generally only be used in situations where you need to know whether an option contains a value, but don't need to know the value.
如果您需要知道是否有值以及该值是什么,您应该使用模式匹配或 Option
的高阶函数之一,例如 map
、flatMap
、getOrElse
(如果你眯着眼睛考虑按名称参数,这是一种高阶函数职能).如果您想对存在的值执行某些操作,否则什么都不做,您可以使用 foreach
(或等效的 for
循环),但请注意在这里的错误情况下真的不应该做任何事情.您应该将错误告诉用户.
In cases where you need to know both whether there is a value and what that value is, you should either use pattern matching or one of Option
's higher-order functions, such as map
, flatMap
, getOrElse
(which is kind of a higher-order function if you squint a bit and consider by-name arguments as kind-of like functions). For cases where you want to do something with the value if there is one and do nothing otherwise, you can use foreach
(or equivalently a for
loop), but note that you really shouldn't do nothing in the error case here. You should tell the user about the error instead.
这篇关于(Scala) 我是否正确使用了选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!