Scala 标准库
Scala 标准库由包 scala
组成,其中包含许多类和模块。以下描述了其中一些类。
基本类型别名
scala
包提供了以下基本类型别名,它们向用户代码公开了一些无法以其他方式编写的 类型 的形式
type AnyKind = ´x´ // where ´x´ is the internal AnyKind type
type Nothing = ´x´ // where ´x´ is the internal Nothing type
type | = [A, B] =>> A ´|´ B // where | is the internal union type operator
type & = [A, B] =>> A ´&´ B // where & is the internal intersection type operator
根类
此层次结构的根是由类 scala.Any
形成的。Scala 执行环境中的每个类都直接或间接地继承自此类。根据定义,Any
也是最顶层的 适当类型 。类 Any
具有两个直接子类:AnyRef
和 AnyVal
。
子类 AnyRef
表示在底层主机系统中以对象形式表示的所有值。用其他语言编写的类继承自 scala.AnyRef
。
类 AnyVal
的预定义子类描述了在底层主机系统中未实现为对象的那些值。
未显式继承自 AnyVal
的用户定义的 Scala 类直接或间接地继承自 AnyRef
。它们不能同时继承自 AnyRef
和 AnyVal
。
类 AnyRef
和 AnyVal
仅需要提供在类 Any
中声明的成员,但实现可能会向这些类添加特定于主机的成员(例如,实现可能会将类 AnyRef
与其自己的对象根类标识)。
以下定义描述了这些根类的签名。
package scala
/** The universal root class */
abstract class Any {
/** Defined equality; abstract here */
def equals(that: Any): Boolean
/** Semantic equality between values */
final def == (that: Any): Boolean =
if (null eq this) null eq that else this equals that
/** Semantic inequality between values */
final def != (that: Any): Boolean = !(this == that)
/** Hash code; abstract here */
def hashCode: Int = ...
/** Textual representation; abstract here */
def toString: String = ...
/** Type test; needs to be inlined to work as given */
def isInstanceOf[a]: Boolean
/** Type cast; needs to be inlined to work as given */ */
def asInstanceOf[A]: A
}
/** The root class of all value types */
final class AnyVal extends Any
/** The root class of all reference types */
class AnyRef extends Any {
def equals(that: Any): Boolean = this eq that
final def eq(that: AnyRef): Boolean = ... // reference equality
final def ne(that: AnyRef): Boolean = !(this eq that)
def hashCode: Int = ... // hashCode computed from allocation address
def toString: String = ... // toString computed from hashCode and class name
def synchronized[T](body: => T): T // execute `body` in while locking `this`.
}
类型测试 ´x´.isInstanceOf[´T´]
等同于一个类型化的模式匹配
´x´ match {
case _: ´T'´ => true
case _ => false
}
其中类型 ´T'´ 与 ´T´ 相同,除非 ´T´ 的形式为 ´D´ 或 ´D[\mathit{tps}]´,其中 ´D´ 是某个外部类 ´C´ 的类型成员。在这种情况下,´T'´ 为 ´C´#´D´
(或 ´C´#´D[tps]´
),而 ´T´ 本身将扩展为 ´C´.this.´D[tps]´
。换句话说,isInstanceOf
测试不会检查类型是否具有相同的封闭实例。
如果 ´T´ 是 数值类型 ,则测试 ´x´.asInstanceOf[´T´]
会被特殊处理。在这种情况下,强制转换将被转换为对 转换方法 x.to´T´
的应用。对于非数值类型 ´x´,操作将引发 ClassCastException
。
值类
值类是其实例在底层主机系统中不表示为对象的类。所有值类都继承自类 AnyVal
。Scala 实现需要提供值类 Unit
、Boolean
、Double
、Float
、Long
、Int
、Char
、Short
和 Byte
(但也可以自由提供其他值类)。这些类的签名在下面定义。
数值类型
类 Double
、Float
、Long
、Int
、Char
、Short
和 Byte
统称为数值类型 。类 Byte
、Short
或 Char
称为子范围类型 。子范围类型以及 Int
和 Long
称为整数类型 ,而 Float
和 Double
称为浮点类型 。
数值类型按以下偏序排列
Byte - Short
\
Int - Long - Float - Double
/
Char
Byte
和 Short
是此顺序中排名最低的类型,而 Double
是排名最高的类型。排名不 意味着 一致性关系 ;例如,Int
不是 Long
的子类型。但是,对象 Predef
定义了从每个数值类型到所有更高排名数值类型的 视图 。因此,当 上下文 需要时,低排名类型会隐式转换为高排名类型。
给定两个数值类型 ´S´ 和 ´T´,´S´ 和 ´T´ 的操作类型 定义如下:如果 ´S´ 和 ´T´ 都是子范围类型,则 ´S´ 和 ´T´ 的操作类型为 Int
。否则,´S´ 和 ´T´ 的操作类型是两个类型中排名较高的那个。给定两个数值 ´v´ 和 ´w´,´v´ 和 ´w´ 的操作类型是其运行时类型的操作类型。
任何数值类型 ´T´ 都支持以下方法。
用于等于 (==
)、不等于 (!=
)、小于 (<
)、大于 (>
)、小于或等于 (<=
)、大于或等于 (>=
) 的比较方法,每个方法都有 7 个重载的备选方法。每个备选方法都接受某个数值类型的参数。其结果类型为类型 Boolean
。该操作通过将接收方及其参数转换为其操作类型并执行该类型的给定比较操作来进行评估。
算术方法包括加法 (+
)、减法 (-
)、乘法 (*
)、除法 (/
) 和取余 (%
),每种方法都有 7 个重载版本。每个版本都接受一个数值类型 ´U´ 的参数。其结果类型是 ´T´ 和 ´U´ 的运算类型。运算通过将接收者及其参数转换为它们的运算类型,并执行该类型的给定算术运算来进行评估。
无参数的算术方法包括恒等 (+
) 和取反 (-
),其结果类型为 ´T´。第一个方法返回接收者本身,而第二个方法返回其取反值。
转换方法包括 toByte
、toShort
、toChar
、toInt
、toLong
、toFloat
、toDouble
,它们使用 Java 数值类型强制转换操作的规则将接收者对象转换为目标类型。转换可能会截断数值(例如从 Long
到 Int
或从 Int
到 Byte
),或者可能会丢失精度(例如从 Double
到 Float
或在 Long
和 Float
之间转换)。
整数数值类型除了上述操作外,还支持以下操作
位操作方法包括按位与 (&
)、按位或 {|
} 和按位异或 (^
),每种方法都有 5 个重载版本。每个版本都接受一个整数数值类型的参数。其结果类型是 ´T´ 和 ´U´ 的运算类型。运算通过将接收者及其参数转换为它们的运算类型,并执行该类型的给定按位运算来进行评估。
一个无参数的按位取反方法 (~
)。其结果类型是接收者类型 ´T´ 或 Int
,取两者中较大的一个。运算通过将接收者转换为结果类型,并对其值的每一位进行取反来进行评估。
位移方法包括左移 (<<
)、算术右移 (>>
) 和无符号右移 (>>>
)。每种方法都有两个重载版本,分别接受一个 Int
类型的参数 ´n´ 和一个 Long
类型的参数 ´n´。运算的结果类型是接收者类型 ´T´ 或 Int
,取两者中较大的一个。运算通过将接收者转换为结果类型,并执行指定位数 ´n´ 的移位来进行评估。
数值类型还实现了 Any
类中的 equals
、hashCode
和 toString
操作。
equals
方法测试参数是否为数值类型。如果为真,它将执行适合该类型的 ==
操作。也就是说,数值类型的 equals
方法可以被认为是如下定义的
def equals(other: Any): Boolean = other match {
case that: Byte => this == that
case that: Short => this == that
case that: Char => this == that
case that: Int => this == that
case that: Long => this == that
case that: Float => this == that
case that: Double => this == that
case _ => false
}
hashCode
方法返回一个整数哈希码,它将相等的数值映射到相等的结果。对于 Int
类型和所有子范围类型,它保证是恒等式。
toString
方法将接收者显示为整数或浮点数。
示例
这是数值类型 Int
的签名
package scala
abstract sealed class Int extends AnyVal {
def == (that: Double): Boolean // double equality
def == (that: Float): Boolean // float equality
def == (that: Long): Boolean // long equality
def == (that: Int): Boolean // int equality
def == (that: Short): Boolean // int equality
def == (that: Byte): Boolean // int equality
def == (that: Char): Boolean // int equality
/* analogous for !=, <, >, <=, >= */
def + (that: Double): Double // double addition
def + (that: Float): Double // float addition
def + (that: Long): Long // long addition
def + (that: Int): Int // int addition
def + (that: Short): Int // int addition
def + (that: Byte): Int // int addition
def + (that: Char): Int // int addition
/* analogous for -, *, /, % */
def & (that: Long): Long // long bitwise and
def & (that: Int): Int // int bitwise and
def & (that: Short): Int // int bitwise and
def & (that: Byte): Int // int bitwise and
def & (that: Char): Int // int bitwise and
/* analogous for |, ^ */
def << (cnt: Int): Int // int left shift
def << (cnt: Long): Int // long left shift
/* analogous for >>, >>> */
def unary_+ : Int // int identity
def unary_- : Int // int negation
def unary_~ : Int // int bitwise negation
def toByte: Byte // convert to Byte
def toShort: Short // convert to Short
def toChar: Char // convert to Char
def toInt: Int // convert to Int
def toLong: Long // convert to Long
def toFloat: Float // convert to Float
def toDouble: Double // convert to Double
}
类 Boolean
类 Boolean
只有两个值:true
和 false
。它实现了以下类定义中给出的操作。
package scala
abstract sealed class Boolean extends AnyVal {
def && (p: => Boolean): Boolean = // boolean and
if (this) p else false
def || (p: => Boolean): Boolean = // boolean or
if (this) true else p
def & (x: Boolean): Boolean = // boolean strict and
if (this) x else false
def | (x: Boolean): Boolean = // boolean strict or
if (this) true else x
def == (x: Boolean): Boolean = // boolean equality
if (this) x else x.unary_!
def != (x: Boolean): Boolean = // boolean inequality
if (this) x.unary_! else x
def unary_!: Boolean = // boolean negation
if (this) false else true
}
该类还实现了来自类 Any
的操作 equals
、hashCode
和 toString
。
equals
方法如果参数与接收者是相同的布尔值,则返回 true
,否则返回 false
。hashCode
方法在调用 true
时返回一个固定的、特定于实现的哈希码,在调用 false
时返回一个不同的、固定的、特定于实现的哈希码。toString
方法返回接收者转换为字符串,即 "true"
或 "false"
。
类 Unit
类 Unit
只有一个值:()
。它只实现了来自类 Any
的三个方法 equals
、hashCode
和 toString
。
equals
方法如果参数是单元值 ()
,则返回 true
,否则返回 false
。hashCode
方法返回一个固定的、特定于实现的哈希码。toString
方法返回 "()"
。
标准引用类
本节介绍一些标准的 Scala 引用类,它们在 Scala 编译器中以特殊方式处理 - Scala 为它们提供语法糖,或者 Scala 编译器为它们的操作生成特殊代码。标准 Scala 库中的其他类在 Scala 库文档中由 HTML 页面记录。
类 String
Scala 的 String
类通常派生自底层主机系统的标准 String 类(并且可能与其相同)。对于 Scala 客户端,该类被认为在每种情况下都支持一个方法
def + (that: Any): String
它将左操作数与其右操作数的文本表示形式连接起来。
Function
类
对于每个自然数 ´n \geq 0´,scala
包定义了以下函数类
package scala
trait Function´_n´[-´T_1´, ..., -´T_n´, +´R´]:
def apply(´x_1´: ´T_1´, ..., ´x_n´: ´T_n´): ´R´
这些类参与 具体函数类型 的脱糖。
对于 ´n \leq 22´ 的值,Function´_n´
类定义了额外的函数
package scala
trait Function´_n´[-´T_1´, ..., -´T_n´, +´R´]:
...
override def toString = "<function´_n´>"
def curried: ´T_1´ => ... => ´T_n´ => R = ...
def tupled: ((´T_1´, ..., ´T_n´)) => R = ...
隐式导入的 Predef
对象将名称 Function
定义为 Function1
的别名。
Function1
的子类 PartialFunction
表示(间接)指定其域的函数。使用 isDefined
方法查询部分函数是否为给定输入定义(即,输入是否为函数域的一部分)。
class PartialFunction[-A, +B] extends Function1[A, B] {
def isDefinedAt(x: A): Boolean
... // various derived methods
}
PartialFunction
参与 模式匹配匿名函数 的脱糖。
特质 Product
所有案例类自动扩展 Product
特质(并生成合成方法以符合它)(但不是 Product´n´
),并为其每个参数定义 _´n´
方法。
特质 Enum
所有枚举定义自动扩展 reflect.Enum
特质(并生成合成方法以符合它)。
元组类
元组是以下类定义的HLists 的一种形式
/** Superclass of all tuples. */
sealed trait Tuple extends Product:
/** Return a new tuple by prepending the element to `this` tuple. */
inline def *: [H, This >: this.type <: Tuple] (x: H): H *: This = ...
...
object Tuple:
/** Type of the element at position N in the tuple X. */
type Elem[X <: Tuple, N <: Int] = ...
...
/** A tuple of 0 elements. */
type EmptyTuple = EmptyTuple.type
/** A tuple of 0 elements. */
case object EmptyTuple extends Tuple:
override def toString(): String = "()"
/** Tuple of arbitrary non-zero arity */
sealed trait NonEmptyTuple extends Tuple:
/** Get the i-th element of this tuple. */
inline def apply[This >: this.type <: NonEmptyTuple](n: Int): Elem[This, n.type] = ...
...
sealed abstract class *:[+H, +T <: Tuple] extends NonEmptyTuple
object `*:` :
def unapply[H, T <: Tuple](x: H *: T): (H, T) = (x.head, x.tail)
对于 ´1 \leq n \leq 22´,*:
的具体实现是 Tuple´_n´
类的实例,它们也实现了相应的 Product´_n´
特质。它们至少在标准 Scala 库中定义如下(它们也可能添加其他方法并实现其他特质)。
trait Product´_n´[+´T_1´, ..., +´T_n´] extends Product:
override def productArity: Int = ´n´
def _1: ´T_1´
...
def _n: ´T_n´
final case class Tuple´_n´[+´T_1´, ..., +´T_n´](_1: ´T_1´, ..., _n: ´T_n´)
extends *:[´T_1´, ´T_2´ *: ... _: ´T_n´ *: EmptyTuple]
with Product´_n´[´T_1´, ..., ´T_n´]
对于 ´n > 22´,*:
的具体实现是特定于实现的私有类的实例。
类 Array
数组上的所有操作都脱糖为底层平台的相应操作。因此,以下类定义仅供参考
final class Array[T](_length: Int)
extends java.io.Serializable with java.lang.Cloneable {
def length: Int = ...
def apply(i: Int): T = ...
def update(i: Int, x: T): Unit = ...
override def clone(): Array[T] = ...
}
如果 ´T´ 不是类型参数或抽象类型,则类型 Array[T]
在底层主机系统中表示为数组类型 |T|[]
,其中 |T|
是 T
的擦除。如果 ´T´ 是类型参数或抽象类型,则可能使用不同的表示(在 Java 平台上为 Object
)。
操作
length
返回数组的长度,apply
表示下标,update
表示元素更新。
由于 apply
和 update
操作的语法糖,我们对数组 xs
上的操作有以下 Scala 和 Java 代码之间的对应关系
Scala
Java
xs.length
xs.length
xs(i)
xs[i]
xs(i) = e
xs[i] = e
在 Predef
中存在两种对数组经常使用的隐式转换:转换为 scala.collection.mutable.ArrayOps
和转换为 scala.collection.mutable.ArraySeq
(scala.collection.Seq
的子类型)。
这两种类型都使 Scala 集合 API 中的许多标准操作可用。转换为 ArrayOps
是临时的,因为在 ArrayOps
上定义的所有操作都返回类型为 Array
的值,而转换为 ArraySeq
是永久性的,因为所有操作都返回类型为 ArraySeq
的值。转换为 ArrayOps
优先于转换为 ArraySeq
。
由于 Scala 中参数化类型和宿主语言中数组的 ad-hoc 实现之间的紧张关系,在处理数组时需要考虑一些微妙的点。这些将在下面解释。
方差
与 Java 中的数组不同,Scala 中的数组 *不是* 协变的;也就是说,´S <: T´ 在 Scala 中并不意味着 Array[´S´] ´<:´ Array[´T´]
。但是,如果宿主环境允许,则可以将 ´S´ 数组强制转换为 ´T´ 数组。
例如,Array[String]
不符合 Array[Object]
,即使 String
符合 Object
。但是,可以将类型为 Array[String]
的表达式强制转换为 Array[Object]
,并且此强制转换将在不引发 ClassCastException
的情况下成功。示例
val xs = new Array[String](2)
// val ys: Array[Object] = xs // **** error: incompatible types
val ys: Array[Object] = xs.asInstanceOf[Array[Object]] // OK
使用多态元素类型 ´T´ 实例化数组需要在运行时有关类型 ´T´ 的信息。此信息是通过向类型 ´T´ 添加 scala.reflect.ClassTag
的 上下文界限 来合成的。一个例子是以下 mkArray
方法的实现,该方法创建任意类型 ´T´ 的数组,给定一个定义其元素的 ´T´ 序列
import reflect.ClassTag
def mkArray[T : ClassTag](elems: Seq[T]): Array[T] = {
val result = new Array[T](elems.length)
var i = 0
for (elem <- elems) {
result(i) = elem
i += 1
}
result
}
如果类型 ´T´ 是宿主平台提供专门数组表示的类型,则使用此表示。
示例
在 Java 虚拟机上,调用 mkArray(List(1,2,3))
将返回一个 int
的原始数组,在 Java 中写为 int[]
。
伴随对象
Array
的伴随对象提供了用于实例化一维和多维数组的各种工厂方法,一个提取器方法 unapplySeq
,它允许对数组进行模式匹配,以及其他实用程序方法
package scala
object Array {
/** copies array elements from `src` to `dest`. */
def copy(src: AnyRef, srcPos: Int,
dest: AnyRef, destPos: Int, length: Int): Unit = ...
/** Returns an array of length 0 */
def empty[T: ClassTag]: Array[T] =
/** Create an array with given elements. */
def apply[T: ClassTag](xs: T*): Array[T] = ...
/** Creates array with given dimensions */
def ofDim[T: ClassTag](n1: Int): Array[T] = ...
/** Creates a 2-dimensional array */
def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = ...
...
/** Concatenate all argument arrays into a single array. */
def concat[T: ClassTag](xss: Array[T]*): Array[T] = ...
/** Returns an array that contains the results of some element computation a number
* of times. */
def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = ...
/** Returns a two-dimensional array that contains the results of some element
* computation a number of times. */
def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = ...
...
/** Returns an array containing values of a given function over a range of integer
* values starting from 0. */
def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = ...
/** Returns a two-dimensional array containing values of a given function
* over ranges of integer values starting from `0`. */
def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = ...
...
/** Returns an array containing a sequence of increasing integers in a range. */
def range(start: Int, end: Int): Array[Int] = ...
/** Returns an array containing equally spaced values in some integer interval. */
def range(start: Int, end: Int, step: Int): Array[Int] = ...
/** Returns an array containing repeated applications of a function to a start value. */
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = ...
/** Enables pattern matching over arrays */
def unapplySeq[A](x: Array[A]): Option[IndexedSeq[A]] = Some(x)
}
类节点
package scala.xml
trait Node {
/** the label of this node */
def label: String
/** attribute axis */
def attribute: Map[String, String]
/** child axis (all children of this node) */
def child: Seq[Node]
/** descendant axis (all descendants of this node) */
def descendant: Seq[Node] = child.toList.flatMap {
x => x::x.descendant.asInstanceOf[List[Node]]
}
/** descendant axis (all descendants of this node) */
def descendant_or_self: Seq[Node] = this::child.toList.flatMap {
x => x::x.descendant.asInstanceOf[List[Node]]
}
override def equals(x: Any): Boolean = x match {
case that:Node =>
that.label == this.label &&
that.attribute.sameElements(this.attribute) &&
that.child.sameElements(this.child)
case _ => false
}
/** XPath style projection function. Returns all children of this node
* that are labeled with 'that'. The document order is preserved.
*/
def \(that: Symbol): NodeSeq = {
new NodeSeq({
that.name match {
case "_" => child.toList
case _ =>
var res:List[Node] = Nil
for (x <- child.elements if x.label == that.name) {
res = x::res
}
res.reverse
}
})
}
/** XPath style projection function. Returns all nodes labeled with the
* name 'that' from the 'descendant_or_self' axis. Document order is preserved.
*/
def \\(that: Symbol): NodeSeq = {
new NodeSeq(
that.name match {
case "_" => this.descendant_or_self
case _ => this.descendant_or_self.asInstanceOf[List[Node]].
filter(x => x.label == that.name)
})
}
/** hashcode for this XML node */
override def hashCode =
Utility.hashCode(label, attribute.toList.hashCode, child)
/** string representation of this node */
override def toString = Utility.toXML(this)
}
Predef
对象
Predef
对象为 Scala 程序定义了标准方法和类型别名。它被隐式导入,如 关于名称绑定的章节 中所述,因此所有定义的成员都可以在没有限定符的情况下使用。它在 JVM 环境中的定义符合以下签名
package scala
object Predef {
// classOf ---------------------------------------------------------
/** Returns the runtime representation of a class type. */
def classOf[T]: Class[T] = null
// this is a dummy, classOf is handled by compiler.
// valueOf -----------------------------------------------------------
/** Retrieve the single value of a type with a unique inhabitant. */
@inline def valueOf[T](implicit vt: ValueOf[T]): T {} = vt.value
// instances of the ValueOf type class are provided by the compiler.
// Standard type aliases ---------------------------------------------
type String = java.lang.String
type Class[T] = java.lang.Class[T]
// Miscellaneous -----------------------------------------------------
type Function[-A, +B] = Function1[A, B]
type Map[A, +B] = collection.immutable.Map[A, B]
type Set[A] = collection.immutable.Set[A]
val Map = collection.immutable.Map
val Set = collection.immutable.Set
// Manifest types, companions, and incantations for summoning ---------
type ClassManifest[T] = scala.reflect.ClassManifest[T]
type Manifest[T] = scala.reflect.Manifest[T]
type OptManifest[T] = scala.reflect.OptManifest[T]
val ClassManifest = scala.reflect.ClassManifest
val Manifest = scala.reflect.Manifest
val NoManifest = scala.reflect.NoManifest
def manifest[T](implicit m: Manifest[T]) = m
def classManifest[T](implicit m: ClassManifest[T]) = m
def optManifest[T](implicit m: OptManifest[T]) = m
// Minor variations on identity functions -----------------------------
def identity[A](x: A): A = x
def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world
@inline def locally[T](x: T): T = x // to communicate intent and avoid unmoored statements
// Asserts, Preconditions, Postconditions -----------------------------
def assert(assertion: Boolean) {
if (!assertion)
throw new java.lang.AssertionError("assertion failed")
}
def assert(assertion: Boolean, message: => Any) {
if (!assertion)
throw new java.lang.AssertionError("assertion failed: " + message)
}
def assume(assumption: Boolean) {
if (!assumption)
throw new IllegalArgumentException("assumption failed")
}
def assume(assumption: Boolean, message: => Any) {
if (!assumption)
throw new IllegalArgumentException("assumption failed: " + message.toString)
}
def require(requirement: Boolean) {
if (!requirement)
throw new IllegalArgumentException("requirement failed")
}
def require(requirement: Boolean, message: => Any) {
if (!requirement)
throw new IllegalArgumentException("requirement failed: "+ message)
}
// Printing and reading -----------------------------------------------
def print(x: Any) = Console.print(x)
def println() = Console.println()
def println(x: Any) = Console.println(x)
def printf(text: String, xs: Any*) = Console.printf(text.format(xs: _*))
// Implicit conversions ------------------------------------------------
...
}
预定义的隐式定义
Predef
对象还包含许多隐式定义,这些定义默认情况下可用(因为 Predef
被隐式导入)。隐式定义分为两种优先级。高优先级隐式定义在 Predef
类本身中定义,而低优先级隐式定义在 Predef
继承的类中定义。静态 重载解析 的规则规定,在所有其他条件相同的情况下,隐式解析优先选择高优先级隐式而不是低优先级隐式。
可用的低优先级隐式定义包括以下类别。
对于每种原始类型,一个包装器,它将该类型的值转换为 `runtime.Rich*` 类的实例。例如,类型为 `Int` 的值可以隐式转换为 `runtime.RichInt` 类的实例。
对于每种元素为原始类型的数组类型,一个包装器,它将该类型的数组转换为 `ArraySeq` 类的实例。例如,类型为 `Array[Float]` 的值可以隐式转换为 `ArraySeq[Float]` 类的实例。还有一些泛型数组包装器,它们将类型为 `Array[T]` 的元素(对于任意 `T`)转换为 `ArraySeq`。
从 `String` 到 `WrappedString` 的隐式转换。
可用的高优先级隐式定义包括以下类别。
一个隐式包装器,它向 `Any` 类型添加了具有以下重载变体的 `ensuring` 方法。
def ensuring(cond: Boolean): A = { assert(cond); x }
def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x }
def ensuring(cond: A => Boolean): A = { assert(cond(x)); x }
def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x }
一个隐式包装器,它向 `Any` 类型添加了具有以下实现的 `->` 方法。
def -> [B](y: B): (A, B) = (x, y)
对于每种元素为原始类型的数组类型,一个包装器,它将该类型的数组转换为 `runtime.ArrayOps` 类的实例。例如,类型为 `Array[Float]` 的值可以隐式转换为 `runtime.ArrayOps[Float]` 类的实例。还有一些泛型数组包装器,它们将类型为 `Array[T]` 的元素(对于任意 `T`)转换为 `ArrayOps`。
一个隐式包装器,它向 `Any` 类型添加了具有以下实现的 `+` 和 `formatted` 方法。
def +(other: String) = String.valueOf(self) + other
def formatted(fmtstr: String): String = fmtstr format self
实现以下映射的传递闭包的数值原始类型转换
Byte -> Short
Short -> Int
Char -> Int
Int -> Long
Long -> Float
Float -> Double
原始类型与其包装版本之间的装箱和拆箱转换
Byte <-> java.lang.Byte
Short <-> java.lang.Short
Char <-> java.lang.Character
Int <-> java.lang.Integer
Long <-> java.lang.Long
Float <-> java.lang.Float
Double <-> java.lang.Double
Boolean <-> java.lang.Boolean
一个隐式定义,它为任何类型 `T` 生成类型为 `T <:< T` 的实例。这里,`<:<` 是一个定义如下类的类。
sealed abstract class <:<[-From, +To] extends (From => To)
`<:<` 类型的隐式参数通常用于实现类型约束。