在Scala 3中细化类型和匿名子类之间有什么区别?



匿名类定义是

匿名类是由Scala生成的合成子类编译器从类或trait名所在的新表达式中编译后面跟着花括号。类的体匿名子类,可以为空。但是,如果下面的名称New指的是包含这些抽象成员的trait或类必须在定义主体的花括号内进行具体化吗匿名子类。

细分类型定义是

通过提供基类型内部成员数而形成的类型花括号。花括号中的成员细化了存在于基类型中。例如,"动物"的类型"吃草"是Animal { type SuitableFood = Grass }

——这两个定义都摘自Martin Odersky等人的《Programming in Scala Fifth Edition》一书。

有什么区别?你能用简单的例子来说明吗?


让我们看看我的代码示例,它编译:

abstract class A:
type T
// anonymous class
var o1 = new A { type T = String }
// refinement type
var o2: A { type T = String } = null
o1 = o2 // OK
o2 = o1 // OK

在我看来,细化类型是创建新类型的一种方便的方法,匿名类隐式地做到了这一点。

正如Dmytro Mitin在[1]和[2]中指出的,主要的区别就像class和type的区别一样。

限制变量在运行时可以引用或表达式可以生成的可能值。细化类型仍然是一个类型,它可以用来代替定义一个新的class

如果在示例中不使用细化类型,则必须定义一个新的class

class AString extends A:
type T = String

是物体的蓝图。一旦定义了类,就可以使用关键字new从类蓝图中创建对象。

类型和类是不同的(实际上是正交的)概念。类型属于类型理论,类属于面向对象。类存在于字节码中,类型大多不存在于字节码中(如果它们没有特别持久化到运行时,或者它们明显不对应于类)。

在Scala(和Java)中,类和类型的区别是什么?Type和Class的区别是什么?

https://typelevel.org/blog/2017/02/13/more-types-than-classes.html

new A { type T = String }

的简写
{
class AImpl extends A {
type T = String
}
new AImpl
}

如果你定义了一个匿名类

val o1 = new A { type T = String }
例如,o1的类型可以细化为
val o1: A { type T = String } = new A { type T = String }

甚至结构

val o1: A { type T = String; def foo(): Unit } = new A { 
type T = String
def foo(): Unit = println("foo")
}

或者不精炼如果我们静态向上转换,只是

val o1: A = new A { type T = String }

所以定义一个匿名类并不意味着变量的类型是细化类型。

另一方面,您可以考虑细化类型
type X = A { type T = String }
val o2: A { type T = String } = null

没有引入匿名类。现在字节码中唯一的类是A,没有AImpl(直到实例化new ...)。

Scala细化类型可以与类型论(或具有依赖类型的编程语言)中的细化类型进行比较,即赋予谓词的(依赖)类型。

最新更新