正如其他地方指出的,您可以简单地使用
Option
的
orElse
方法:
val default: ProductAttributes = ???
def applyDefaults(pa: ProductAttributes): ProductAttributes =
ProductAttributes(
price = pa.price.orElse(default.price),
locationId = pa.locationId.orElse(default.locationId),
colorCount = pa.colorCount.orElse(default.colorCount)
)
但问题是:这真的是一个有用的函数吗?因为一旦调用了它,您可能希望以某种方式利用所有值现在都已定义的事实。但是怎么做呢?你可以打电话
.get
在那些上面
选项
s、 但是如果你忘了打电话,你的程序就会崩溃
applyDefaults
。或者您可以使用“安全”方法,如
getOrElse(xxx)
,那么你打算在那里放什么而不是
xxx
? 不管你放在那里,它都是死代码,因为你已经应用了默认值。
这里的问题是,函数签名并不能表示函数的功能:它会使可选性消失。纠正这种情况的一种方法是将类型参数添加到
ProductAttributes
它告诉您这些值是否为可选值:
case class ProductAttributes[F[_]](
price: F[Int],
localtionId: F[Int],
colorCount: F[Int])
type Id[A] = A
val default = ProductAttributes[Id](20, 17, 3)
def applyDefaults(pa: ProductAttributes[Option]): ProductAttributes[Id] =
ProductAttributes[Id](
price = pa.price.getOrElse(default.price),
locationId = pa.locationId.getOrElse(default.locationId),
colorCount = pa.colorCount.getOrElse(default.colorCount)
)
签名现在告诉读者函数的作用:它需要
ProductAttributes产品属性
并返回一个包含非可选字段的字段。然后,您可以在以后执行任何必要的逻辑,而不会有崩溃的风险(因为
收到
)或者写死代码。