Scala:如何检查是否至少定义了一个类的一个字段?

时间:2015-08-19 00:23:04

标签: scala reflection field optional

我有一个类,它有几个可选字段,如下所示:

class Container(f1: Option[String] = None,
                f2: Option[Boolean] = None,
                f3: Option[Int] = None,
                f4: Option[String] = None
                // ... 30 other fields which is unfortunate/terrible and
                // cannot be changed at the moment
                 ) {
  def hasAtleastOneDefinedField: Boolean = {
    this.f1.isDefined ||
      this.f2.isDefined ||
      this.f3.isDefined ||
      this.f4.isDefined
    // this is too-much of boilerplate
  }

  // This is something along the lines of what I want
  def hasAtleastOneDefinedField2: Boolean = {
    // this.getAllDeclaredFields.find(field => field.value.isDefined)
    ???
  }
}

不使用反射可以做同样的事吗?

3 个答案:

答案 0 :(得分:3)

不确定这可以节省多少,但是:

  val hasAtLeastOneDefinedField = List(f1, f2, f3, ..., f35).exists { _.isDefined }

不要认为还有另一种方法没有反思/宏。

答案 1 :(得分:2)

只是一个想法,但根据您的预期用途,可能有值得考虑的设计模式可以使您的意图更清晰。

例如,如果您要确定是否有足够的数据来构造某些内容,那么一个选项就是构建器模式,例如:

if (removeNum >= 0 && removeNum < cusList.size()) { 
    custList.remove(removeNum);
}else{
    System.out.println("Index out of bounds, " + removeNum + " >= " + custList.size());
}

如果你只允许以这种方式构建Container实例(例如,Container类&#39;构造函数只对构建器可见),你可以确定它们只有一个字段集(有多种方法可以扩展它以生成具有多个字段集的容器,例如见下文。

这可以扩展到,例如,确保在创建Container之前设置两个,三个......所有字段。例如:

object ContainerBuilder() {
  def fromF1(f1: F1) = Container(f1 = Some(f1))
  def fromF2(f2: F2) = Container(f2 = Some(f2))
  ...
}

答案 2 :(得分:0)

更多表达方式:

val o1 = None
val o2 = None
val o3 = Option("o")

o1.orElse(o2).orElse(o3).isDefined

List(o1, o2, o3).flatten.nonEmpty