gpt4 book ai didi

scala - 伴随对象应用方法失败

转载 作者:行者123 更新时间:2023-12-04 17:51:42 25 4
gpt4 key购买 nike

Scala 类在它们的伴随对象中具有 applyunapply 方法是很常见的。
unapply 的行为是明确的:如果它的参数是或可以转换为类的有效实例,则返回它的 Some。否则,返回 None

举一个具体的例子,让我们想象一个 Url 案例类:

object Url {
def apply(str: String): Url = ???
def unapply(str: String): Option[Url] = ???
}

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

如果 str 是有效 URL,则 unapply 将返回 Some[Url] ,否则返回 None
apply 对我来说不太清楚,但是:它应该如何对 str 不是有效 URL 使用react?

来自 Java 世界,我的第一直觉是抛出一个 IllegalArgumentException ,这将允许我们将伴随对象实现为:
object Url {
def apply(str: String): Url = ... // some function that parses a URI and throws if it fails.

def unapply(str: String): Option[Url] = Try(apply(str)).toOption
}

我知道这在功能世界中不被认为是非常好的做法(例如,在 this answer 中解释过)。

另一种方法是让 apply 返回一个 Option[Url] ,在这种情况下,它是 unapply 的简单克隆,最好不要实现。

这是要得出的正确结论吗?这种可能会失败的 apply 方法是否应该根本不实现?在这种情况下, throw 是否可以?有没有我没有看到的第三种选择?

最佳答案

这有点主观,但我认为你也不应该这样做。

假设您允许 apply 失败,即抛出异常或返回一个空选项。然后执行 val url = Url(someString) 可能会失败,尽管看起来非常像一个构造函数。这就是整个问题:伴随对象的 apply 方法应该为您可靠地构造新实例,而您根本无法从任意字符串可靠地构造 Url 实例。所以不要那样做。
unapply 通常应该用于获取有效的 Url 对象并返回另一个表示形式,您可以使用该表示形式再次创建 Url。作为一个例子,看看为 case 类生成的 unapply 方法,它只返回一个包含构造它的参数的元组。所以签名实际上应该是 def unapply(url: Url): String

所以我的结论是,两者都不应该用于构建 Url 。我认为最惯用的方法是使用 def parse(str: String): Option[Url] 方法来明确您实际在做什么(解析字符串)并且它可能会失败。然后您可以执行 Url.parse(someString).map(url => ...) 以使用您的 Url 实例。

关于scala - 伴随对象应用方法失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23994449/

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