Scala在如何将语言功能实现为库功能方面做了大量工作。
是否有语言专门处理的类型列表?
在规范中还是作为实现细节?
这将包括,例如,优化远离元组的匹配。
与模式匹配,理解,try-catch块和其他语言结构相关的特殊约定怎么样?
字符串在某种程度上对编译器来说是特殊的吗?我看到字符串增强只是一个库隐式转换,并且Predef
支持字符串连接,但是这种语言在某种程度上是特殊的吗?
同样,我看到有关<:<
和classOf
以及asInstanceOf
的问题,而且不清楚什么是神奇的内在因素。有没有办法区分,无论是使用编译器选项还是通过查看字节代码?
我想了解Scala.JS和Scala-native等实现是否统一支持某个功能,或者某个功能实际上是否可能依赖于实现,具体取决于库的实现。
答案 0 :(得分:74)
有很多类型的已知&#34;已知&#34;编译器,并在不同程度上是特殊的。您可以在scalac的Definitions.scala中找到完整列表。
我们可以根据他们所承受的特殊程度对他们进行分类。
免责声明:我可能已经忘记了一些。
以下类型对Scala的类型系统至关重要。它们会影响类型检查本身的执行方式。所有这些类型都在规范中提到(或者至少,它们肯定应该是)。
Any
,AnyRef
,AnyVal
,Null
,Nothing
:位于Scala&#39;类型顶部和底部的五种类型系统。scala.FunctionN
,匿名函数(包括eta-expansion)给出的(规范)类型。即使在具有SAM处理匿名函数的2.12中,FunctionN
在某些情况下仍然是特殊的(特别是在重载分辨率时)。scala.PartialFunction
(对类型推断的工作方式有影响)Unit
Int
,Long
,Float
,Double
,Char
,Boolean
,String
,Symbol
,java.lang.Class
Char
s,弱一致性(这两个项目符号覆盖所有原始类型)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
,用于varargs参数。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
,{ {1}},Double
。Unit
。scala.Array
(目前Scala Native目前不支持,请参阅#334)Cloneable
和String
(主要用于字符串连接)StringBuilder
,几乎涵盖了所有方法以下是他们不同意的地方:
Object
)java.lang.Integer
Serializable
和java.rmi.Remote
java.rmi.RemoteException
中的一些注释(例如scala.annotation.*
)strictfp
中的一些内容,由Scala / JVM用于实现结构类型此外,虽然不是 types 本身,但a long list of primitive methods也由后端专门处理。
除了上面提到的所有平台上提供的类型之外,非JVM平台还添加了自己的特殊类型以实现互操作性。
java.lang.reflect.*
:概念上是js.Any
的第三个子类型,Any
和AnyVal
除外。它们具有JavaScript语义而不是Scala语义。AnyRef
以及所有原始类型的盒装版本(严重重写 - 所谓&#34;劫持&#34; - 由编译器完成)String
:他们的js.ThisFunctionN
方法与其他JavaScript类型的行为不同(第一个实际参数成为被调用函数的apply
)thisArgument
和js.UndefOr
(他们表现为JS类型,即使他们不扩展js.|
)js.Any
(js.Object
是特殊的空JS对象文字new js.Object()
){}
(在js.JavaScriptException
和throw
中非常特别)catch
(用于贬低varargs)js.WrappedArray
(类似于js.ConstructorTag
)ClassTag
以及js.native
另外,还有十几个primitive methods。
js.annotation.*
,UByte
,UShort
和UInt
ULong
,指针类型Ptr
,函数指针类型FunctionPtrN
native.*