Scala中的可选布尔参数
我最近一直在开发基于ApachePOI功能的DSL风格的库包装器,并面临着一个我似乎不是很好的解决方案的挑战 该库的目标之一是为用户提供将电子表格模型构建为不可变对象集合的能力,即Scala中的可选布尔参数,scala,Scala,我最近一直在开发基于ApachePOI功能的DSL风格的库包装器,并面临着一个我似乎不是很好的解决方案的挑战 该库的目标之一是为用户提供将电子表格模型构建为不可变对象集合的能力,即 val headerStyle=CellStyle(fillPattern=CellFill.Solid,fillForegroundColor=Color.AquaMarine,font=font(bold=true)) val italicStyle=CellStyle(font=font(italic=true
val headerStyle=CellStyle(fillPattern=CellFill.Solid,fillForegroundColor=Color.AquaMarine,font=font(bold=true))
val italicStyle=CellStyle(font=font(italic=true))
根据以下假设:
- 用户可以选择指定任何参数(也就是说,您可以创建不带参数的
,也可以使用明确指定的参数的完整列表)李>CellStyle
- 如果用户未明确指定参数,则认为该参数未定义,将使用默认环境值(我们转换为的格式的默认值)李>
bold=true
的界面,我决定使用接受空值的Java包装器
object ModelObject {
def apply(boolParam : java.lang.Boolean = null) : ModelObject = ModelObject(
boolParam = Option(boolParam).map(_.booleanValue)
)
}
case class ModelObject private(boolParam : Option[Boolean])
然而,这是不对的,我一直在想是否有更好的方法来解决这个问题。我一直在考虑定义联合类型(使用其他对象表示未定义的值):,但是,由于未定义状态不应该显式地用于IDE向用户公开的参数类型,这将非常容易混淆(理想情况下,我希望它是布尔型的)
有没有更好的办法解决这个问题
进一步资料:
- 更多DSL API示例:
- 完整类的示例实现:
选项
)
您可以这样简单地使用它:
scala>case class ModelObject(boolParam: OptArg[Boolean] = NoArg)
defined class ModelObject
scala> ModelObject(true)
res12: ModelObject = ModelObject(SomeArg(true))
scala> ModelObject()
res13: ModelObject = ModelObject(NoArg)
但是,正如您所看到的,OptArg
现在泄漏在ModelObject
类本身中(boolParam
被键入为Option[Boolean]
)。
解决这个问题(如果对您很重要)只需要像您自己一样定义一个单独的工厂:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class ModelObject private(boolParam: Option[Boolean])
object ModelObject {
def apply(boolParam: OptArg[Boolean] = NoArg): ModelObject = new ModelObject(
boolParam = boolParam.toOption
)
}
// Exiting paste mode, now interpreting.
defined class ModelObject
defined module ModelObject
scala> ModelObject(true)
res22: ModelObject = ModelObject(Some(true))
scala> ModelObject()
res23: ModelObject = ModelObject(None)
UPDATE与@drexin所示的简单定义几个重载的
apply
方法相比,使用此模式的优势在于,在后一种情况下,重载的数量随着参数的数量快速增长(2^N)。如果ModelObject
有4个参数,这意味着需要手动写入16个重载!您可以使用我在这里描述的模式的变体:
总之,您可以使用一些helper泛型类来表示可选参数(很像选项
)
您可以这样简单地使用它:
scala>case class ModelObject(boolParam: OptArg[Boolean] = NoArg)
defined class ModelObject
scala> ModelObject(true)
res12: ModelObject = ModelObject(SomeArg(true))
scala> ModelObject()
res13: ModelObject = ModelObject(NoArg)
但是,正如您所看到的,OptArg
现在泄漏在ModelObject
类本身中(boolParam
被键入为Option[Boolean]
)。
解决这个问题(如果对您很重要)只需要像您自己一样定义一个单独的工厂:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class ModelObject private(boolParam: Option[Boolean])
object ModelObject {
def apply(boolParam: OptArg[Boolean] = NoArg): ModelObject = new ModelObject(
boolParam = boolParam.toOption
)
}
// Exiting paste mode, now interpreting.
defined class ModelObject
defined module ModelObject
scala> ModelObject(true)
res22: ModelObject = ModelObject(Some(true))
scala> ModelObject()
res23: ModelObject = ModelObject(None)
UPDATE与@drexin所示的简单定义几个重载的
apply
方法相比,使用此模式的优势在于,在后一种情况下,重载的数量随着参数的数量快速增长(2^N)。如果ModelObject
有4个参数,这意味着需要手动写入16个重载!您可以使用我在这里描述的模式的变体:
总之,您可以使用一些helper泛型类来表示可选参数(很像选项
)
您可以这样简单地使用它:
scala>case class ModelObject(boolParam: OptArg[Boolean] = NoArg)
defined class ModelObject
scala> ModelObject(true)
res12: ModelObject = ModelObject(SomeArg(true))
scala> ModelObject()
res13: ModelObject = ModelObject(NoArg)
但是,正如您所看到的,OptArg
现在泄漏在ModelObject
类本身中(boolParam
被键入为Option[Boolean]
)。
解决这个问题(如果对您很重要)只需要像您自己一样定义一个单独的工厂:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class ModelObject private(boolParam: Option[Boolean])
object ModelObject {
def apply(boolParam: OptArg[Boolean] = NoArg): ModelObject = new ModelObject(
boolParam = boolParam.toOption
)
}
// Exiting paste mode, now interpreting.
defined class ModelObject
defined module ModelObject
scala> ModelObject(true)
res22: ModelObject = ModelObject(Some(true))
scala> ModelObject()
res23: ModelObject = ModelObject(None)
UPDATE与@drexin所示的简单定义几个重载的
apply
方法相比,使用此模式的优势在于,在后一种情况下,重载的数量随着参数的数量快速增长(2^N)。如果ModelObject
有4个参数,这意味着需要手动写入16个重载!您可以使用我在这里描述的模式的变体:
总之,您可以使用一些helper泛型类来表示可选参数(很像选项
)
您可以这样简单地使用它:
scala>case class ModelObject(boolParam: OptArg[Boolean] = NoArg)
defined class ModelObject
scala> ModelObject(true)
res12: ModelObject = ModelObject(SomeArg(true))
scala> ModelObject()
res13: ModelObject = ModelObject(NoArg)
但是,正如您所看到的,OptArg
现在泄漏在ModelObject
类本身中(boolParam
被键入为Option[Boolean]
)。
解决这个问题(如果对您很重要)只需要像您自己一样定义一个单独的工厂:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class ModelObject private(boolParam: Option[Boolean])
object ModelObject {
def apply(boolParam: OptArg[Boolean] = NoArg): ModelObject = new ModelObject(
boolParam = boolParam.toOption
)
}
// Exiting paste mode, now interpreting.
defined class ModelObject
defined module ModelObject
scala> ModelObject(true)
res22: ModelObject = ModelObject(Some(true))
scala> ModelObject()
res23: ModelObject = ModelObject(None)
更新使用此模式的优点,与简单地定义几个重载的apply
方法相比