对案例类值实施约束的正确方法是什么

尼古拉斯·里纳多(Nicolas Rinaudo)

通常,在构造时抛出异常并不是一件很礼貌的事情,但是我不确定在尝试对case类值施加约束时如何避免这种情况。

举例来说,我需要代表一个范围,并且两个边界都必须为正。立即实施是:

case class Range(from: Int, to: Int)

但是,这不能确保fromto都为正,也不能to大于from

我的第一个本能是按以下方式实现它:

case class Range(from: Int, to: Int) {
  require(from >= 0)
  require(to >= 0)
  require(to >= from)
}

但是,这使Range的构造函数不安全。

是否存在一种通用的模式来保持案例类的易用性,强制执行值约束并避免引发异常?

DCK王

这是非常主观的,但是我会尝试的。

这取决于您的班级的构造方式。在内部代码中随便使用一个简单的实用程序范围类的情况下,任何使用它的程序员都应该意识到,给范围错误的值可能会导致奇怪的结果。您可以假定对类的合理使用确实不会遇到此问题,并且在这些罕见的情况下引发异常可能不是一个不好的做法,以表明有人真的被搞砸了。如果从上下文可以明显看出应该将什么价值观提供给班级,我认为如果人们不能满足这些理智的期望就抛出异常并不是特别不好的口味。

将此与有时在Scala中仍然发生NullPointerExceptions或ArithmethicExceptions的行为进行比较有时,面对足够的“精神错乱”时,进行防御性编程已经不合理了。

另一方面,如果您的类被值填充,则您对它们的控制较少,即它们是用户输入的直接结果,您只需要简单地对构造进行更多控制。使用返回Option或的函数创建伴随对象Either

 object Range {
     def createSafe(from: Int, to: Int): Option[Range] = {
         if(from >= 0 && to >= 0 && to >= from)
            Some(Range(from, to))
         else
            None
     }
 }

然后,您甚至可以通过覆盖apply其他建议的答案,甚至在案例类的实例化中重用验证逻辑

 object Range {
    def createSafe ...
    def apply(from: Int, to: Int): Range = {
        createSafe(from, to).getOrElse(throw new IllegalArgumentException(...))
    }
 }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

实施CupertinoActionSheet的正确方法是什么?

实施AsyncTask的正确方法是什么?静态或非静态嵌套类?

用Redux实施事务的正确方法是什么

实施动画边框底部的正确方法是什么?

在iOS应用中实施MVC模式的正确方法是什么?

在where子句中使用案例的正确方法是什么

GpyOpt忽略约束。指定它们的正确方法是什么?

检查空值的正确方法是什么?

导出组件值的正确方法是什么?

在Scala中对案例类应用递归操作

Scala按类型对案例类进行排序

在类组件中获取事件的反应引用值的正确方法是什么?

在Vue.js 2.0中的v模型上实施格式化的正确方法是什么

在基本索引表单上实施delete all选项的正确方法是什么

实施操纵Dom的第三方库的正确方法是什么?

在我的Sprite-Kit游戏中实施此动作的正确方法是什么?

在vega-lite中实施自定义点击处理程序的正确方法是什么

实施自定义Laravel护照授予的正确方法是什么?

创建案例循环/开关语句类型的PowerShell函数的正确方法是什么?

正确的方法是什么?

约束基类的目的是什么?

用计时器处理类的正确方法是什么?

将 js 类导入 Svelte 组件的正确方法是什么?

实用程序类-正确的方法是什么?

加载包主类的正确方法是什么?

公开类拥有的资源的正确方法是什么?

在Swift中更改ViewController类名称的正确方法是什么?

在类中调用属性的正确方法是什么?

从KType创建类实例的正确方法是什么