什么类型是特殊的Scala编译器?
Scala对于如何将语言功能实现为库功能做了大量工作。
有没有一种语言特别对待的类型列表?
在规范中还是作为实现细节?
这将包括,例如,优化远离元组匹配。
关于模式匹配,理解,try-catch块和其他语言结构的特殊约定呢?
字符串对于编译器来说是特殊的吗? 我发现字符串增强只是一个库隐式转换,而且Predef
支持字符串连接,但是这种语言在某种程度上是特殊的吗?
同样,我看到有关<:<
和classOf
和asInstanceOf
,并且不清楚什么是神奇的内在。 有没有办法通过编译器选项或通过查看字节码来区分差异?
我想了解一个特性是否被Scala.JS和Scala-native等实现统一支持,或者如果某个特性实际上可能证明是实现相关的,则取决于库实现。
有一个令人难以置信的编译器“已知”的类型,并且在不同程度上是特殊的。 你可以在scalac的Definitions.scala中找到完整的列表。
我们可以根据它们的特殊程度对它们进行分类。
免责声明:我可能已经忘记了更多。
特殊的类型系统
以下类型对Scala的类型系统至关重要。 它们对如何执行类型检查本身有影响。 所有这些类型都在规范中提到(或者至少它们肯定应该是)。
Any
, AnyRef
, AnyVal
, Null
, Nothing
:位于Scala类型系统顶部和底部的五种类型。 scala.FunctionN
,由匿名函数(包括eta-expansion)给出的(规范)类型。 即使在2.12中,对匿名函数进行SAM处理, FunctionN
在某些情况下仍然是特殊的(特别是在重载分辨率方面)。 scala.PartialFunction
(对类型推断的工作方式有影响) Unit
Int
, Long
, Float
, Double
, Char
, Boolean
, String
, Symbol
, java.lang.Class
Char
,对于弱一致性(总起来说,这两个项目符号涵盖了所有基元类型) Option
和元组(用于模式匹配和自动修改) java.lang.Throwable
scala.Dynamic
scala.Singleton
scala.reflect.*
,特别是ClassTag
, TypeTag
等 scala.annotation.{,ClassFile,Static}Annotation
scala.annotation.*
中的注释(例如, unchecked
) scala.language.*
scala.math.ScalaNumber
(因不明原因) 已知编译器是解除某些语言功能的问题
以下类型对于类型系统并不重要。 它们对类型检查没有影响。 但是,Scala语言确实具有许多构造,这些构造解析了这些类型的表达式。
这些类型也将在说明书中提及。
scala.collection.Seq
, Nil
和WrappedArray
,用于可变参数参数。 TupleN
类型 Product
和Serializable
(用于案例类) MatchError
,由模式匹配结构生成 scala.xml.*
scala.DelayedInit
List
(编译器对这些进行一些简单的优化,比如将List()
重写为Nil
) 已知该语言的实施
这可能是你最关心的名单,因为你说你有兴趣知道在不同的后端会有什么不同。 以前的类别由编译器的早期(前端)阶段处理,因此由Scala / JVM,Scala.js和Scala Native共享。 这个类别通常被称为编译器后端,因此可能有不同的处理方式。 请注意,Scala.js和Scala Native都尝试在合理的程度上模仿Scala / JVM的语义。
这些类型可能不会在语言规范本身中提及,至少不是全部。
以下是后端达成共识的地方(据我所知,Scala Native是这样的):
Boolean
, Char
, Byte
, Short
, Int
, Long
, Float
, Double
, Unit
。 scala.Array
。 Cloneable
(目前在Scala Native中不支持,请参阅#334) String
和StringBuilder
(主要用于字符串连接) Object
,几乎所有的方法 这里是他们不同意的地方:
java.lang.Integer
) Serializable
java.rmi.Remote
和java.rmi.RemoteException
scala.annotation.*
的注释(例如strictfp
) java.lang.reflect.*
一些东西,由Scala / JVM用来实现结构类型 此外,尽管不是类型本身,但是一系列原始方法也由后端专门处理。
平台特定的类型
除了上述类型(可在所有平台上使用)之外,非JVM平台还可以添加自己的特殊类型以实现互操作性。
Scala.js特定的类型
请参阅JSDefinitions.scala
js.Any
:概念上Any
,除了AnyVal
和AnyRef
之外的第三种子类型。 他们拥有JavaScript语义而不是Scala语义。 String
和盒装版本(编译器大量重写 - 所谓的“劫持”) - js.ThisFunctionN
:它们的apply
方法的行为与其他JavaScript类型的不同(第一个实际参数成为被调用函数的thisArgument
) js.UndefOr
和js.|
(尽管它们没有扩展js.Any
但它们表现为JS类型) js.Object
( new js.Object()
是特殊的,作为一个空的JS对象字面值{}
) js.JavaScriptException
(在throw
和catch
表现得非常特别) js.WrappedArray
(用于解除可变参数) js.ConstructorTag
(类似于ClassTag
) js.native
和js.native
所有注释js.annotation.*
另外,还有十几个原始方法。
Scala原生特定类型
参见NirDefinitions.scala
UByte
, UShort
, UInt
和ULong
Ptr
,指针类型 FunctionPtrN
,函数指针类型 native.*
注释native.*
scala.scalanative.runtime
一些额外的基本方法