gpt4 book ai didi

scala - 为什么以及如何将案例类迁移到 Scala 中的提取器

转载 作者:行者123 更新时间:2023-12-02 04:24:09 27 4
gpt4 key购买 nike

Scala 编程 中关于何时使用案例类以及何时使用提取器的讨论中,他们说

Extractors break [the] link between data representations and patterns ... This property is called representation independence ...

If your component had defined and exported a set of case classes, you'd be stuck with them because client code could already contain pattern matches against these classes ...

Fortunately, you need not decide right away. You could always start with case classes and then, if the need arises, change to extractors. Because patterns over extractors and patterns over case classes look exactly the same in Scala, pattern matches in your clients will continue to work.

我想弄清楚这看起来像什么。假设,使用他们的示例,我使用

定义电子邮件
case class Email(user: String, domain: String)

我和客户 Bob 都和它匹配

def send(addr: Email) = addr match {
case Email(user, domain) => ...
}

send(Email("joel", "gmail.com"))

然后假设我决定切换到提取器以获得表示独立性作为

// case class Email(user: String, domain: String)

object Email {
def apply(user: String, domain: String) = user + "@" + domain

def unapply(addr: String) = addr split "@" match {
case Array(user: String, domain: String) => Some(user, domain)
case _ => None
}
}

除了 send 中的编译失败外,这一切都有效:“未找到:键入电子邮件”。我可以用

解决这个问题
type Email = String

但这是正确的方法吗?我不太明白这如何帮助我获得代表独立性。当然,Bob 现在可以 匹配 "joel@gmail.com"Email("joel", "gmail.com")(现在是等效的),但我必须假设他们使用的是 Email

最佳答案

我假设 表示独立性 意味着您可以将内容存储在 Email 中,以您想要的任何方式,但您仍然需要有这种单独的类型 Email... 如果您想从 apply 返回 Email 并在 unapply 中提取:

class Email(private val internal: String)

object Email {
def apply(user: String, domain: String): Email = new Email(user + "@" + domain)

def unapply(email: Email): Option[(String, String)] =
email.internal split "@" match {
case Array(user: String, domain: String) => Some((user, domain))
case _ => None
}
}

这样你就可以写:

val email: Email = Email("my", "email.com")

email match {
case Email(user, domain) => ...
}

同时能够随心所欲地更改 Email 的内部结构。但是,仍然必须有一些Email类型,它是否是traitclass以及里面的内容应该与您无关API 的用户。您也可以编写 type Email = String 但类型别名不是“新类型”,因此您可以将任何 String 放在那里,编译器将不会遵守。是否需要由您决定。

关于scala - 为什么以及如何将案例类迁移到 Scala 中的提取器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56466977/

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