0

Background

I'm using a java web UI library (Vaadin, but that's irrelevant - I'm not using the Scaladin add-on) which has a TextField that has a method setValue(String) to set the current text value.

As it's a java library, it has no notion of Option but can represent a null value as e.g. an empty string (it's configurable). So I've written an implicit wrapper class as follows:

implicit class ExtendedTextField(self: TextField) {
    def :=(value: String) = self.setValue(value)
    def :=(maybeValue: Option[String]) = self.setValue(maybeValue.orNull)
}

This allows me to set the value using the := operator directly on a TextField instance and allows me to deal with the Option to null conversion in a single place.

Problem

When I have e.g. a form with a bunch of text fields showing the values for some object of type X, then if I have an Option[X] I'm doing this:

fieldA := (for (x <- maybeX) yield x.valueA)
fieldB := (for (x <- maybeX) yield x.valueB)
fieldC := (for (x <- maybeX) yield x.valueC)
...

In other words, I want to call the := with Some(string) in case I have maybeX is Some but with None if maybeX is none. In addition, suppose x.valueD is actually an Option[String], I would call

fieldD := (for (x <- maybeX) yield x.valueD).flatten

(I could simply always call flatten, but it wouldn't have an effect if there are no nested options)

Is there a nicer way to write this, getting rid of all the duplicate for comprehensions and flattening the result? Maybe using a macro?

I'd prefer not to use reflection (I'm sure it will be possible to put all the fields in a sequence, zip it with a sequence containing the property names, then map this using a function that returns None or does the relflection lookup, and also flattens the result).

4

1 回答 1

2

这几乎是紧凑的,因为它是一组不同的地图变换,如果它有一个值,你想要执行它。map您可能会使用而不是 for 理解来缩短它:

fieldA := x.map(_.valueA)
fieldB := x.map(_.valueB)
fieldC := x.map(_.valueC)

对于您而言,x 内部的选项flatMap可以得到与 map + flatten 相同的结果:

fieldD := x.flatMap(_.valueD)

您也许可以创建一个宏来执行此操作,但是您将用这种重复与您的代码难以理解的程度进行权衡,并且收益可能会很小。

于 2014-09-14T16:41:00.117 回答