【scala原理系列】scala Predef对象的原理示例源码详解

scala Predef object对象的原理示例源码详解

原理

Predef 是 Scala 标准库中的一个对象,它在编写 Scala 代码时自动引入,无需显式导入。它的作用是提供一些常用的方法和隐式转换,使得编码更加方便和简洁。

原理如下:

  1. 隐式导入:当编译器编译 Scala 代码时,默认会自动导入 Predef 对象中的所有成员,包括方法和隐式转换。这意味着我们可以直接使用 Predef 中定义的方法和隐式转换,而无需显式导入或声明。

  2. 类型装箱和拆箱Predef 中定义了一系列的隐式转换方法,用于将基本类型(如 IntBoolean)与对应的包装类型(如 java.lang.Integerjava.lang.Boolean)之间进行自动转换。这样,在需要使用包装类型的地方,我们可以直接使用基本类型,编译器会自动将其转换为包装类型。

  3. 集合和数组操作Predef 提供了一些方法和隐式转换,用于对集合(如 ArraySeq)和字符串(String)进行操作。例如,可以将数组转换为 WrappedArray 类型,以便使用丰富的数组操作方法;也可以将字符串转换为 WrappedString 类型,提供了一系列的字符串操作方法。

  4. 字符串格式化Predef 中定义了一些方法,用于字符串的格式化。例如,可以使用 formatted 方法按照给定的格式化字符串对字符串进行格式化。

  5. 隐式转换Predef 中还定义了一些隐式转换方法,用于将某些类型自动转换为其他类型。例如,可以将任意类型转换为 ArrowAssoc 类型,以提供箭头操作符(->);也可以将任意类型转换为 Ensuring 类型,以提供 ensuring 方法用于条件判断。

  6. 输入输出Predef 中定义了一些方法,用于从标准输入读取数据或向标准输出打印数据。例如,可以使用 readLine 方法从标准输入读取一行字符串;可以使用 println 方法向标准输出打印字符串。

通过自动导入 Predef 对象中的方法和隐式转换,我们可以更方便地使用这些功能,简化代码编写过程。同时,由于 Predef 是 Scala 标准库的一部分,它的功能经过广泛测试和使用,具有高度的可靠性和稳定性。

方法总结

Predef 是 Scala 标准库中的一个对象,它包含了一些常用的方法和隐式转换。下面是对 Predef 源码中方法和隐式转换的用法分类总结:

  1. 类型装箱和拆箱

    • byteWrapper, shortWrapper, intWrapper, charWrapper, longWrapper, floatWrapper, doubleWrapper, booleanWrapper:将基本类型装箱为对应的包装类型。
    • Byte2byte, Short2short, Integer2int, Character2char, Long2long, Float2float, Double2double, Boolean2boolean:将包装类型拆箱为基本类型。
  2. 集合和数组操作

    • genericWrapArray:将数组转换为 WrappedArray 类型,提供了丰富的数组操作方法。
    • wrapRefArray, wrapIntArray, wrapDoubleArray, wrapLongArray, wrapFloatArray, wrapCharArray, wrapByteArray, wrapShortArray, wrapBooleanArray, wrapUnitArray:分别将不同类型的数组转换为相应的 WrappedArray 类型。
    • wrapString:将字符串转换为 WrappedString 类型,提供了丰富的字符串操作方法。
    • unwrapString:将 WrappedString 转换为普通字符串。
  3. 字符串格式化

    • any2stringfmt:将任意类型转换为 StringFormat 类型,提供了格式化字符串的功能。
    • formatted:在字符串上调用,根据给定的格式化字符串返回格式化后的字符串。
  4. 隐式转换

    • ArrowAssoc:将任意类型转换为 ArrowAssoc 类型,提供了箭头操作符(->)。
    • Ensuring:将任意类型转换为 Ensuring 类型,提供了 ensuring 方法用于条件判断。
    • RichException:将 Throwable 对象转换为 RichException 类型,提供了 getStackTraceString 方法用于获取异常堆栈信息。
    • SeqCharSequence:将 IndexedSeq[Char] 转换为 CharSequence 类型。
    • ArrayCharSequence:将 Array[Char] 转换为 CharSequence 类型。
    • StringCanBuildFrom:用于构建字符串的 CanBuildFrom 实例。
  5. 输入输出

    • readLine:从标准输入读取一行字符串。
    • readBoolean, readByte, readShort, readChar, readInt, readLong, readFloat, readDouble:从标准输入读取相应类型的数据。
    • readf, readf1, readf2, readf3:按照给定的格式从标准输入读取数据。
  6. 其他

    • ???:用于标记尚未实现的方法。
    • print, println, printf:打印输出相关的方法。
    • conforms:用于泛型约束,表示类型 A 是类型 A 的子类型。
    • =:=:用于类型相等判断。

示例

  1. 类型装箱和拆箱
val b: Byte = 10
val byteWrapper: java.lang.Byte = byteWrapper(b)

val s: Short = 20
val shortWrapper: java.lang.Short = shortWrapper(s)

val i: Int = 30
val intWrapper: java.lang.Integer = intWrapper(i)

val c: Char = 'a'
val charWrapper: java.lang.Character = charWrapper(c)

val l: Long = 40L
val longWrapper: java.lang.Long = longWrapper(l)

val f: Float = 50.5f
val floatWrapper: java.lang.Float = floatWrapper(f)

val d: Double = 60.6
val doubleWrapper: java.lang.Double = doubleWrapper(d)

val bool: Boolean = true
val booleanWrapper: java.lang.Boolean = booleanWrapper(bool)

val num: java.lang.Integer = 42
val intValue: Int = Integer2int(num)
  1. 集合和数组操作
val arr: Array[Int] = Array(1, 2, 3, 4, 5)
val wrappedArray: mutable.WrappedArray[Int] = genericWrapArray(arr)

val str: String = "Hello, World!"
val wrappedString: immutable.WrappedString = wrapString(str)

val xs: Seq[Char] = Seq('a', 'b', 'c')
val seqCharSequence: CharSequence = seqToCharSequence(xs)

val charArray: Array[Char] = Array('x', 'y', 'z')
val arrayCharSequence: CharSequence = arrayToCharSequence(charArray)
  1. 字符串格式化
val name: String = "Alice"
val age: Int = 25
val formattedString: String = name.formatted("My name is %s and I am %d years old.")
  1. 隐式转换
val x: Int = 10
val arrowAssoc: ArrowAssoc[Int] = any2ArrowAssoc(x)

val y: Double = 3.14
val ensuring: Ensuring[Double] = any2Ensuring(y)

val ex: Throwable = new RuntimeException("Error")
val richException: RichException = exceptionWrapper(ex)

val str: String = "Hello"
val seqCharSequence: CharSequence = seqToCharSequence(str.toIndexedSeq)

val charArray: Array[Char] = Array('a', 'b', 'c')
val arrayCharSequence: CharSequence = arrayToCharSequence(charArray)

val s: String = readLine()
val b: Boolean = readBoolean()
val i: Int = readInt()
  1. 输入输出
val input: String = readLine("Enter your name: ")
val bool: Boolean = readBoolean()
val num: Int = readInt()

中文源码

/** 
  * `Predef`对象提供了在所有Scala编译单元中都可以访问的定义。
  *
  * === 常用类型 ===
  * Predef为常用类型提供了类型别名,例如不可变集合类型[[scala.collection.immutable.Map]]、[[scala.collection.immutable.Set]]以及[[scala.collection.immutable.List]]的构造函数([[scala.collection.immutable.::]]和[[scala.collection.immutable.Nil]])。
  *
  * === 控制台输入输出 ===
  * Predef提供了一些简单的控制台输入输出函数,如`print`、`println`、`readLine`、`readInt`等。这些函数都是[[scala.Console]]提供的函数的别名。
  *
  * === 断言 ===
  * 提供了一组`assert`函数,用于作为记录和动态检查代码中的不变条件的方法。通过在`scala`命令中提供命令行参数`-Xdisable-assertions`,可以在运行时省略`assert`语句。
  * 还提供了适用于静态分析工具的`assert`的变体:`assume`、`require`和`ensuring`。`require`和`ensuring`用于在函数上指定设计契约样式的前置条件和后置条件,
  * 并且这些规范可以被静态分析工具使用。例如:
  * 
  * {{{
  * def addNaturals(nats: List[Int]): Int = {
  *   require(nats forall (_ >= 0), "List contains negative numbers")
  *   nats.foldLeft(0)(_ + _)
  * } ensuring(_ >= 0)
  * }}}
  *
  * `addNaturals`的声明表明传递的整数列表只应包含自然数(即非负数),并且返回的结果也应该是自然数。`require`和`assert`的区别在于,如果条件失败,
  * 则函数的调用者需要负责,而不是在`addNaturals`内部产生逻辑错误。`ensuring`是`assert`的一种形式,它声明了函数返回值的保证。
  *
  * === 隐式转换 ===
  * 这里还定义了一些常用的隐式转换,包括对数字类型的"扩大转换",例如根据需要将`Short`值转换为`Long`值,以及向数组值添加额外的高阶函数。
  * 更详细的说明可以参考[[scala.Array]]的文档。
  */
object Predef extends LowPriorityImplicits with DeprecatedPredef {
  /**
   * 获取类类型的运行时表示。`classOf[T]`相当于Java中的类字面量`T.class`。
   *
   * @example {{{
   * val listClass = classOf[List[_]]
   * // listClass is java.lang.Class[List[_]] = class scala.collection.immutable.List
   *
   * val mapIntString = classOf[Map[Int,String]]
   * // mapIntString is java.lang.Class[Map[Int,String]] = interface scala.collection.immutable.Map
   * }}}
   */
  def classOf[T]: Class[T] = null // 这是一个存根方法,实际的实现由编译器填充。

  type String        = java.lang.String
  type Class[T]      = java.lang.Class[T]

  // 杂项 -----------------------------------------------------
  scala.`package`                         // 强制引用scala包对象。
  scala.collection.immutable.List         // 强制引用Nil, ::。

  type Function[-A, +B] = Function1[A, B]

  type Map[A, +B] = immutable.Map[A, B]
  type Set[A]     = immutable.Set[A]
  val Map         = immutable.Map
  val Set         = immutable.Set

  // Manifest类型、伴生对象和调用方式
  @annotation.implicitNotFound(msg = "No ClassManifest available for ${T}.")
  @deprecated("Use `scala.reflect.ClassTag` instead", "2.10.0")
  type ClassManifest[T] = scala.reflect.ClassManifest[T]
  // TODO: 直到Scala反射不再是试验性的之前,取消此注释
  // @deprecated("This notion doesn't have a corresponding concept in 2.10, because scala.reflect.runtime.universe.TypeTag can capture arbitrary types. Use type tags instead of manifests, and there will be no need in opt manifests.", "2.10.0")
  type OptManifest[T]   = scala.reflect.OptManifest[T]
  @annotation.implicitNotFound(msg = "No Manifest available for ${T}.")
  // TODO: 直到Scala反射不再是试验性的之前,取消此注释
  // @deprecated("Use `scala.reflect.ClassTag` (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0")
  type Manifest[T]      = scala.reflect.Manifest[T]
  @deprecated("Use `scala.reflect.ClassTag` instead", "2.10.0")
  val ClassManifest     = scala.reflect.ClassManifest
  // TODO: 直到Scala反射不再是试验性的之前,取消此注释
  // @deprecated("Use `scala.reflect.ClassTag` (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0")
  val Manifest          = scala.reflect.Manifest
  // TODO: 直到Scala反射不再是试验性的之前,取消此注释
  // @deprecated("This notion doesn't have a corresponding concept in 2.10, because scala.reflect.runtime.universe.TypeTag can capture arbitrary types. Use type tags instead of manifests, and there will be no need in opt manifests.", "2.10.0")
  val NoManifest        = scala.reflect.NoManifest

  // TODO: 直到Scala反射不再是试验性的之前,取消此注释
  // @deprecated("Use scala.reflect.classTag[T] and scala.reflect.runtime.universe.typeTag[T] instead", "2.10.0")
  def manifest[T](implicit m: Manifest[T])           = m
  @deprecated("Use scala.reflect.classTag[T] instead", "2.10.0")
  def classManifest[T](implicit m: ClassManifest[T]) = m
  // TODO: 直到Scala反射不再是试验性的之前,取消此注释
  // @deprecated("This notion doesn't have a corresponding concept in 2.10, because scala.reflect.runtime.universe.TypeTag can capture arbitrary types. Use type tags instead of manifests, and there will be no need in opt manifests.", "2.10.0")
  def optManifest[T](implicit m: OptManifest[T])     = m

  // 对标识函数的微小变体
  def identity[A](x: A): A         = x    // 见`conforms`方法中的隐式版本
  @inline def implicitly[T](implicit e: T) = e    // 从地狱世界召唤隐式值的方法,TODO:当默认情况下启用依赖方法类型时,将其结果类型给予`e.type`,以使内联器有更好的机会知道在调用`implicitly[MatchingStrategy[Option]].zero`等调用中应内联哪个方法
  @inline def locally[T](x: T): T  = x    // 传达意图并避免未锚定的语句

  // 错误和断言 -------------------------------------------------

  // !!! 尽可能删除此内容 - 最好是在2.11中。
  // 由于sbt的编译器接口仍然在0.12.2中调用它,我们还需要一段时间才能摆脱它。
  @deprecated("Use `sys.error(message)` instead", "2.9.0")
  def error(message: String): Nothing = sys.error(message)

  /** 测试一个表达式,如果为false则抛出`AssertionError`。
   *  如果`-Xelide-below`至少是`ASSERTION`,则不会生成对此方法的调用。
   *
   *  @see elidable
   *  @param assertion   要测试的表达式
   */
  @elidable(ASSERTION)
  def assert(assertion: Boolean) {
    if (!assertion)
      throw new java.lang.AssertionError("assertion failed")
  }

  /** 测试一个表达式,如果为false则抛出`AssertionError`。
   *  如果`-Xelide-below`至少是`ASSERTION`,则不会生成对此方法的调用。
   *
   *  @see elidable
   *  @param assertion   要测试的表达式
   *  @param message     失败消息中要包含的字符串
   */
  @elidable(ASSERTION) @inline
  final def assert(assertion: Boolean, message: => Any) {
    if (!assertion)
      throw new java.lang.AssertionError("assertion failed: "+ message)
  }

  /** 测试一个表达式,如果为false则抛出`AssertionError`。
   *  此方法与`assert`只在表达的意图上有所不同:
   *  `assert`包含需要证明的谓词,而`assume`包含静态检查器的公理。如果`-Xelide-below`至少为`ASSERTION`,则不会生成对此方法的调用。
   *
   *  @see elidable
   *  @param assumption   要测试的表达式
   */
  @elidable(ASSERTION)
  def assume(assumption: Boolean) {
    if (!assumption)
      throw new java.lang.AssertionError("assumption failed")
  }

  /** 测试一个表达式,如果为false则抛出`AssertionError`。
   *  此方法与`assert`只在表达的意图上有所不同:
   *  `assert`包含需要证明的谓词,而`assume`包含静态检查器的公理。如果`-Xelide-below`至少为`ASSERTION`,则不会生成对此方法的调用。
   *
   *  @see elidable
   *  @param assumption   要测试的表达式
   *  @param message      失败消息中要包含的字符串
   */
  @elidable(ASSERTION) @inline
  final def assume(assumption: Boolean, message: => Any) {
    if (!assumption)
      throw new java.lang.AssertionError("assumption failed: "+ message)
  }

  /** 测试一个表达式,如果为false则抛出`IllegalArgumentException`。
   *  此方法类似于`assert`,但将违反条件的责任归咎于方法的调用者。
   *
   *  @param requirement   要测试的表达式
   */
  def require(requirement: Boolean) {
    if (!requirement)
      throw new IllegalArgumentException("requirement failed")
  }

  /** 测试一个表达式,如果为false则抛出`IllegalArgumentException`。
   *  此方法类似于`assert`,但将违反条件的责任归咎于方法的调用者。
   *
   *  @param requirement   要测试的表达式
   *  @param message       失败消息中要包含的字符串
   */
  @inline final def require(requirement: Boolean, message: => Any) {
    if (!requirement)
      throw new IllegalArgumentException("requirement failed: "+ message)
  }
}

  /** `???` 用于标记尚未实现的方法。
   *  @throws NotImplementedError
   */
  def ??? : Nothing = throw new NotImplementedError

  // tupling ------------------------------------------------------------

  @deprecated("使用内置的元组语法或 Tuple2 替代", "2.11.0")
  type Pair[+A, +B] = Tuple2[A, B]
  @deprecated("使用内置的元组语法或 Tuple2 替代", "2.11.0")
  object Pair {
    def apply[A, B](x: A, y: B) = Tuple2(x, y)
    def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
  }

  @deprecated("使用内置的元组语法或 Tuple3 替代", "2.11.0")
  type Triple[+A, +B, +C] = Tuple3[A, B, C]
  @deprecated("使用内置的元组语法或 Tuple3 替代", "2.11.0")
  object Triple {
    def apply[A, B, C](x: A, y: B, z: C) = Tuple3(x, y, z)
    def unapply[A, B, C](x: Tuple3[A, B, C]): Option[Tuple3[A, B, C]] = Some(x)
  }

  // implicit classes -----------------------------------------------------

  implicit final class ArrowAssoc[A](private val self: A) extends AnyVal {
    @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(self, y)
    def[B](y: B): Tuple2[A, B] = ->(y)
  }

  implicit final class Ensuring[A](private val self: A) extends AnyVal {
    def ensuring(cond: Boolean): A = { assert(cond); self }
    def ensuring(cond: Boolean, msg: => Any): A = { assert(cond, msg); self }
    def ensuring(cond: A => Boolean): A = { assert(cond(self)); self }
    def ensuring(cond: A => Boolean, msg: => Any): A = { assert(cond(self), msg); self }
  }

  implicit final class StringFormat[A](private val self: A) extends AnyVal {
    /** 根据给定的 `format` 字符串返回格式化后的字符串。
     *  格式化字符串与 `String.format` 相同
     *  (@see java.lang.String.format)。
     */
    @inline def formatted(fmtstr: String): String = fmtstr format self
  }

  // TODO: remove, only needed for binary compatibility of 2.11.0-RC1 with 2.11.0-M8
  // 注意 `private[scala]` 在字节码中变为 `public`
  private[scala] final class StringAdd[A](private val self: A) extends AnyVal {
    def +(other: String): String = String.valueOf(self) + other
  }
  private[scala] def StringAdd(x: Any): Any = new StringAdd(x)

  // SI-8229 保留了 2.11.0 前的名称,以便在隐藏此隐式转换时保持源代码兼容性
  implicit final class any2stringadd[A](private val self: A) extends AnyVal {
    def +(other: String): String = String.valueOf(self) + other
  }

  implicit final class RichException(private val self: Throwable) extends AnyVal {
    import scala.compat.Platform.EOL
    @deprecated("使用 Throwable#getStackTrace", "2.11.0") def getStackTraceString = self.getStackTrace().mkString("", EOL, EOL)
  }

  implicit final class SeqCharSequence(val __sequenceOfChars: scala.collection.IndexedSeq[Char]) extends CharSequence {
    def length: Int                                     = __sequenceOfChars.length
    def charAt(index: Int): Char                        = __sequenceOfChars(index)
    def subSequence(start: Int, end: Int): CharSequence = new SeqCharSequence(__sequenceOfChars.slice(start, end))
    override def toString                               = __sequenceOfChars mkString ""
  }

  implicit final class ArrayCharSequence(val __arrayOfChars: Array[Char]) extends CharSequence {
    def length: Int                                     = __arrayOfChars.length
    def charAt(index: Int): Char                        = __arrayOfChars(index)
    def subSequence(start: Int, end: Int): CharSequence = new runtime.ArrayCharSequence(__arrayOfChars, start, end)
    override def toString                               = __arrayOfChars mkString ""
  }

  implicit val StringCanBuildFrom: CanBuildFrom[String, Char, String] = new CanBuildFrom[String, Char, String] {
    def apply(from: String) = apply()
    def apply()             = mutable.StringBuilder.newBuilder
  }

  @inline implicit def augmentString(x: String): StringOps = new StringOps(x)
  @inline implicit def unaugmentString(x: StringOps): String = x.repr

  // printing -----------------------------------------------------------

  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.print(text.format(xs: _*))

  // views --------------------------------------------------------------

  implicit def tuple2ToZippedOps[T1, T2](x: (T1, T2))                           = new runtime.Tuple2Zipped.Ops(x)
  implicit def tuple3ToZippedOps[T1, T2, T3](x: (T1, T2, T3))                   = new runtime.Tuple3Zipped.Ops(x)

  implicit def genericArrayOps[T](xs: Array[T]): ArrayOps[T] = (xs match {
    case x: Array[AnyRef]  => refArrayOps[AnyRef](x)
    case x: Array[Boolean] => booleanArrayOps(x)
    case x: Array[Byte]    => byteArrayOps(x)
    case x: Array[Char]    => charArrayOps(x)
    case x: Array[Double]  => doubleArrayOps(x)
    case x: Array[Float]   => floatArrayOps(x)
    case x: Array[Int]     => intArrayOps(x)
    case x: Array[Long]    => longArrayOps(x)
    case x: Array[Short]   => shortArrayOps(x)
    case x: Array[Unit]    => unitArrayOps(x)
    case null              => null
  }).asInstanceOf[ArrayOps[T]]

  implicit def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps.ofBoolean(xs)
  implicit def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte]          = new ArrayOps.ofByte(xs)
  implicit def charArrayOps(xs: Array[Char]): ArrayOps[Char]          = new ArrayOps.ofChar(xs)
  implicit def doubleArrayOps(xs: Array[Double]): ArrayOps[Double]    = new ArrayOps.ofDouble(xs)
  implicit def floatArrayOps(xs: Array[Float]): ArrayOps[Float]       = new ArrayOps.ofFloat(xs)
  implicit def intArrayOps(xs: Array[Int]): ArrayOps[Int]             = new ArrayOps.ofInt(xs)
  implicit def longArrayOps(xs: Array[Long]): ArrayOps[Long]          = new ArrayOps.ofLong(xs)
  implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T]    = new ArrayOps.ofRef[T](xs)
  implicit def shortArrayOps(xs: Array[Short]): ArrayOps[Short]       = new ArrayOps.ofShort(xs)
  implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit]          = new ArrayOps.ofUnit(xs)

  // "Autoboxing" and "Autounboxing" ---------------------------------------------------

  implicit def byte2Byte(x: Byte)           = java.lang.Byte.valueOf(x)
  implicit def short2Short(x: Short)        = java.lang.Short.valueOf(x)
  implicit def char2Character(x: Char)      = java.lang.Character.valueOf(x)
  implicit def int2Integer(x: Int)          = java.lang.Integer.valueOf(x)
  implicit def long2Long(x: Long)           = java.lang.Long.valueOf(x)
  implicit def float2Float(x: Float)        = java.lang.Float.valueOf(x)
  implicit def double2Double(x: Double)     = java.lang.Double.valueOf(x)
  implicit def boolean2Boolean(x: Boolean)  = java.lang.Boolean.valueOf(x)

  implicit def Byte2byte(x: java.lang.Byte): Byte             = x.byteValue
  implicit def Short2short(x: java.lang.Short): Short         = x.shortValue
  implicit def Character2char(x: java.lang.Character): Char   = x.charValue
  implicit def Integer2int(x: java.lang.Integer): Int         = x.intValue
  implicit def Long2long(x: java.lang.Long): Long             = x.longValue
  implicit def Float2float(x: java.lang.Float): Float         = x.floatValue
  implicit def Double2double(x: java.lang.Double): Double     = x.doubleValue
  implicit def Boolean2boolean(x: java.lang.Boolean): Boolean = x.booleanValue

  // Type Constraints --------------------------------------------------------------

  /**
   * `A <:< B` 的实例表示 `A` 是 `B` 的子类型。
   * 要求一个隐式参数的类型为 `A <:< B` 可以表达泛化约束 `A <: B`。
   *
   * @note 我们需要一个新的类型构造函数 `<:<` 和证据 `conforms`,
   * 因为重用 `Function1` 和 `identity` 会导致类型错误的歧义(推断出 `any2stringadd`)。
   *
   * 要对方法参数列表中范围内的任何抽象类型 T 进行约束(不仅限于方法自身的类型参数),
   * 只需添加一个隐式参数,其类型为 `T <:< U`,其中 `U` 是所需的上界;
   * 或者对于下界,使用:`L <:< T`,其中 `L` 是所需的下界。
   *
   * 部分贡献者:Jason Zaugg。
   */
  @implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
  sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
  private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
  // 以避免被用户定义的同名方法(SI-7788)意外遮蔽此方法
  // 集合依赖于此方法。
  implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]

  @deprecated("Use `implicitly[T <:< U]` or `identity` instead.", "2.11.0")
  def conforms[A]: A <:< A = $conforms[A]

  /** `A =:= B` 的实例表示类型 `A` 和 `B` 是相等的。
   *
   * @see `<:<` 用于表达子类型约束
   */
  @implicitNotFound(msg = "Cannot prove that ${From} =:= ${To}.")
  sealed abstract class =:=[From, To] extends (From => To) with Serializable
  private[this] final val singleton_=:= = new =:=[Any,Any] { def apply(x: Any): Any = x }
  object =:= {
     implicit def tpEquals[A]: A =:= A = singleton_=:=.asInstanceOf[A =:= A]
  }

  /** 一种始终存在隐式值的类型。
   *  @see [[scala.Array$]],方法 `fallbackCanBuildFrom`
   */
  class DummyImplicit

  object DummyImplicit {

    /** 产生一个 `DummyImplicit` 的隐式值。
     *   @see [[scala.Array$]],方法 `fallbackCanBuildFrom`
     */
    implicit def dummyImplicit: DummyImplicit = new DummyImplicit
  }
}

private[scala] trait DeprecatedPredef {
  self: Predef.type =>

  // 对直接调用这些方法的人来说,这里是过时的存根。
  @deprecated("使用 `ArrowAssoc`", "2.11.0") def any2ArrowAssoc[A](x: A): ArrowAssoc[A]                                      = new ArrowAssoc(x)
  @deprecated("使用 `Ensuring`", "2.11.0") def any2Ensuring[A](x: A): Ensuring[A]                                            = new Ensuring(x)
  @deprecated("使用 `StringFormat`", "2.11.0") def any2stringfmt(x: Any): StringFormat[Any]                                  = new StringFormat(x)
  @deprecated("直接使用 `Throwable`", "2.11.0") def exceptionWrapper(exc: Throwable)                                    = new RichException(exc)
  @deprecated("使用 `SeqCharSequence`", "2.11.0") def seqToCharSequence(xs: scala.collection.IndexedSeq[Char]): CharSequence = new SeqCharSequence(xs)
  @deprecated("使用 `ArrayCharSequence`", "2.11.0") def arrayToCharSequence(xs: Array[Char]): CharSequence                   = new ArrayCharSequence(xs)

  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readLine(): String                 = StdIn.readLine()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readLine(text: String, args: Any*) = StdIn.readLine(text, args: _*)
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readBoolean()                      = StdIn.readBoolean()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readByte()                         = StdIn.readByte()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readShort()                        = StdIn.readShort()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readChar()                         = StdIn.readChar()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readInt()                          = StdIn.readInt()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readLong()                         = StdIn.readLong()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readFloat()                        = StdIn.readFloat()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readDouble()                       = StdIn.readDouble()
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readf(format: String)              = StdIn.readf(format)
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readf1(format: String)             = StdIn.readf1(format)
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readf2(format: String)             = StdIn.readf2(format)
  @deprecated("使用 `scala.io.StdIn` 中的方法", "2.11.0") def readf3(format: String)             = StdIn.readf3(format)
}

/** `LowPriorityImplicits` 类提供了在所有 Scala 编译单元中都有效的隐式值,
*  但它们在 `Predef` 对象中被优先级更高的转换部分覆盖。
*
*  @author  Martin Odersky
*  @since 2.8
*/
// SI-7335 Predef 的父类在同一个编译单元中定义,以避免在没有先前编译的标准库副本的情况下出现循环引用错误。
private[scala] abstract class LowPriorityImplicits {
  import mutable.WrappedArray
  import immutable.WrappedString

  /** 我们更喜欢 java.lang.* 的包装类型而不是这些包装器,
   *  因为可能存在冲突。冲突的原因是这些包装器需要实现 ScalaNumber,
   *  以便具有对称的 equals 方法,但这也意味着需要实现 java.lang.Number。
   *
   *  注意 - 这些是内联的,因为它们是值类,但是
   *  对 xxxWrapper 的调用没有消除,即使它什么都不做。
   *  即使内联,每个调用点都会执行对 Predef 的 MODULE$ 的无操作检索,
   *  因为加载 Predef 可能具有副作用!
   */
  @inline implicit def byteWrapper(x: Byte)       = new runtime.RichByte(x)
  @inline implicit def shortWrapper(x: Short)     = new runtime.RichShort(x)
  @inline implicit def intWrapper(x: Int)         = new runtime.RichInt(x)
  @inline implicit def charWrapper(c: Char)       = new runtime.RichChar(c)
  @inline implicit def longWrapper(x: Long)       = new runtime.RichLong(x)
  @inline implicit def floatWrapper(x: Float)     = new runtime.RichFloat(x)
  @inline implicit def doubleWrapper(x: Double)   = new runtime.RichDouble(x)
  @inline implicit def booleanWrapper(x: Boolean) = new runtime.RichBoolean(x)

  implicit def genericWrapArray[T](xs: Array[T]): WrappedArray[T] =
    if (xs eq null) null
    else WrappedArray.make(xs)

  // 由于 JVM 认为数组是协变的,所以一个长度为 0 的 Array[AnyRef]
  // 对于所有 T <: AnyRef 来说和另一个一样好。为了避免通过这个隐式转换创建 100,000,000 个唯一的数组,
  // 让我们共享一个。
  implicit def wrapRefArray[T <: AnyRef](xs: Array[T]): WrappedArray[T] = {
    if (xs eq null) null
    else if (xs.length == 0) WrappedArray.empty[T]
    else new WrappedArray.ofRef[T](xs)
  }

  implicit def wrapIntArray(xs: Array[Int]): WrappedArray[Int] = if (xs ne null) new WrappedArray.ofInt(xs) else null
  implicit def wrapDoubleArray(xs: Array[Double]): WrappedArray[Double] = if (xs ne null) new WrappedArray.ofDouble(xs) else null
  implicit def wrapLongArray(xs: Array[Long]): WrappedArray[Long] = if (xs ne null) new WrappedArray.ofLong(xs) else null
  implicit def wrapFloatArray(xs: Array[Float]): WrappedArray[Float] = if (xs ne null) new WrappedArray.ofFloat(xs) else null
  implicit def wrapCharArray(xs: Array[Char]): WrappedArray[Char] = if (xs ne null) new WrappedArray.ofChar(xs) else null
  implicit def wrapByteArray(xs: Array[Byte]): WrappedArray[Byte] = if (xs ne null) new WrappedArray.ofByte(xs) else null
  implicit def wrapShortArray(xs: Array[Short]): WrappedArray[Short] = if (xs ne null) new WrappedArray.ofShort(xs) else null
  implicit def wrapBooleanArray(xs: Array[Boolean]): WrappedArray[Boolean] = if (xs ne null) new WrappedArray.ofBoolean(xs) else null
  implicit def wrapUnitArray(xs: Array[Unit]): WrappedArray[Unit] = if (xs ne null) new WrappedArray.ofUnit(xs) else null

  implicit def wrapString(s: String): WrappedString = if (s ne null) new WrappedString(s) else null
  implicit def unwrapString(ws: WrappedString): String = if (ws ne null) ws.self else null

  implicit def fallbackStringCanBuildFrom[T]: CanBuildFrom[String, T, immutable.IndexedSeq[T]] =
    new CanBuildFrom[String, T, immutable.IndexedSeq[T]] {
      def apply(from: String) = immutable.IndexedSeq.newBuilder[T]
      def apply() = immutable.IndexedSeq.newBuilder[T]
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigDataMLApplication

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值