提问人:Talos 提问时间:1/18/2023 最后编辑:Dmytro MitinTalos 更新时间:1/19/2023 访问量:174
Scala 3 中的细化类型和匿名子类有什么区别?
What is a difference between refinement type and anonymous subclass in Scala 3?
问:
匿名类定义是
匿名类是由 Scala 生成的合成子类 来自类或特征名称的新表达式的编译器 然后是大括号。大括号包含 匿名子类,该子类可能为空。但是,如果名称如下 new 是指包含抽象成员的特征或类,这些 必须在定义主体的卷曲括号内具体化 匿名子类。
细化类型定义是
通过为基类型提供内部的多个成员而形成的类型 大括号。大括号中的成员优化了 存在于基本类型中。例如,“动物 吃草“是
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
如果不在示例中使用优化类型,则必须定义一个新的 .class
class AString extends A:
type T = String
类是对象的蓝图。定义类后,可以使用关键字 new 从类蓝图创建对象。
类型和类是不同的(实际上是正交的)概念。类型属于类型论,类属于 OOP。类存在于字节码中,类型大多不存在于字节码中(如果它们没有专门持久化到运行时,或者它们显然不对应于类)。
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 细化类型可以与类型论中的细化类型(或具有依赖类型的编程语言)进行比较,即(依赖)类型被赋予谓词。
评论