Scala 3在类型推理方面会带来哪些变化?目前文档中只是简单的说明 待办事项. 例如:
Scala 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)
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)
Scala 2.13
scala> 42 == Some(42)
^
warning: comparing values of types Int and Some[Int] using `==` will always yield false
val res2: Boolean = false
Scala 3
scala> 42 == Some(42)
1 |42 == Some(42)
|^^^^^^^^^^^^^^
|Values of types Int and Some[Int] cannot be compared with == or !=
所以对于你的 Equality
例如它实际上是由新的 多重平等 这几乎意味着,如果你有一个 Eql[A, B]
其中A是B,那么A型只能与它有一个 Eql
的实例(形式为 Eql[A, C]
或 Eql[C, A]
).
就scala 3的一般类型推理而言,主要有以下几点。
联盟类型: 我们现在可以用联合类型和表达式来表示,如
if (condition) 1 else "1"
属于推断型 Int | String
.
显式空值: 联合类型的一个新用途是描述可空类型的一种方式,例如,我们可以在Java中写这样的代码。
public String getUser(int id) {
if (id == 0) {
return "Admin";
}
return null;
}
在Scala 2中我们也可以这样写。
def getUser(id: Int): String = if (id == 0) return "Admin" else null
但是在scala 3中,这样的方法也必须被声明为: String | Null
来表示它的可空性,并且在scala 3的新版本中默认不会编译。
当使用Java时,它变得更加复杂,所以如果你想了解更多关于它的信息,我建议在链接中阅读。
GADT。类似于如何 @functionalInterface
在java中,我们知道有GADTs.这意味着,如果你有一个trait,有一个未实现的方法,你可以通过传递一个带有该签名的lambda来创建它的实例。
trait Fooable {
def foo(): Unit
}
你可以通过传递一个带有该签名的lambda来创建它的实例,所以在这个例子中:
val fooable: Fooable = () => print("Fooing")
推断类型现在通过单个参数列表的剩余部分进行传播,这意味着使用多个参数列表来帮助推断可能是不必要的。
Scala 2.13
scala> def f[T](i: T, g: T => T) = g(i)
def f[T](i: T, g: T => T): T
scala> f(41, x => x + 1)
^
error: missing parameter type
Scala 3
scala> def f[T](i: T, g: T => T) = g(i)
def f[T](i: T, g: T => T): T
scala> f(41, x => x + 1)
val res0: Int = 42
我想这种变化可能与 允许参数间的依赖关系 #2079