代码之家  ›  专栏  ›  技术社区  ›  SomeStranger314

case类中的Scala BigDecimal和强制MathContext

  •  1
  • SomeStranger314  · 技术社区  · 8 年前

    我正在尝试创建一个 case class 持有 BigDecimal 作为具有特定 MathContext (汇总,精度2)。文件上说 BigDecimal.mc 是一个 val ,因此没有简单的重新分配。所以我想出了两个解决方案。首先是这个

    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 回复  |  直到 8 年前
        1
  •  1
  •   SergGr    8 年前

    让构造函数私有化,从而强制所有人使用 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))
    }
    
        2
  •  1
  •   sarveshseri    8 年前
    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
    
    推荐文章