[3.0]数组的创建及原理初探
2016-05-24 10:45
351 查看
参考
ClassTag API泛型的理解与应用
上下文界定
类型系统
问题
怎么理解scala中数组的创建方式? T:ClassTag如何类理解?def makeArray[T:ClassTag](elems : T*):Array[T] = Array[T](elems:_*) // 创建任意类型的数组
分析
第一、makeArray方法体中的 语句:Array[T](elems:_*)会调用Array的伴生对象中apply方法,具体实现如下:
def apply[T: ClassTag](xs: T*): Array[T] = { val array = new Array[T](xs.length) var i = 0 for (x <- xs.iterator) { array(i) = x; i += 1 } array }
第二、数组创建的方法申明:
def makeArray[T:ClassTag](elems : T*):Array[T]等价于
def makeArray[T] (elems : T*)(implicit elem:ClassTag[T]):Array[T]详见上下文绑定
综合一、二两条,详细版的数组创建方式如下:
def makeArray[T] (elems : T*)(implicit elem:ClassTag[T]):Array[T] ={ val arr = new Array(elems.length) var i = 0 for(item<-elems){ arr(i) = item; i+=1 } arr }
那么问题来了,这里为什么需要添加一个隐式参数ClassTag[T]呢?我们用反证法来加以说明-假设没有ClassTag[T]. 没有ClassTag[T]的话,由于上述方式创建的数组,其存储空间是在运行时分配的,而类型信息T在运行时已被擦除(参见泛型原理)也就是说程序运行时不知道T到底是什么类型-Int、Long还是其他类型?这样就无法创建数组:不知道应该为数组中的每个元素分配多大的内存空间!
ClassTag[T]的出现正是为了解决这个问题的 - “A ClassTag[T] stores the erased class of a given type
T, accessible via the runtimeClass field ” - ClassTag会把T的具体类型信息保留到程序运行期,至于内部是如何实现的,有待后续进一步分析。
总结
以后就放心大胆地使用简洁版的方式创建数组吧:def makeArray[T:ClassTag](elems : T*):Array[T] = Array[T](elems:_*)
相关文章推荐
- Android基于AOP的非侵入式监控之——AspectJ实战
- windows server 2008 r2的FTP配置和访问
- 深入了解cookie
- 【常用算法思路分析系列】链表相关高频题集
- 算法学习(十四)最大公约数问题
- 从分支clone代码
- bp神经网络及matlab实现
- 贪心算法解决基站问题
- Linux下设置定期(定时)执行脚本crontab命令
- 【BZOJ3143】[Hnoi2013]游走【高斯消元】【期望DP】【贪心】
- PostgreSQL 递归查询
- 调整数组顺序使奇数在前
- 工具类开篇
- c++中构造函数调用构造函数
- windows上安装Anaconda和python
- Android设计模式之单例模式
- 使用python计算夏普比率与最大回撤和最大回撤时间的程序
- iOS常用宏定义
- Android绘图机制与处理技巧
- setjmp和longjmp浅析