Scala 3 中的类型推断变化

Mar*_*lic 4 scala type-inference dotty scala-3

Scala 3 将在类型推断方面带来哪些变化?当前文档只是说明TODO。例如,

弱一致性

斯卡拉 2.13

scala> val i: Int = 42
val i: Int = 42

scala> val c: Char = 'a'
val c: Char = a

scala> List(i,c)
val res0: List[Int] = List(42, 97)
Run Code Online (Sandbox Code Playgroud)

Scala 3 (dotty 0.24.0-RC1)

scala> val i: Int = 42
val i: Int = 42

scala> val c: Char = 'a'
val c: Char = a

scala> List(i,c)
val res0: List[AnyVal] = List(42, a)
Run Code Online (Sandbox Code Playgroud)

平等

斯卡拉 2.13

scala> 42 == Some(42)
          ^
       warning: comparing values of types Int and Some[Int] using `==` will always yield false
val res2: Boolean = false
Run Code Online (Sandbox Code Playgroud)

斯卡拉 3

scala> 42 == Some(42)
1 |42 == Some(42)
  |^^^^^^^^^^^^^^
  |Values of types Int and Some[Int] cannot be compared with == or !=
Run Code Online (Sandbox Code Playgroud)

小智 5

因此,对于您的Equality示例,它实际上是由新的Multiversal Equality引起的,这几乎意味着如果您有一个Eql[A, B]where A is B 则类型 A 只能与它具有Eql实例的事物进行比较(形式为Eql[A, C]or Eql[C, A])。

就scala 3的一般类型推断而言,主要有:

  • 联合类型:我们现在可以表示联合类型和表达式,例如

     if (condition) 1 else "1"
    
    Run Code Online (Sandbox Code Playgroud)

    应该推断为类型Int | String

  • Explicit Nulls:联合类型的新用途之一是描述可为空类型的方法,因此例如我们可以用 Java 编写这样的代码:

     public String getUser(int id) {
         if (id == 0) {
             return "Admin";
         }
         return null;
     }
    
    Run Code Online (Sandbox Code Playgroud)

    同样在 Scala 2 中,我们可以这样写:

    def getUser(id: Int): String = if (id == 0) return "Admin" else null
    
    Run Code Online (Sandbox Code Playgroud)

    但是在 scala 3 中,这样的方法也必须声明为类型String | Null以表示其可空性,并且在较新版本的 scala 3 中默认情况下不会编译。

    使用 Java 时会变得更加复杂,因此如果您想了解更多信息,我建议您阅读链接。

  • GADT:类似于@functionalInterface我们知道有 GADT 的 Java 中的工作方式。这意味着如果你有一个未实现的方法的特征:

    trait Fooable {
        def foo(): Unit
    }
    
    Run Code Online (Sandbox Code Playgroud)

    您可以通过传递带有该签名的 lambda 来创建它的实例,因此在此示例中:

    val fooable: Fooable = () => print("Fooing")
    
    Run Code Online (Sandbox Code Playgroud)

    还有一些,包括上下文函数隐式转换参数解组,但这些是主要的。