gpt4 book ai didi

scala - 在 Scala 中进行空检查的最佳实践

转载 作者:行者123 更新时间:2023-12-04 01:05:37 25 4
gpt4 key购买 nike

我明白 null在 Scala 中不受欢迎,并且应该始终将可选值包装在 Option 中(或“空类型”,如果有的话)。

优点很明显,永远不需要检查 null值,并且生成的代码更安全,更易于阅读。

然而在实践中,没有什么能阻止一个值成为 null - 规则不是由编译器强制执行的,更像是君子协定。例如,当与 Java API 交互时,这很容易中断。

是否有最佳实践?例如,假设我需要写一个 Url case 类,并且该类的实例可以从 java.net.URI 创建:

object Url {
def apply(uri: URI): Url = Url(uri.getScheme, uri.getHost, uri.getRawPath)
}

case class Url(protocol: String, host: String, path: String) {
def protocol(value: String): Url = copy(protocol = value)
def host(value: String): Url = copy(host = value)
def path(value: String): Url = copy(path = value)
}

URI实例可以返回 nullgetScheme , getHostgetRawPath .在 apply(URI) 中是否足以防止这些问题?方法(例如,使用 require 语句)?从技术上讲,为了完全安全,最好保护 protocol , hostpath辅助方法以及构造函数,但这听起来像是大量的工作和样板。

相反,防止已知接受/返回的 API 是否被认为是安全的 null值(在我们的示例中为 URI)并假设外部调用者不会通过 null值(value)观或只有在他们这样做时才怪自己?

最佳答案

在处理纯函数时,最好坚持完全实现,而不是使用 null , require或异常抛出,对数据中的所有失败进行编码。类型如 OptionEither正是为了这个。它们都是 monad,因此您可以对它们使用“for”语法。

以下对您的代码的修改显示了一个总函数 apply ,当输入 Java URI 时,它只产生一个有意义的值不提供 null s。我们通过将结果包装在 Option 中来对“有意义”的概念进行编码。 .

object Url {
def apply(uri: java.net.URI): Option[Url] =
for {
protocol <- Option(uri.getScheme)
host <- Option(uri.getHost)
path <- Option(uri.getRawPath)
}
yield Url(protocol, host, path)
}

case class Url(protocol: String, host: String, path: String)

函数 Option是一个标准的空检查函数,它映射 nullNone并将值包装在 Some 中.

关于你的“设置”功能,你可以实现 null - 类似地检查它们,使用 Option .例如。:
case class Url(protocol: String, host: String, path: String) {
def protocol(value: String): Option[Url] =
Option(value).map(v => copy(protocol = v))
// so on...
}

但是我会建议反对。在 Scala 中,通常不使用 null s,所以只实现 null 也是惯例。 -处理“桥接”API,当您从 Java 库中获取值时。这就是为什么 null - 从 java.net.URI 转换时检查确实很有意义,但在那之后你就进入了 Scala 世界,那里应该没有 null s,因此 null -检查只是变得多余。

关于scala - 在 Scala 中进行空检查的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23992051/

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