背景
我正在使用一个java web UI库(Vaadin,但这不相关 - 我没有使用Scaladin插件),其中TextField
有一个方法setValue(String)
来设置当前文本值。
由于它是一个java库,它没有Option
的概念,但可以表示null
值,例如implicit class ExtendedTextField(self: TextField) {
def :=(value: String) = self.setValue(value)
def :=(maybeValue: Option[String]) = self.setValue(maybeValue.orNull)
}
。一个空字符串(它是可配置的)。所以我编写了一个隐式包装类,如下所示:
:=
这允许我直接在TextField实例上使用fieldA := (for (x <- maybeX) yield x.valueA)
fieldB := (for (x <- maybeX) yield x.valueB)
fieldC := (for (x <- maybeX) yield x.valueC)
...
运算符设置值,并允许我在一个地方处理Option to null转换。
问题
当我有例如一个带有一堆文本字段的表单,显示某个X类型对象的值,如果我有一个Option [X],我就是这样做的:
:=
换句话说,我想用Some(字符串)调用fieldD := (for (x <- maybeX) yield x.valueD).flatten
,以防我有可能是一些但是如果MaybeX是none则使用None。另外,假设x.valueD实际上是一个Option [String],我会调用
flatten
(我可以随时调用{{1}},但如果没有嵌套选项则不会产生效果)
有没有更好的方法来写这个,摆脱所有重复的理解和扁平化的结果?也许使用宏?
我不想使用反射(我确信可以将所有字段放在一个序列中,用包含属性名称的序列压缩它,然后使用返回None或者函数的函数映射它relflection查找,并使结果变平。)
答案 0 :(得分:2)
这是一样紧凑,因为它是一组你想要执行的不同地图变换,如果它有一个值。你可以用map
而不是理解来缩短它:
fieldA := x.map(_.valueA)
fieldB := x.map(_.valueB)
fieldC := x.map(_.valueC)
并且对于x flatMap
内部选项的情况,它可以获得与map + flatten相同的结果:
fieldD := x.flatMap(_.valueD)
您可以创建一个执行此操作的宏,但您将根据代码的理解程度进行交易,并且获得的收益可能非常小。