Scala Predef对象详解

Scala Predef对象

Scala程序设计 第2版 - 原版.pdf 下载:https://download.csdn.net/download/u014646662/10805074

目录:

1.Predef源码

2.类型装换

3.类型定义

4.条件检查方法

5.输入输出方法

6.其他

对人工智能感兴趣的同学,可以点击以下链接:

现在人工智能非常火爆,很多朋友都想学,但是一般的教程都是为博硕生准备的,太难看懂了。最近发现了一个非常适合小白入门的教程,不仅通俗易懂而且还很风趣幽默。所以忍不住分享一下给大家。点这里可以跳转到教程。

https://www.cbedai.net/u014646662

1 Predef源码

为了方便起见,只要你编译代码,Scala 编译器就会自动导入顶层Scala 包(名为scala)以及在java.lang 包(就像javac 的)中的定义。因此,许多常见的Java 和Scala 类型都可以不经过明显地导入或提供完整的名称就可以使用。另外,编译器还导入了Predef 对象中的一些定。接下来,我们来详细了解Predef 提供的特性。需要注意的是,Scala 2.11 版本的Predef 引入了很多变化,其中大部分是不可见的。

看一看源码:

package scala
object Predef extends scala.LowPriorityImplicits with scala.DeprecatedPredef {
  def classOf[T] : Predef.Class[T] = { /* compiled code */ }
  type Class[T] = java.lang.Class[T]
  type String = java.lang.String
  type Function[-A, +B] = scala.Function1[A, B]
  type Map[A, +B] = scala.collection.immutable.Map[A, B]
  type Set[A] = scala.collection.immutable.Set[A]
  val Map : scala.collection.immutable.Map.type = { /* compiled code */ }
  val Set : scala.collection.immutable.Set.type = { /* compiled code */ }
  @scala.deprecated("use `scala.reflect.ClassTag` instead", "2.10.0")
  @scala.annotation.implicitNotFound("No ClassManifest available for ${T}.")
  type ClassManifest[T] = scala.reflect.ClassManifest[T]
  type OptManifest[T] = scala.reflect.OptManifest[T]
  @scala.annotation.implicitNotFound("No Manifest available for ${T}.")
  type Manifest[T] = scala.reflect.Manifest[T]
  @scala.deprecated("use `scala.reflect.ClassTag` instead", "2.10.0")
  val ClassManifest : scala.reflect.ClassManifestFactory.type = { /* compiled code */ }
  val Manifest : scala.reflect.ManifestFactory.type = { /* compiled code */ }
  val NoManifest : scala.reflect.NoManifest.type = { /* compiled code */ }
  def manifest[T](implicit m : Predef.Manifest[T]) : Predef.Manifest[T] = { /* compiled code */ }
  @scala.deprecated("use scala.reflect.classTag[T] instead", "2.10.0")
  def classManifest[T](implicit m : Predef.ClassManifest[T]) : Predef.ClassManifest[T] = { /* compiled code */ }
  def optManifest[T](implicit m : Predef.OptManifest[T]) : Predef.OptManifest[T] = { /* compiled code */ }
  @scala.inline
  def identity[A](x : A) : A = { /* compiled code */ }
  @scala.inline
  def implicitly[T](implicit e : T) : T = { /* compiled code */ }
  @scala.inline
  def locally[T](x : T) : T = { /* compiled code */ }
  @scala.annotation.elidable(2000)
  def assert(assertion : scala.Boolean) : scala.Unit = { /* compiled code */ }
  @scala.inline
  @scala.annotation.elidable(2000)
  final def assert(assertion : scala.Boolean, message : => scala.Any) : scala.Unit = { /* compiled code */ }
  @scala.annotation.elidable(2000)
  def assume(assumption : scala.Boolean) : scala.Unit = { /* compiled code */ }
  @scala.inline
  @scala.annotation.elidable(2000)
  final def assume(assumption : scala.Boolean, message : => scala.Any) : scala.Unit = { /* compiled code */ }
  def require(requirement : scala.Boolean) : scala.Unit = { /* compiled code */ }
  @scala.inline
  final def require(requirement : scala.Boolean, message : => scala.Any) : scala.Unit = { /* compiled code */ }
  def ??? : scala.Nothing = { /* compiled code */ }
  @scala.deprecated("use built-in tuple syntax or Tuple2 instead", "2.11.0")
  type Pair[+A, +B] = scala.Tuple2[A, B]
  @scala.deprecated("use built-in tuple syntax or Tuple2 instead", "2.11.0")
  object Pair extends scala.AnyRef {
    def apply[A, B](x : A, y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
    def unapply[A, B](x : scala.Tuple2[A, B]) : scala.Option[scala.Tuple2[A, B]] = { /* compiled code */ }
  }
  @scala.deprecated("use built-in tuple syntax or Tuple3 instead", "2.11.0")
  type Triple[+A, +B, +C] = scala.Tuple3[A, B, C]
  @scala.deprecated("use built-in tuple syntax or Tuple3 instead", "2.11.0")
  object Triple extends scala.AnyRef {
    def apply[A, B, C](x : A, y : B, z : C) : scala.Tuple3[A, B, C] = { /* compiled code */ }
    def unapply[A, B, C](x : scala.Tuple3[A, B, C]) : scala.Option[scala.Tuple3[A, B, C]] = { /* compiled code */ }
  }
  implicit final class ArrowAssoc[A](self : A) extends scala.AnyVal {
    @scala.inline
    def ->[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
    def →[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
  }
  implicit final class Ensuring[A](self : A) extends scala.AnyVal {
    def ensuring(cond : scala.Boolean) : A = { /* compiled code */ }
    def ensuring(cond : scala.Boolean, msg : => scala.Any) : A = { /* compiled code */ }
    def ensuring(cond : scala.Function1[A, scala.Boolean]) : A = { /* compiled code */ }
    def ensuring(cond : scala.Function1[A, scala.Boolean], msg : => scala.Any) : A = { /* compiled code */ }
  }
  implicit final class StringFormat[A](self : A) extends scala.AnyVal {
    @scala.inline
    def formatted(fmtstr : Predef.String) : Predef.String = { /* compiled code */ }
  }
  implicit final class any2stringadd[A](self : A) extends scala.AnyVal {
    def +(other : Predef.String) : Predef.String = { /* compiled code */ }
  }
  implicit final class RichException(self : scala.Throwable) extends scala.AnyVal {
    @scala.deprecated("use Throwable#getStackTrace", "2.11.0")
    def getStackTraceString : _root_.scala.Predef.String = { /* compiled code */ }
  }
  implicit final class SeqCharSequence(@scala.deprecated("will be made private", "2.12.0") val __sequenceOfChars : scala.collection.IndexedSeq[scala.Char]) extends java.lang.Object with java.lang.CharSequence {
    def length() : scala.Int = { /* compiled code */ }
    def charAt(index : scala.Int) : scala.Char = { /* compiled code */ }
    def subSequence(start : scala.Int, end : scala.Int) : java.lang.CharSequence = { /* compiled code */ }
    override def toString() : _root_.scala.Predef.String = { /* compiled code */ }
  }
  implicit final class ArrayCharSequence(@scala.deprecated("will be made private", "2.12.0") val __arrayOfChars : scala.Array[scala.Char]) extends java.lang.Object with java.lang.CharSequence {
    def length() : scala.Int = { /* compiled code */ }
    def charAt(index : scala.Int) : scala.Char = { /* compiled code */ }
    def subSequence(start : scala.Int, end : scala.Int) : java.lang.CharSequence = { /* compiled code */ }
    override def toString() : _root_.scala.Predef.String = { /* compiled code */ }
  }
  implicit val StringCanBuildFrom : scala.collection.generic.CanBuildFrom[Predef.String, scala.Char, Predef.String] = { /* compiled code */ }
  @scala.inline
  implicit def augmentString(x : Predef.String) : scala.collection.immutable.StringOps = { /* compiled code */ }
  @scala.inline
  implicit def unaugmentString(x : scala.collection.immutable.StringOps) : Predef.String = { /* compiled code */ }
  def print(x : scala.Any) : scala.Unit = { /* compiled code */ }
  def println() : scala.Unit = { /* compiled code */ }
  def println(x : scala.Any) : scala.Unit = { /* compiled code */ }
  def printf(text : Predef.String, xs : scala.Any*) : scala.Unit = { /* compiled code */ }
  implicit def tuple2ToZippedOps[T1, T2](x : scala.Tuple2[T1, T2]) : scala.runtime.Tuple2Zipped.Ops[T1, T2] = { /* compiled code */ }
  implicit def tuple3ToZippedOps[T1, T2, T3](x : scala.Tuple3[T1, T2, T3]) : scala.runtime.Tuple3Zipped.Ops[T1, T2, T3] = { /* compiled code */ }
  implicit def genericArrayOps[T](xs : scala.Array[T]) : scala.collection.mutable.ArrayOps[T] = { /* compiled code */ }
  implicit def booleanArrayOps(xs : scala.Array[scala.Boolean]) : scala.collection.mutable.ArrayOps.ofBoolean = { /* compiled code */ }
  implicit def byteArrayOps(xs : scala.Array[scala.Byte]) : scala.collection.mutable.ArrayOps.ofByte = { /* compiled code */ }
  implicit def charArrayOps(xs : scala.Array[scala.Char]) : scala.collection.mutable.ArrayOps.ofChar = { /* compiled code */ }
  implicit def doubleArrayOps(xs : scala.Array[scala.Double]) : scala.collection.mutable.ArrayOps.ofDouble = { /* compiled code */ }
  implicit def floatArrayOps(xs : scala.Array[scala.Float]) : scala.collection.mutable.ArrayOps.ofFloat = { /* compiled code */ }
  implicit def intArrayOps(xs : scala.Array[scala.Int]) : scala.collection.mutable.ArrayOps.ofInt = { /* compiled code */ }
  implicit def longArrayOps(xs : scala.Array[scala.Long]) : scala.collection.mutable.ArrayOps.ofLong = { /* compiled code */ }
  implicit def refArrayOps[T <: scala.AnyRef](xs : scala.Array[T]) : scala.collection.mutable.ArrayOps.ofRef[T] = { /* compiled code */ }
  implicit def shortArrayOps(xs : scala.Array[scala.Short]) : scala.collection.mutable.ArrayOps.ofShort = { /* compiled code */ }
  implicit def unitArrayOps(xs : scala.Array[scala.Unit]) : scala.collection.mutable.ArrayOps.ofUnit = { /* compiled code */ }
  implicit def byte2Byte(x : scala.Byte) : java.lang.Byte = { /* compiled code */ }
  implicit def short2Short(x : scala.Short) : java.lang.Short = { /* compiled code */ }
  implicit def char2Character(x : scala.Char) : java.lang.Character = { /* compiled code */ }
  implicit def int2Integer(x : scala.Int) : java.lang.Integer = { /* compiled code */ }
  implicit def long2Long(x : scala.Long) : java.lang.Long = { /* compiled code */ }
  implicit def float2Float(x : scala.Float) : java.lang.Float = { /* compiled code */ }
  implicit def double2Double(x : scala.Double) : java.lang.Double = { /* compiled code */ }
  implicit def boolean2Boolean(x : scala.Boolean) : java.lang.Boolean = { /* compiled code */ }
  implicit def Byte2byte(x : java.lang.Byte) : scala.Byte = { /* compiled code */ }
  implicit def Short2short(x : java.lang.Short) : scala.Short = { /* compiled code */ }
  implicit def Character2char(x : java.lang.Character) : scala.Char = { /* compiled code */ }
  implicit def Integer2int(x : java.lang.Integer) : scala.Int = { /* compiled code */ }
  implicit def Long2long(x : java.lang.Long) : scala.Long = { /* compiled code */ }
  implicit def Float2float(x : java.lang.Float) : scala.Float = { /* compiled code */ }
  implicit def Double2double(x : java.lang.Double) : scala.Double = { /* compiled code */ }
  implicit def Boolean2boolean(x : java.lang.Boolean) : scala.Boolean = { /* compiled code */ }
  @scala.annotation.implicitNotFound("Cannot prove that ${From} <:< ${To}.")
  sealed abstract class <:<[-From, +To]() extends scala.AnyRef with scala.Function1[From, To] with scala.Serializable {
    
  }
  implicit def $conforms[A] : Predef.<:<[A, A] = { /* compiled code */ }
  @scala.deprecated("use `implicitly[T <:< U]` or `identity` instead.", "2.11.0")
  def conforms[A] : Predef.<:<[A, A] = { /* compiled code */ }
  @scala.annotation.implicitNotFound("Cannot prove that ${From} =:= ${To}.")
  sealed abstract class =:=[From, To]() extends scala.AnyRef with scala.Function1[From, To] with scala.Serializable {
    
  }
  object =:= extends scala.AnyRef with scala.Serializable {
    implicit def tpEquals[A] : Predef.=:=[A, A] = { /* compiled code */ }
  }
  class DummyImplicit() extends scala.AnyRef {
  }
  object DummyImplicit extends scala.AnyRef {
    implicit def dummyImplicit : Predef.DummyImplicit = { /* compiled code */ }
  }
}

2 类型转换

implicit def byte2Byte(x : scala.Byte) : java.lang.Byte = { /* compiled code */ }
  implicit def short2Short(x : scala.Short) : java.lang.Short = { /* compiled code */ }
  implicit def char2Character(x : scala.Char) : java.lang.Character = { /* compiled code */ }
  implicit def int2Integer(x : scala.Int) : java.lang.Integer = { /* compiled code */ }
  implicit def long2Long(x : scala.Long) : java.lang.Long = { /* compiled code */ }
  implicit def float2Float(x : scala.Float) : java.lang.Float = { /* compiled code */ }
  implicit def double2Double(x : scala.Double) : java.lang.Double = { /* compiled code */ }
  implicit def boolean2Boolean(x : scala.Boolean) : java.lang.Boolean = { /* compiled code */ }
  implicit def Byte2byte(x : java.lang.Byte) : scala.Byte = { /* compiled code */ }
  implicit def Short2short(x : java.lang.Short) : scala.Short = { /* compiled code */ }
  implicit def Character2char(x : java.lang.Character) : scala.Char = { /* compiled code */ }
  implicit def Integer2int(x : java.lang.Integer) : scala.Int = { /* compiled code */ }
  implicit def Long2long(x : java.lang.Long) : scala.Long = { /* compiled code */ }
  implicit def Float2float(x : java.lang.Float) : scala.Float = { /* compiled code */ }
  implicit def Double2double(x : java.lang.Double) : scala.Double = { /* compiled code */ }
  implicit def Boolean2boolean(x : java.lang.Boolean) : scala.Boolean = { /* compiled code */ }

3 类型定义

Predef 定义了若干的类型及类型别名。为了鼓励使用不可变集合,Predef 为最常用的不可变集合定义了别名:

type Class[T] = java.lang.Class[T]
type String = java.lang.String
type Map[A, +B] = scala.collection.immutable.Map[A, B]
type Set[A] = scala.collection.immutable.Set[A]
type Function[-A, +B] = scala.Function1[A, B]
val Map : scala.collection.immutable.Map.type = { /* compiled code */ }
val Set : scala.collection.immutable.Set.type = { /* compiled code */ }

支持类型推断的其他一些Predef 类型。

我们经常使用a -> b(或等价的a → b)这种写法:

object Test {
  def main(args: Array[String]): Unit = {

    val a = (1, "one")
    val b = 1 -> "one"
    val c = 1 → "one"
    println(a) //输出:(1,one)
    println(b) //输出:(1,one)
    println(c) //输出:(1,one)
    val map = Map("one" -> 1, "two" -> 2)
    println(map) //输出:Map(one -> 1, two -> 2)
  }
}

事实上,Scala 根本不知道a -> b 意味着什么,因此上述方法并非没有意义。这种“字面量”格式实际上运用了方法-> 和一个特殊的Scala 特性——隐式转换。通过运用隐式转换,我们可以在任意两种类型值之间插入函数->。与此同时,由于a -> b 并不是元组的字面量语法,因此Scala 必须通过某些方式将该表达式转化为元组(a, b)。

很明显,->之所以能用,就是因为我们已经把->方法定义好了,也就是 ArrowAssoc的->方法,源码如下

  implicit final class ArrowAssoc[A](self : A) extends scala.AnyVal {
    @scala.inline
    def ->[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
    def →[B](y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
  }

在此只因关键字implicit起的作用,具体执行过程:

(1) 编译器发现我们试图对String 对象执行-> 方法(例如“ one” -> 1)。
(2) 由于String 未定义-> 方法,编译器将检查当前作用域中是否存在定义了该方法的隐式转换。
(3) 编译器发现了ArrowAssoc 类。
(4) 编译器将创建ArrowAssoc 对象,并向其传入one 字符串。
(5) 之后,编译器将解析表达式中的-> 1 部分代码,并确认了整个表达式的类型与Map.apply 方法的预期类型相吻合,即两者均为pair 实例。

如果希望执行隐式转换,那么在声明时必须使用implicit 关键字,能够执行隐式转换的无外乎两类:构造方法中只接受单一参数的类型或者是只接受单一参数的方法。

为了限定参数类型,Scala有了隐式证据<:<,在哪里用到了呢?

package cn.com.tengen.test.obj

object Test {
  def main(args: Array[String]): Unit = {

    val map = Map("one" -> 1, "two" -> 2)
    println(map.toMap) //输出:Map(one -> 1, two -> 2)

    val list1 = List((1,"aa"),(2,"bb"),(3,"cc"),(4,"dd"))
    println(list1.toMap) //Map(1 -> aa, 2 -> bb, 3 -> cc, 4 -> dd)

    val list2 = List(1,2,3,4)
    println(list2.toMap) //抛出异常
  }
}
  @scala.annotation.implicitNotFound("Cannot prove that ${From} <:< ${To}.")
  sealed abstract class <:<[-From, +To]() extends scala.AnyRef with scala.Function1[From, To] with scala.Serializable {
    
  }
package scala.collection

trait TraversableOnce[+A] extends scala.Any with scala.collection.GenTraversableOnce[A] {
    ...
  def toMap[T, U](implicit ev: _root_.scala.Predef.<:<[A, scala.Tuple2[T, U]]): scala.collection.immutable.Map[T, U] = {
    /* compiled code */
  }
    ...
}

4 条件检查方法

有时你希望断言某条件为真,希望它“快速失败”(尤其在测试时)。Predef 定义了许多有助于达到这个目的的方法。

• def assert(assertion: Boolean)
测试条件是否为真,如果不为真,抛出java.lang.AssertionError 异常。
• def assert(assertion: Boolean, message: => Any)
类似前面的assert,但增加了一个可选参数,该参数将被转为错误信息字符串。
• def assume(assertion: Boolean)
与assert 相同,但其表示当一段代码块(如方法)正确时,条件才为真。
• def assume(assertion: Boolean, message: => Any)
类似前面的assume,但增加了一个可选参数,该参数将被转为错误信息字符串。
• def require(requirement: Boolean)
与assume 相同,但根据Scaladoc,其含义是调用方是否满足某些条件,也可以表示某个实现不能得出特定的结果。
• def require(requirement: Boolean, message: => Any)
类似前面的require,但增加了一个可选参数,该参数将被转为错误信息字符串。

5 输入输出方法

Scala把数据打印到控制台,这是我们经常做的操作,其实他也是Predef定义的。Predef 为我们提供了四种将字符串打印到stdout 的形式。

  def print(x : scala.Any) : scala.Unit = { /* compiled code */ }
  def println() : scala.Unit = { /* compiled code */ }
  def println(x : scala.Any) : scala.Unit = { /* compiled code */ }
  def printf(text : Predef.String, xs : scala.Any*) : scala.Unit = { /* compiled code */ }

• def print(x: Any): Unit
将x 转为字符串,然后写到标准输出,结尾不会自动添加换行。
• def printf(format: String, xs: Any*): Unit
用format 和其他参数xs 对printf 风格的字符串进行格式化,然后将结果写到标准输出,结尾不会自动添加换行。
• def println(x: Any): Unit
类似print,但结尾会自动添加换行。
• def println(): Unit
向标准输出打印空行。

在老的版本中(2.12之前)Predef提供了相当多的输入方法:

@scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readLine() : DeprecatedPredef.super[Predef/*scala.Predef*/].String = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readLine(text : DeprecatedPredef.super[Predef/*scala.Predef*/].String, args : scala.Any*) : _root_.scala.Predef.String = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readBoolean() : scala.Boolean = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readByte() : scala.Byte = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readShort() : scala.Short = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readChar() : scala.Char = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readInt() : scala.Int = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readLong() : scala.Long = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readFloat() : scala.Float = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readDouble() : scala.Double = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readf(format : DeprecatedPredef.super[Predef/*scala.Predef*/].String) : scala.List[scala.Any] = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readf1(format : DeprecatedPredef.super[Predef/*scala.Predef*/].String) : scala.Any = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readf2(format : DeprecatedPredef.super[Predef/*scala.Predef*/].String) : scala.Tuple2[scala.Any, scala.Any] = { /* compiled code */ }
  @scala.deprecated("use the method in `scala.io.StdIn`", "2.11.0")
  def readf3(format : DeprecatedPredef.super[Predef/*scala.Predef*/].String) : scala.Tuple3[scala.Any, scala.Any, scala.Any] = { /* compiled code */ }

• def readBoolean(): Boolean
从标准输入的一个整行中读取一个Boolean 值。
• def readByte(): Byte
从标准输入的一个整行中读取一个Byte 值。
• def readChar(): Char
从标准输入的一个整行中读取一个Char 值。
• def readDouble(): Double
从标准输入的一个整行中读取一个Double 值。
• def readFloat(): Float
从标准输入的一个整行中读取一个Float 值。
• def readInt(): Int
从标准输入的一个整行中读取一个Int 值。
• def readLine(text: String, args: Any*): String
向标准输出中打印格式化的提示文本,并从标准输入中读取一整行字符串。
• def readLine(): String
从标准输入中读取一整行字符串。
• def readLong(): Long
从标准输入的一个整行中读取一个Long 值。
• def readShort(): Short
从标准输入的一个整行中读取一个Short 值。
• def readf(format: String): List[Any]
根据format 中的区分符号,从标准输入中读取格式化输入。
• def readf1(format: String): Any
根据format 中的区分符号,从标准输入中读取格式化输入。并根据format 的指定,返回提取的第一个值。

• def readf2(format: String): (Any, Any)
根据format 中的区分符号,从标准输入中读取格式化输入。并根据format 的指定,返回提取的前两个值。
• def readf3(format: String): (Any, Any, Any)
根据format 中的区分符号,从标准输入中读取格式化输入。并根据format 的指定,返回提取的前三个值。

在输入时也可以选择Java的方式:

  val read:Scanner = new Scanner(System.in)
  val line = read.nextLine()
  val b = read.nextByte()
  val s = read.nextShort()
  val i = read.nextInt()
  val f = read.nextFloat()
  val d = read.nextDouble()
  val l = read.nextLong()
  val bool = read.nextBoolean()

6 杂项方法

1 ???

在一个尚未实现的方法的方法体中调用。它为方法提供了具体的定义,允许编译器将方法所属的类型视为具体(与抽象对应)的类。然而,如果调用该方法,就会抛出scala.NotImplementedError 异常。源码如下:

def ??? : scala.Nothing = { /* compiled code */ }

2 identity

直接返回参数x。在将方法传给组合器(combinator)时,如果不需要进行修改,就可以用它。例如:在一个工作流程中,我们通过给map 传入一个函数来对集合元素进行转化。有时我们不需要做任何转化,你可以传入identity。源码如下:

@scala.inline
  def identity[A](x : A) : A = { /* compiled code */ }

3 implicitly

当隐式参数列表使用简写[T:M] 时,编译器会添加形式为(implicit arg: M[T]) 的隐式参数列表(实际名称不是arg,而是编译器合成的唯一名称)。调用implicitly 可以返回参数arg。源码如下:

 @scala.inline
  def implicitly[T](implicit e : T) : T = { /* compiled code */ }

看一个例子:

package cn.com.tengen.test.obj

class Test{

}
case class MyList[A](list: List[A]) {
  def sortBy1[B](f: A => B)(implicit ord: Ordering[B]): List[A] =
    list.sortBy(f)(ord)
  def sortBy2[B : Ordering](f: A => B): List[A] =
    list.sortBy(f)(implicitly[Ordering[B]])
}


object Test {
  def main(args: Array[String]): Unit = {
    val list = MyList(List(1,3,5,2,4))
    val l1 = list sortBy1 (i => -i)
    val l2 = list sortBy2 (i => -i)
    println(l1)
    println(l2)
  }
}
有些集合提供了一些排序方法,List.sortBy 便是其中之一。List.sortBy 方法的第一个参数类型为函数,该输入函数能够将函数的输入参数转化为另一个满足math.Ordering 条件的类型。而math.Ordering 是与Java 中的Comparable抽象等同的类型。List.sortBy 方法的另一个参数则为隐式参数,该参数知道如何对类型B 的实例进行排序。

MyList 类提供了两种方式编写像sortBy 类型的方法。第一种实现:sortBy1 方法应用了我们已知的语法。该方法接受一个额外的类型为Ordering[B] 的隐式值作为其输入。调用sortBy1 方法时,在当前作用域中一定存在某一Ordering[B] 的对象实例,该实例清楚地知道如何对我们所需要的B 类型对象进行排序。我们认为B 的界限被“上下文”所限定,在这个例子中,上下文限定了B 对实例进行排序的能力。

由于这种Scala 方言应用非常普遍,因此Scala 提供了一个简化版的语法,这正是第二类实现 sortBy2 所使用的语法。类型参数B : Ordering被称为 上下文定界( context bound), 它暗指第二个参数列表(也就是那个隐式参数列表)将接受Ordering[B] 实例。

不过,我们仍需要在方法中访问Ordering 对象实例。由于在源代码中我们不再明确地声明Ordering 对象实例,因此这个实例没有自己的名称。针对这种现象我们该怎么办呢?Predef.implicitly 方法帮我们解决了这个问题。implicitly 方法会对传给函数的所有标记为隐式参数的实例进行解析。请注意implicitly 方法所需要的类型签名,在本例中Ordering[B] 是其类型签名。

4.Pair 与 Triple

Pair是一个二元组,Triple是一个三元组
源码:
@scala.deprecated("use built-in tuple syntax or Tuple2 instead", "2.11.0")
  type Pair[+A, +B] = scala.Tuple2[A, B]
  @scala.deprecated("use built-in tuple syntax or Tuple2 instead", "2.11.0")
  object Pair extends scala.AnyRef {
    def apply[A, B](x : A, y : B) : scala.Tuple2[A, B] = { /* compiled code */ }
    def unapply[A, B](x : scala.Tuple2[A, B]) : scala.Option[scala.Tuple2[A, B]] = { /* compiled code */ }
  }
  @scala.deprecated("use built-in tuple syntax or Tuple3 instead", "2.11.0")
  type Triple[+A, +B, +C] = scala.Tuple3[A, B, C]
  @scala.deprecated("use built-in tuple syntax or Tuple3 instead", "2.11.0")
  object Triple extends scala.AnyRef {
    def apply[A, B, C](x : A, y : B, z : C) : scala.Tuple3[A, B, C] = { /* compiled code */ }
    def unapply[A, B, C](x : scala.Tuple3[A, B, C]) : scala.Option[scala.Tuple3[A, B, C]] = { /* compiled code */ }
  }
5. Map与Set

我们先可一个例子:
object Test {
  def main(args: Array[String]): Unit = {
    val map = Map(1->"aaa",2->"BBB")
    val set = Set(1,2,33,44,44,6)
    println(map)
    println(set)
  }
}

这里我们用的Map和Set都是Predef中的两个属性,而并没有直接导入scala.collection.immutable.Map和scala.collection.immutable.Set,看源码:

 type Map[A, +B] = scala.collection.immutable.Map[A, B]
  type Set[A] = scala.collection.immutable.Set[A]
  val Map : scala.collection.immutable.Map.type = { /* compiled code */ }
  val Set : scala.collection.immutable.Set.type = { /* compiled code */ }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值