gpt4 book ai didi

scala - 对案例类值强制执行约束的正确方法是什么

转载 作者:行者123 更新时间:2023-12-03 18:30:13 24 4
gpt4 key购买 nike

在构建时抛出异常通常被视为不是一件非常礼貌的事情,但我不确定在尝试对案例类值强制执行约束时如何避免这种情况。

例如,假设我需要表示一个范围,并且两个边界都必须为正。立即实现将是:

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的构造函数不安全。

是否有一种通用模式可以保持 case 类的易用性、强制值约束并避免抛出异常?

最佳答案

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

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

将此与 NullPointerException 的行为进行比较s 或 ArithmethicException s 有时仍会在 Scala 中发生。有时,在面对足够的“疯狂”时进行防御性编程不再合理。

另一方面,如果您的类由您控制较少的值填充,即它们是用户输入的直接结果,您必须简单地对您的构造进行更大的控制。使用返回 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(...))
}
}

关于scala - 对案例类值强制执行约束的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24002422/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com