通过List.apply方法构造List的背后逻辑
来源:互联网 发布:php和seo哪个好 编辑:程序博客网 时间:2024/05/22 14:04
通过List
伴生对象的apply
方法来创建实例: List("A","B")
过程发生了什么
首先,List
伴生对象的apply
方法接收的是一个可变参数列表,即数组:
override def apply[A](xs: A*): List[A] = xs.toList
而我们传入的Array("A","B")
数组会被隐式转换为 WrappedArray
的子类型,这是在LowPriorityImplicits
里定义的:
// Since the JVM thinks arrays are covariant, one 0-length Array[AnyRef]// is as good as another for all T <: AnyRef. Instead of creating 100,000,000// unique ones by way of this implicit, let's share one.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)}
随后对这个WrappedArray
的子类型ofRef[String]
类型,调用 toList
方法
不过在进行toList
时用到了隐式参数CanBuildFrom,我们先看一下List
伴生对象中定义的,用于生成CanBuildFrom信息的隐式方法:
/** $genericCanBuildFromInfo */implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, List[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
现在来追踪toList
的执行过程,在父类TraversableOnce
的toList
方法里调用了to
方法,而这个to
方法里有声明一个隐式参数。
用隐式参数CanBuildFrom
构造了一个List
类型的容器,把数据填充进去,再返回result
里面的隐式参数:
implicit cbf: CanBuildFrom[Nothing, A, Col[A @uV]]
先不用管里面难懂的类型参数,编译在寻找对应的隐式参数值时,通过上面的 to[List]
声明的目标类型是List
,所以从List
的伴生对象中去寻找,通过 canBuildFrom
隐式函数得到了需要的参数,它是把一个可复用的对象造型成我们需要的CBF类型:
ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
ReusableCBF
的意思是可复用的CanBuildFrom
,它在 GenTraversableFactory
里定义:
通过这个CBF隐式参数帮我们构造了一个新的容器,然后把当前集合里的数据放进去,最后再调用新容器的result
来得到List
通过断点,发现 b.result
时进入了 ListBuffer.toList
的代码里,也就是说这个隐式参数构造出来的新容器类型是 ListBuffer 的子类型。
最终,它返回ListBuffer
类里的start
成员,这个start
是一个 ::
类型(List的子类)
- 通过List.apply方法构造List的背后逻辑
- list的构造函数
- List的【addAll(List list)】方法
- 为什么List的构造方法是ArrayList(),而不是同名的List()?
- List集合构造方法以及主要方法
- 【STL】list的构造函数
- 通过反射填充泛型集合List的静态方法
- 通过反射填充泛型集合List的静态方法
- list实现的排行榜 针对游戏逻辑
- 通过WCF传输的 List
- List的contains()方法
- List的contains()方法
- List的contains()方法
- List的contains()方法
- list arraylist的方法
- List的contains()方法
- list 方法的实现
- list 方法的实现
- #131 – Dependency Properties Inherit Values from Higher Up in the Logical Tree(逻辑树中元素的依赖属性可从其上层元素继承)
- /proc 文件系统的学习
- 那些年我们刷过的算法题---滑动窗口练习题
- CSS Modules 用法教程
- f_sync解决fatfs文件掉电数据丢失问题
- 通过List.apply方法构造List的背后逻辑
- 专题四-1006-典型Kruskal算法应用
- Android振动器(Vibrator)系统详解
- 前后端数据交互方法
- 专访阿里云高级专家赵林:从0到1,中间件的研发运维之路
- CDISC SDTM LB domain学习笔记
- 设计模式---单例模式
- 从头到尾彻底解析哈希表算法
- 山东大学现代软件开发技术复习纲要