到处使用 Option 感觉有点尴尬。我做错了什么吗?
由于我读到了有关 Option
类的文章,它可以帮助您避免 NullPointerException,因此我开始在各处使用它。想象一下这样的事情:
var file:Option[File] = None
后来当我使用它时:
val actualFile = file.getOrElse(new File("nonexisting"))
if(actualFile.getName.equals("nonexisting")) { // instead of null checking
}
else { // value of file was good
}
做这样的事情对我来说并不那么“正确”。我还注意到 .get
已被弃用。 。你们也在用Option做这种事情吗,还是我走错了路?
As a result of articles I read about the Option
class which helps you avoid NullPointerException's, I started to use it all over the place. Imagine something like this:
var file:Option[File] = None
and later when I use it:
val actualFile = file.getOrElse(new File("nonexisting"))
if(actualFile.getName.equals("nonexisting")) { // instead of null checking
}
else { // value of file was good
}
Doing stuff like this doesn't feel all that "right" to me. I also noticed that .get
has become deprecated. . Is this sort of stuff what you guys are doing with Option's too, or am I going the wrong way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
返回 Option 然后使用 getOrElse 生成一些表示“未找到”的哨兵值通常不是一个好主意。这就是
Option
的设计目的:表示未找到值!当与诸如
map
和foreach
之类的函数式编程结构结合使用时,Option
真正显示了其强大功能。当处理多个选项时,这是最有效的。例如,假设我编写一个方法,它接受一个字符串并返回一个文件,但前提是该文件存在并且是文件而不是目录:到目前为止,使用
null
更容易 - 在至少直到你忘记这可能会给你null
并且你得到一个 NPE。无论如何,现在让我们尝试使用它。看看发生了什么!在前一种情况下,我们必须手动进行逻辑测试并创建临时变量。啊!在第二种情况下,
map
为我们做了所有脏活:None被映射到None,Some(file)
被映射到Some(fileinputstream)< /代码>。简单的!
但情况还在变得更好。也许我们想要找到一大堆文件的大小:
等等,这里发生了什么 - 所有的
None
怎么样?难道我们不应该引起重视并采取一些措施吗?好吧,这就是flatMap
的用武之地:它将所有答案连接到一个列表中。None
是长度为零的答案,因此它会忽略它。Some(f)
有一个答案 -f
- 因此它将其放入列表中。然后我们使用折叠将所有长度相加——现在列表中的所有元素都是有效的。相当不错!It's generally not a good idea to return
Option
and then usegetOrElse
to produce some sentinel value that means "not found". That's whatOption
is designed for: to signify that a value is not found!Option
really shows its power when used in conjunction with functional programming constructs likemap
andforeach
. This is most potent when dealing with multiple options. For example, suppose I write a method that takes a string and gives me back a file, but only if the file exists and is a file not a directory:So far, using
null
is easier--at least until you forget that this might give younull
and you get a NPE. Anyway, let's now try to use it.Look what happened! In the former case, we had to do logic tests by hand and create temporary variables. Ugh! In the second case,
map
did all the dirty work for us: None was mapped to None, andSome(file)
was mapped toSome(fileinputstream)
. Easy!But it gets better yet. Maybe we want to find the size of a whole bunch of files:
Wait, what is going on here--what about all the
None
? Don't we have to pay attention and handle them somehow? Well, that's whereflatMap
comes in: it joins together all the answers into a single list.None
is an answer of length zero, so it ignores it.Some(f)
has one answer--f
--so it puts it in the list. Then we use a fold to add up all the lengths--now that all the elements in the list are valid. Pretty nice!最好不解析
Option
的值,而是应用逻辑到它包含的任何内容:基本上,这会处理一个
>File
如果找到并且不执行任何操作(并且相当于 Thomas 的第一个for
理解,因为for
编译为对foreach< 的调用/代码>)。它是更简洁的版本:
更重要的是,它的伟大之处在于您可以链接操作,例如:
It's a good idea to not resolve the value of the
Option
, but to apply logic to whatever is it contains:Basically this processes a
File
if one is found and does nothing otherwise (and is equivalent to Thomas' firstfor
comprehension becausefor
compiles to a call toforeach
). It is a more concise version of:What's more, the great thing about this is that you can chain operations, something like:
在大多数情况下,您会使用模式匹配
如果您只对文件感兴趣,如果它在那里,您可以使用 for 表达式
然后您可以链接表达式以在容器上的多个级别上工作
或者您可以使用 isDefined 和 get:
get is Scala 2.8.0.Beta-1 中未弃用。
In most cases you would use pattern matching
If you're only interested in the file if it is there you can use a for expression
You can then chain for expressions to work on multiple levels on containers
Alternatively you can use isDefined and get:
get is not deprecated in Scala 2.8.0.Beta-1.
这里有一个替代方案:
但是,如果您需要在文件存在时执行某些操作,如果文件不存在则执行其他操作,则
match
语句更合适:这与
if 几乎相同
语句,但我更喜欢它的链接性质,对于像Option
这样的东西,我也想提取一个值。Here's an alternative:
However, if you need to do something if the file exists, and something else if it does not, a
match
statement is more appropriate:That's pretty much the same as an
if
statement, but I like it's chaining nature better for things likeOption
, where I want to extract a value as well.主要是重申每个人都在说的话,但我认为当你有一个像这样的可为 null 的 var 时,你至少会遇到 4 种不同的情况:
1. 文件不能为 null
当你尝试实际使用该文件时会抛出异常。快速失败,耶!
2. 文件为空,但在这种情况下我们有一个合理的默认值:
3、根据文件是否存在的两个逻辑分支:
4. 如果文件为空,则不执行任何操作,也称为静默失败。我不认为在现实生活中这对我来说通常是更可取的:
或者,也许更清楚?
Mostly restating what everyone is saying, but I think there's at least 4 different situations you will encounter when you have a nullable var like this:
1. The file must not be null
Will throw an exception when you try to actually use the file. Fail fast, yay!
2. The file is null, but in this case we have a sensible default:
3. Two branches of logic based on whether the file exists:
4. No-op if the file is null, aka silently fail. I don't think this one is very often preferable for me in real life:
Or, maybe more clearly?