案例类中的Scala BigDecimal并强制MathContext

时间:2018-01-12 10:13:29

标签: scala functional-programming bigdecimal case-class

我正在尝试创建一个case class,其中BigDecimal作为具有特定MathContext的值(RoundUp,Precision 2)。文档说BigDecimal.mcval,所以没有简单的重新分配。所以我想出了两个解决方案。首先是这个

case class Test(number: BigDecimal)

object Test {
    def apply(n) = new Test(n, new java.math.MathContext(2))
} 

我不喜欢那个,因为它可以使用new关键字进行环游。

case class Test(var number: BigDecimal){
    number = BigDecimal(number.toString, new java.math.MathContext(2))
}

第二个有效,但是很丑陋,并产生额外的开销。我只是想知道我是否忽略了一些简单而优雅的东西。

2 个答案:

答案 0 :(得分:1)

import scala.languageFeature.implicitConversions
import java.math.{MathContext, BigDecimal}

trait BigDecimalSpecial {
  def specialValue: BigDecimal
  def mathContext: MathContext
}

object BigDecimalSpecial {

  case class BigDecimalSpecial1(bd: BigDecimal) extends BigDecimalSpecial {
    val mathContext = new MathContext(2)
    val specialValue = new BigDecimal(bd.toString(), mathContext)
  }

  implicit def toBigDecimalSpecial1(bd: BigDecimal): BigDecimalSpecial = BigDecimalSpecial1(bd)

}

import BigDecimalSpecial._

val b = new BigDecimal("2.353453")
// b: java.math.BigDecimal = 2.353453

val forced = b.specialValue
// forced: java.math.BigDecimal = 2.4

答案 1 :(得分:0)

如何将构造函数设为私有,从而迫使每个人都使用apply

// constructor is private - use apply instead!
case class MyBigDecimal private(number: BigDecimal)

object MyBigDecimal {
  private val defaultContext = new java.math.MathContext(2)

  def apply(number: BigDecimal) = new MyBigDecimal(BigDecimal(number.bigDecimal, defaultContext))
}

另外你的第二个例子可能会被重写为丑陋而不是那么低效:

case class MyBigDecimalWithVar(var number: BigDecimal) {
  number = BigDecimal(number.bigDecimal, new java.math.MathContext(2))
}