为什么使用foreach
,map
,flatMap
等被认为比使用get
进行Scala选项更好?如果我使用isEmpty
,我可以安全地致电get
。
答案 0 :(得分:75)
嗯,有点回到“告诉,不要问”。请考虑以下两行:
if (opt.isDefined) println(opt.get)
// versus
opt foreach println
在第一种情况下,您正在查看opt
内部,然后根据您所看到的情况做出反应。在第二种情况下,您只是告诉opt
您想要做什么,并让它处理它。
第一种情况对Option
了解太多,复制内部逻辑,脆弱且容易出错(如果写错了,可能导致运行时错误,而不是编译时错误)。
除此之外,它不可组合。如果你有三个选项,一个理解就可以解决它们:
for {
op1 <- opt1
op2 <- opt2
op3 <- opt3
} println(op1+op2+op3)
if
,事情开始变得混乱。
答案 1 :(得分:21)
使用foreach
的一个很好的理由是使用嵌套选项解析某些东西。如果您有类似
val nestedOption = Some(Some(Some(1)))
for {
opt1 <- nestedOption
opt2 <- opt1
opt3 <- opt2
} println(opt3)
控制台打印1
。如果你将这个扩展到一个类,你可以选择存储对某个东西的引用,然后存储另一个引用,为了理解,你可以避免使用None / Some check的巨大“金字塔”。
答案 2 :(得分:17)
对于实际问题已经有了很好的答案,但是对于更多Option
- foo,你一定要查看Tony Morris' Option Cheat Sheet。
答案 3 :(得分:6)
将map
,foreach
和flatMap
等内容直接应用于Option
而非使用get
然后执行功能是它适用于Some
或 None
,您无需进行特殊检查以确保值存在。
val x: Option[Int] = foo()
val y = x.map(_+1) // works fine for None
val z = x.get + 1 // doesn't work if x is None
这里y
的结果是Option[Int]
,这是可取的,因为如果x
是可选的,那么y
也可能不确定。由于get
不适用于None
,因此您必须做一些额外的工作以确保您没有收到任何错误;由map
为您完成的额外工作。
答案 4 :(得分:2)
简单地说:
如果您需要做某事(当您不需要捕获每次调用的返回值时的过程),只有定义了该选项(即Some
):use {{ 1}}(如果您关心每次调用的结果,请使用foreach
)
如果您定义了选项,则需要执行某些操作,如果不是,则需要执行其他操作:在if语句中使用map
如果选项是isDefined
,则需要值;如果是Some
,则需要默认值:使用None
答案 5 :(得分:0)
尝试使用Options
执行我们的操作更为必要的风格,您需要tel 做什么以及如何做。换句话说,我们正在指挥事物并进一步深入map,flatmap
内部。其中module delay_one_cycle(
input clk,
input[3:0] original_signal,
output reg[3:0] delayed_signal
);
always @(posedge clk) begin
delayed_signal <= original_signal;
end
endmodule
module delay_one_cycle_tb();
reg clk;
reg[3:0] original_signal;
wire[3:0] delayed_signal;
delay_one_cycle doc_inst (clk, original_signal, delayed_signal);
// Initial setup
initial begin
clk = 0;
original_signal = 4'd9;
#5 original_signal = 4'd10;
#5 original_signal = 4'd11;
#4 original_signal = 4'd12;
#3 original_signal = 4'd13;
// finish the simulation
#5 $finish;
end
// clock
always begin
#1 clk = !clk;
end
endmodule
是更具功能性的做事方式,我们说该做什么但不做怎么做。