scala编程实践与选项

时间:2017-12-02 07:55:21

标签: scala scala-option

可能是我的设计存在缺陷(很可能是这样),但我一直在考虑Option中使用Scala的方式,我并不是很满意。让我们说我有3种方法可以像这样互相呼叫:

def A(): reads a file and returns something
def B(): returns something
def C(): Side effect (writes into DB)

C()来电B(),然后B()来电A()

现在,由于A()依赖于I/O操作,我必须处理异常并返回Option否则它不会编译(如果A()没有什么都归还)。当B()Option收到A()并且必须返回某些内容时,它必然会将另一个Option返回到C()。所以,你可以想象我的代码充斥着match/case Some/case None(不要总是自由地使用getOrElse())。而且,如果C()依赖于其他一些也返回Option的方法,那么您将会害怕查看C()的定义。

那么,我错过了什么吗?或者我的设计有多么有缺陷?我该如何改进呢?

2 个答案:

答案 0 :(得分:3)

match上使用case / Option时,如果您希望丢弃Option并在处理Some(...)后产生一些值,则通常很有用如果您有None,则为同一类型的不同值。 (就我个人而言,我经常发现fold对于这种情况更加清洁。)

另一方面,如果您正在通过Option,那么还有其他方法可以解决这个问题。

def a():Option[DataType] = {/*read new data or fail*/}

def b(): Optioon[DataType] = {
  ... //some setup
  a().map{ inData =>
    ... //inData is real, process it for output
  }
}
def c():Unit = {
  ... //some setup
  b().foreach{ outData =>
    ... //outData is real, write it to DB
  }
}

答案 1 :(得分:0)

  我错过了什么吗?

Option是一个设计决定,但可能还有其他决定。即,当您想要描述API返回的错误时会发生什么? Option只能告诉你两种状态,要么我已经成功读取了值,要么我失败了。但有时你真的想知道为什么你失败了。或者更重要的是,如果我返回None,是因为文件不存在还是因为我没有异常(即我没有读取文件的权限?)。

无论您选择哪种方式,通常都会处理一个或多个效果Option是表示部分函数的一种这样的效果,即该操作可能不会产生结果。正如其他人所说,使用与Option的模式匹配是一种处理它的方式,还有其他操作可以减少冗长。

例如,如果要在值存在的情况下调用操作,而在不存在的情况下调用另一个操作并且它们都具有相同的返回类型,则可以使用Option.fold

scala> val maybeValue = Some(1)
maybeValue: Some[Int] = Some(1)

scala> maybeValue.fold(0)(x => x + 1)
res0: Int = 2

一般来说,有many such combinators defined on Option和其他效果,它们在开始时可能看起来很麻烦,后来它们会在你身上成长,当你想要一个接一个地组成操作时,你会发现它们真正的力量。 / p>