浅谈Scala 2.8的包对象(package object)
2019独角兽企业重金招聘Python工程师标准>>>
Scala 2.8提供包对象(package object)的新特性。什么是包对象呢?按我的理解,根据Scala“一切皆对象”设计哲学,包(package)也是一种对象。既然是对象,那么就应该有属性和方法,也可以在包对象内声明某个类型的别名。举个例
package com{package object ggd543{type HashMap[A,B] = scala.collection.mutable.HashMap[A,B];val HashMap = scala.collection.mutable.HashMapdef print = println("hello, ggd543")}package object aiguozhe{var name = "aiguozhe"def sayHello = println("hello")}}
可以看到,定义包对象跟定义一个普通的伴随对象(companion object)在写法上的唯一区别就是在关键字object 前加上 package 。
然后我们可以像使用伴随对象那样使用包对象,比如
object Test extends Application{val myMap: com.ggd543.HashMap[String,String]= null; println(com.ggd543.HashMap) println(com.ggd543.print); println(com.aiguozhe.name)com.aiguozhe.name = "AIGUOZHE"println(com.aiguozhe.name)
}
如果包对象的作用仅仅限于伴随对象那样,那scala 2.8完全没有必要引入这种特性。实际上包对象最重要的用途是兼容旧的类库,或者为某些数据类型提供增强版本。
比如在scala 2.7.7中,List是定义在scala包下的一个不可变集合类。这样做的目的是每次使用List的时候不需要显式地导入包名,因为List是一个使用很频繁的类。
在Scala中,包java.lang,包scala和伴随对象Predef里的所有数据类型,属性和方法会被自动导入到每个Scala文件中
然而另一方面,List由于具有不可变的特性,它应该归入scala.collection.immutable包中。因此在scala 2.8中,List被挪到scala.collection.immutable包下里,但这样一来2.8版本如何兼容2.7.7版本。于是Scala 2.8引入“包对象”这个特性来解决这个问题。如果你查阅Scala 2.8版本的API文档或源码,你会发现它定义了一个包对象:
package object scala { // Type and value aliases for collection classestype TraversableOnce[+A] = scala.collection.TraversableOnce[A] type Traversable[+A] = scala.collection.Traversable[A]val Traversable = scala.collection.Traversabletype Iterable[+A] = scala.collection.Iterable[A]val Iterable = scala.collection.Iterabletype Seq[+A] = scala.collection.Seq[A]val Seq = scala.collection.Seqtype IndexedSeq[+A] = scala.collection.IndexedSeq[A]val IndexedSeq = scala.collection.IndexedSeqtype Iterator[+A] = scala.collection.Iterator[A]val Iterator = scala.collection.Iteratortype BufferedIterator[+A] = scala.collection.BufferedIterator[A]type List[+A] = scala.collection.immutable.List[A]val List = scala.collection.immutable.Listval Nil = scala.collection.immutable.Niltype ::[A] = scala.collection.immutable.::[A]val :: = scala.collection.immutable.::type Stream[+A] = scala.collection.immutable.Stream[A]val Stream = scala.collection.immutable.Streamval #:: = scala.collection.immutable.Stream.#::type Vector[+A] = scala.collection.immutable.Vector[A]val Vector = scala.collection.immutable.Vectortype StringBuilder = scala.collection.mutable.StringBuildertype Range = scala.collection.immutable.Rangeval Range = scala.collection.immutable.Range// Numeric types which were moved into scala.math.*type BigDecimal = scala.math.BigDecimalval BigDecimal = scala.math.BigDecimaltype BigInt = scala.math.BigIntval BigInt = scala.math.BigInttype Equiv[T] = scala.math.Equiv[T]type Fractional[T] = scala.math.Fractional[T]type Integral[T] = scala.math.Integral[T]type Numeric[T] = scala.math.Numeric[T]val Numeric = scala.math.Numerictype Ordered[T] = scala.math.Ordered[T]val Ordered = scala.math.Orderedtype Ordering[T] = scala.math.Ordering[T]val Ordering = scala.math.Orderingtype PartialOrdering[T] = scala.math.PartialOrdering[T] type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T]// others }
也就是说scala.List相当于指向了scala.collection.immutable.List,从而保证升级到Scala 2.8版本不会对原有的程序造成影响。
可能有些读者会问,通过定义一个伴随对象scala 能否解决兼容的问题?但细想一下就发现不妥,因为scala包下的一切都要搬到这个伴随对象scala中去了,这似乎不太现实。实际上,Scala编译器会在scala包下创建一个叫package的类,这个类里面的内容就是package object scala中的东西, scala.List被翻译成scala.package.List, 但对于程序员来说是透明的 。同样道理也会在com.ggd543包和com.aiguozhe包下分别创建一个package类.
有了包对象这个新特性,我们不但解决了新旧版本的兼容性问题,还可以对旧的类库或第三方接口做一些包装或改进,而不需要额外创建一些类或接口(虽然实际上还是创建了一个类package,但这是编译器帮我们完成的)。比如在Play-scala module的0.8版本(http://www.playframework.org/modules/scala-0.8.zip)中,就对一些JPA接口进行了封装和改进:
import play.data.validation._
import javax.persistencepackage play { package db {import annotation.target.fieldpackage object jpa{//enumsval CascadeType = CascadeTypeWrapperval LockModeType = LockModeTypeWrapperval FetchType = FetchTypeWrapper//classestype Table = persistence.Tabletype Entity = persistence.Entitytype Inheritance = persistence.Inheritance//javax.persistence fieldtype AttributeOverrides = persistence.AttributeOverrides @fieldtype Basic = persistence.Basic @fieldtype Column = persistence.Column @field// ...
}
转载于:https://my.oschina.net/aiguozhe/blog/35202
浅谈Scala 2.8的包对象(package object)相关推荐
- php字面量,浅谈js之字面量、对象字面量的访问、关键字in的用法
一:字面量含义 字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量. 字面量分为字符串字面量(string literal ).数组字面量(array literal) ...
- 浅谈Perl的类、包、模块与面对对象编程
http://blog.chinaunix.net/uid-27464093-id-3308003.html Perl面向对象Perl面向对象学习例子实例代码教程 - 在我们了解perl的面向对象的概 ...
- 浅谈ASP.net中的DataSet对象
在我们对数据库进行操作的时候,总是先把数据从数据库取出来,然后放到一个"容器"中,再通过这个"容器"取出数据显示在前台,而充当这种容器的角色中当属DataSet ...
- 浅谈 Scala 中下划线的用途
Scala 作为一门函数式编程语言,对习惯了指令式编程语言的同学来说,会不大习惯,这里除了思维方式之外,还有语法层面的,比如 underscore(下划线)就会出现在多种场合,令初学者相当疑惑,今天就 ...
- 浅谈一下javascript中的this对象
this是什么? this关键字是函数运行时自动生成的一个内部对象,也被称作为环境对象,只能在函数内部使用.谁'调用'this,this就指向谁.打个比方来说:this就相当于中文中的"我& ...
- Scala 入门-包对象(package object)
专栏原创出处:github-源笔记文件 ,github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明. Scala 编程语言专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Scala ...
- 浅谈:Spring Boot原理分析,切换内置web服务器,SpringBoot监听项目(使用springboot-admin),将springboot的项目打成war包
浅谈:Spring Boot原理分析(更多细节解释在代码注释中) 通过@EnableAutoConfiguration注解加载Springboot内置的自动初始化类(加载什么类是配置在spring.f ...
- 浅谈HTTPS通信机制和Charles抓包原理-by:nixs
转载请注明出处:https://blog.csdn.net/zwjemperor/article/details/80719427 主页:https://blog.csdn.net/zwjempero ...
- java对象头_浅谈java对象结构 对象头 Markword
概述 对象实例由对象头.实例数据组成,其中对象头包括markword和类型指针,如果是数组,还包括数组长度; | 类型 | 32位JVM | 64位JVM| | ------ ---- | ----- ...
最新文章
- Kotlin中的接口回调
- python 获得github代码库列表
- IOS8如何获取当前UIViewController
- java semaphore(0)_面试官:说说Java中的信号量?Semaphore
- 绕过图片防盗链的方法
- css float属性
- python字典长度可变吗_Python字典dict实现原理
- Gartner发布2011十大关键技术
- netty框架实现websocket达到高并发
- allegro隐藏/显示铜皮
- Excel表格公式大全
- java手机壁纸_java-爬取手机高清壁纸
- 【菜鸟逆袭记】之初识操作符
- leetCode_Patching Array
- 苏宁易购易付宝注销教程
- 今天在隧道一车上的一幕
- 手机常亮展示软件_手机常亮展示软件下载
- shiro中登录的时候url地址栏带jsessionid的两种方式
- 2022年深圳市国家高新技术企业认定条件、时间、流程
- 极域电子教室系统 远程桌面 打不开 连不上 删除GATESRV.exe MasterHelper.exe
热门文章
- 基于android的视频采集系统的设计与实现,基于Android的视频采集系统的设计与实现...
- mysql配置多个磁盘_MySQL多实例配置(两)
- jquery加载完成后方法只执行一次_JavaScript的超级库--jQuery内容整理(3)
- Java开发中遇到具有挑战的事_170道Java工程师面试题,你敢挑战吗?
- linux c语言变量地址类型,C语言基础知识:访问内存地址的方法
- MongoDB Cursor Methods
- date_range
- VMware 虚拟化平台规划设计方案
- 公有云退款流程及政策--退款规则及退款流程(阿里云 华为云) --2020-09-03
- 签名证书无效”-在vCenter Server Appliance 6.5 / 6.7上使用Shell脚本重新生成和替换已过期的STS证书(76719)