【Scala】Scala的Predef对象
来源:互联网 发布:厦门建研集团待遇 知乎 编辑:程序博客网 时间:2024/05/31 13:17
隐式引用(Implicit Import)
Scala会自动为每个程序加上几个隐式引用,就像Java程序会自动加上java.lang包一样。Scala中,以下三个包的内容会隐式引用到每个程序上。所不同的是,Scala还会隐式加进对Predef的引用,这极大方便了程序员的工作。
import java.lang._ // in JVM projects, or system namespace in .NETimport scala._ // everything in the scala packageimport Predef._ // everything in the Predef object
上面三个包,包含了常用的类型和方法。java.lang包包含了常用的java语言类型,如果在.NET环境中,则会引用system命名空间。类似的,scala还会隐式引用scala包,也就是引入常用的scala类型。
请注意
上述三个语句的顺序藏着一点玄机。我们知道,通常,如果import进来两个包都有某个类型的定义的话,比如说,同一段程序,即引用了’scala.collection.mutable.Set’又引用了’import scala.collection.immutable.Set’则编译器会提示无法确定用哪一个Set。这里的隐式引用则不同,如果有相同的类型,后面的包的类型会将前一个隐藏掉。比如,java.lang和scala两个包里都有StringBuilder,这种情况下,会使用scala包里定义的那个。java.lang里的定义就被隐藏掉了,除非显示的使用java.lang.StringBuilder。
Predef对象
Predef提供常用函数
包scala中的Predef对象包含了许多有用的方法。例如,Scala源文件中写下println语句,实际调用的是Predef的println,Predef.println
转而调用Console.println
,完整真正的工作。
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: _*))
断言函数assert以及相关函数也是在Predef中定义的:
/** Tests an expression, throwing an `AssertionError` if false.* Calls to this method will not be generated if `-Xelide-below`* is at least `ASSERTION`.** @see elidable* @param assertion the expression to test*/@elidable(ASSERTION)def assert(assertion: Boolean) {if (!assertion) throw new java.lang.AssertionError("assertion failed")}/** Tests an expression, throwing an `AssertionError` if false.* Calls to this method will not be generated if `-Xelide-below`* is at least `ASSERTION`.** @see elidable* @param assertion the expression to test* @param message a String to include in the failure message*/@elidable(ASSERTION) @inlinefinal def assert(assertion: Boolean, message: => Any) {if (!assertion) throw new java.lang.AssertionError("assertion failed: "+ message)}
Predef定义类型别名
Predef是一个对象(Object),这个对象中,定义一些类型别名,如:
scala.collection.immutable.List // to force Nil, :: to be seen.type Function[-A, +B] = Function1[A, B]type Map[A, +B] = immutable.Map[A, B]type Set[A] = immutable.Set[A]val Map = immutable.Mapval Set = immutable.Set
现在我们知道了,直接使用集合时,如List,Map,Set,用到的是immutable包中的对象,这是在Predef里定义的。
隐式转换
Predef对象定义了常用的隐式转换,如:
implicit final class any2stringadd[A](private val self: A) extends AnyVal { def +(other: String): String = String.valueOf(self) + other}
该隐式转换,给AnyVal的所有子类型都加上了+(other: String): String
方法,便于在打印或其他字符串操作时,加入其他的值类型。
再如:
@inline implicit def augmentString(x: String): StringOps = new StringOps(x)@inline implicit def unaugmentString(x: StringOps): String = x.repr
该隐式转换,使得我们可以自由的对String使用StringOps的方法。
同理,数值类型的富包装(Rich Wrapper)也是这样实现的。
Scala程序员可以较少关心装箱和拆箱操作,这也是由于Predef对象里定义了Scala值类型与java基本类型直接的隐式转换。
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.byteValueimplicit def Short2short(x: java.lang.Short): Short = x.shortValueimplicit def Character2char(x: java.lang.Character): Char = x.charValueimplicit def Integer2int(x: java.lang.Integer): Int = x.intValueimplicit def Long2long(x: java.lang.Long): Long = x.longValueimplicit def Float2float(x: java.lang.Float): Float = x.floatValueimplicit def Double2double(x: java.lang.Double): Double = x.doubleValueimplicit def Boolean2boolean(x: java.lang.Boolean): Boolean = x.booleanValue
关于装箱(Boxing)和拆箱(Unboxing)
熟悉Java或C#等语言的读者会知道,装箱是指将原始类型转换成引用类型(对象),用于需要对象的操作,而拆箱,则是把对象转换成原始类型,用于需要原始类型的场景。
由于数值类型本身已经是类对象,因此Scala里不需要装箱(boxing)和拆箱(unboxing)操作。 当然,Scala代码最终会运行在JVM上,所以实际上,始终会有装箱成Scala类对象,和拆箱成Java原始值类型的操作,但是这些操作是透明的,程序员不需要关心(实际上,这是由定义在Predef中的隐式转换完成的)。
参考资料
Predef官方标准库文档
隐式引用(Implicit Import)和Predef
转载请注明作者Jason Ding及其出处
GitCafe博客主页(http://jasonding1354.gitcafe.io/)
Github博客主页(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
Google搜索jasonding1354进入我的博客主页
- 【Scala】Scala的Predef对象
- scala的predef对象
- scala.Predef
- "scala.Predef$.$conforms scala/Predef$$less$colon$less"问题
- Spark java.lang.NoSuchMethodError: scala.Predef$.refArrayOps
- 关于异常 java.lang.NoSuchMethodError: scala.Predef$.ArrowAssoc(Ljava/lang/Object;)的处理
- Scala的面向对象
- Scala的面向对象
- Spark Streaming 报错:NoSuchMethodError: scala.Predef$.ArrowAssoc
- Exception in thread "main" java.lang.NoClassDefFoundError: scala/Predef
- java.lang.NoSuchMethodError: scala.Predef$.$scope()Lscala/xml/TopScope$;
- Spark Q&A : java.lang.NoSuchMethodError: scala.Predef$.ArrowAssoc
- Exception in thread "main" java.lang.NoSuchMethodError: scala.Predef$.$conforms()Lscala/Predef$$less
- Scala对象
- Scala 对象
- Scala对象
- scala对象
- Scala对象
- C++文件操作详解(ifstream、ofstream、fstream)
- select ......for update 语句解释 (文章中有些地方描述的不是很准确)
- Android studio LogCat 显示
- Python Unittest 自动化单元测试框架Demo
- apache 与 tomcat的关系
- 【Scala】Scala的Predef对象
- 223Rectangle Area
- 导出遇到 ORACLE 错误 1455:转换列溢出整数数据类型
- Coroutine couldn't be started because the the game object 'GameController' is inactive!
- Java中的异常 Exception finally
- 【C语言】在两个数成对出现的数组中找到一个单独的数。
- MySQL 5.6 for Windows 解压缩版配置安装
- Tomcat源码学习——第1章
- iOS ibeacon后台运行相关文章