gpt4 book ai didi

scala - 理解 Scala 3 book 中 "Option"的定义和脱糖

转载 作者:行者123 更新时间:2023-12-04 11:47:09 25 4
gpt4 key购买 nike

几周后我将开始担任 Scala 角色,但我之前没有写过任何 Scala(是的,我 future 的雇主知道这一点),尽管我已经写了很多 C# 和 Haskell。无论如何,我正在浏览 Scala 3 书,并找到了这个 example :

enum Option[+T]:
case Some(x: T)
case None
显然dusugars变成:
enum Option[+T]:
case Some(x: T) extends Option[T]
case None extends Option[Nothing]
我的两个问题是:
  • 这种脱糖机制究竟是如何工作的?特别是为什么Some默认扩展 Option[T]None扩展 Option[Nothing] ?
  • 这似乎是定义 Option 的一种奇怪方式。 .我会这样定义它:
  • enum Option[+T]:
    case Some(x: T) extends Option[T]
    case None extends Option[T]
    确实与 None延伸 Option[None]这不会失败吗?
    Option[string] x = None;
    Option[T]T 中是协变的和 None不是 string 的子类型?
    我敢肯定,我在这里遗漏了一些非常基本的东西。

    最佳答案

    枚举脱糖工作原理的一个很好的来源是 Issue #1970 上的原始提案。 .
    该页面上与您的问题相关的部分标题为“脱糖”。让我们看看你的 Option定义。

    enum Option[+T]:
    case Some(x: T)
    case None
    Some是具有类型参数的枚举下的参数化情况,因此规则 #4 适用

    If E is an enum class with type parameters Ts, then a case in its companion object without an extends clause

    case C <params> <body>

    ...

    For the case where C does not have type parameters, assume E's type parameters are

    V1 T1 > L1 <: U1 ,   ... ,    Vn Tn >: Ln <: Un      (n > 0)

    where each of the variances Vi is either '+' or '-'. Then the case expands to

    case C <params> extends E[B1, ..., Bn] <body>

    所以你的 Some案例得到一个 extends Option[T]的条款,如你所料。然后规则#5 为我们提供了我们的实际案例类。
    另一方面,您的 None出于同样的原因,不使用类型参数,因此结果基于方差。
  • T是不变的,我们必须指定一个 extends条款明确
  • T是协变的,我们得到 Nothing
  • T是逆变的,我们得到 Any

  • 您的 T是协变的,所以我们扩展 Option[Nothing] ,记住它是 Option[S] 的子类型对于任何 S .因此,您的赋值(请记住,在 Scala 中,我们使用 val/ var 来声明变量,而不仅仅是类型名称)
    val x: Option[String] = None;
    None是类型 None.type 的值, 扩展 Option[Nothing] . Option[Nothing]Option[String] 的子类型自 NothingString 的子类型.所以任务成功。
    这也是同样的原因 Nil (空列表)扩展 List[Nothing] .我可以构建一个 Nil它有一个具体类型( List[Nothing] 的子类型),然后我可以出现并在前面添加任何我想要的。结果列表不再是 List[Nothing] ; 1 +: NilList[Int]"a" +: NilList[String] ,但重点是, Nil可以来自我程序的任何地方,我们不必预先决定我们希望它是什么类型。我们不能(安全地)在可变数据类型上使用协方差,所以这一切只适用于 ListOption是不可变的。可变集合,如 ArrayBuffer它的类型参数是不变的。 (注意:Java 的内置数组是协变的,即 unsound 会导致各种问题)

    关于scala - 理解 Scala 3 book 中 "Option"的定义和脱糖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67886541/

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