scala成长之路:问题记录

  scala成长之路(5)问题记录

  还是在看scala sdk源码的时候,有很多问题要考自己慢慢摸索,这里做个记录。

  一. 隐式转换的作用域?

  隐式转换需要三个因素

  1. 己方(当前对象)

  2. 转换函数

  3. 对方(转换的目标类)

  这三个需要在同一个作用域内才能生效吗?举个简单的例子,依然是java HashSet隐式转换为scala Set(可以参看本系列(3)),我们只是在要用到转换的文件里写了一行:

  import scala.collection.JavaConverters._

  也就是说导入了JavaConverters单例中的全部转换函数,但是我们并没有导入转换的目标类AsScala,所以按道理来说当前解释器并不知道AsScala的存在,就更不知道asScala方法要去哪寻找了。所以我们换一种思路,解释器的执行顺序也许是样:

  1. 发现某个对象上调用了不存在的方法f

  2. 以该对象为输入参数寻找所有的隐式转换函数

  3. 列出所有隐式转换函数的输出参数类

  4. 看看这些类中是否有方法f;如有,则执行转换;没有则报错。

  因此我们可以回答所提出的问题了:并不需要三者在同一作用域内才能生效,只需要原对象、转换函数,就能触发隐式转换。

  二. 隐式转换遇到继承类怎么办?

  例如

  class SmartAnimal (n:String){

  val name = n

  }class Person (n:String) extends SmartAnimal(n) {

  override val name = n

  }

  object converter {

  implicit def asDog(person: Person):Dog = {

  print(from Person to Dog)

  new Dog(person.name + _dog)

  }

  implicit def asDog(animal:SmartAnimal):Dog = {

  print(from SmartAnimal to Dog)

  new Dog(animal.name)

  }

  }

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

  var a = new Person(aaa)

  a.bark

  }

  输出:

  from Person to Dog

  wang, wang, wang...

  可以看到,隐式转换会尽可能优先将原对象转换到子类。但是如果我们把上边的子类转换方法注释掉呢?

  object converter {// implicit def asDog(person: Person):Dog = {// print(from Person to Dog\n)// new Dog(person.name + _dog)// }

  implicit def asDog(animal:SmartAnimal):Dog = {

  print(from SmartAnimal to Dog\n) new Dog(animal.name)

  }

  }

  执行结果

  from SmartAnimal to Dog

  wang, wang, wang...

  子类无法转换,则转换为父类。所以我们可以总结得出,scala中的隐式转换有多个有继承目标类可选时,是自下而上的,从子类往父类去找。

  三、传值参数与传名参数

  形式:

  def funByName(arg: =Int) = println(arg)//传名参数

  def funByValue(arg:Int) = println(arg)//传值参数

  注意传名参数的:和=之间一定要有空格!!!

  在所传的参数为一个值(变量、常量)时,传名和传值并没有什么区别;只有当传递的为函数调用时,才会显现出差别:

  传值参数将需要的参数调用计算完成之后,再将计算的结果作为一个单一的值输入函数运行(只算一次);

  传名函数先将参数(需要执行的函数)传入函数体内,在需要用到该值的时候再执行(可能会算多次)。

  看起来像是没什么区别是吧?请考虑这种情况,在某个类的方法中需要重复用到该参数,而该参数所传入的调用的函数每次返回的结果都不一样:

  def pTimeByValue(time:Long) = { for(i - 1 to 5){

  println(time)

  Thread.sleep(1333)

  }

  }

  def pTimeByName(time: =Long) = { for(i - 1 to 5){

  println(time)

  Thread.sleep(1333)

  }

  }

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

  println(按值传递打印五次时间:)

  pTimeByValue(System.currentTimeMillis())

  println(-------------------------\n按名传递打印五次时间:)

  pTimeByName(System.currentTimeMillis())

  }

  执行结果

  按值传递打印五次时间:15358837613621535883761362153588376136215358837613621535883761362-------------------------按名传递打印五次时间:15358837680561535883769390153588377072315358837720571535883773391

  二者之间的区别足够清晰且一目了然了吧~简单来说,

  按值传递——劳动一次,享受一生

  按名传递——每次都要自己动手

?

原文地址:https://www.cnblogs.com/qfdsj/p/9579294.html

时间: 2024-11-06 09:26:48

scala成长之路:问题记录的相关文章

scala成长之路(2)对象和类

scala提供了一种特殊的定义单例的方法:object关键字 scala> object Shabi{ | val age = 0 | val name = "shabi" | def say = { | println("hello, I am a shabi") | } | }defined object Shabi scala> Shabi.sayhello, I am a shabi object定义的单例可以类比于java中的静态元素,也类似于

scala成长之路(4)compaion object——伴生对象的使用

虽然java一直声称自己是完全面向对象的语言,但一直以来都被很多人所质疑,其中java的静态成员函数就是主要的"罪魁祸首".由于java中保留了静态方法的调用,导致其编程模式依然有过程式编程的可能,尤其是在静态方法被滥用的当下(一个顽固的面向过程程序员完全可以将他的过程思维用一大推静态方法实现,而class仅仅只是个空有其表的外壳而已) 所以在scala中,设计者摒弃了static关键字,宣称自己是完全面向对象的,似乎更有说服力... 但是我们在编程中有时确实需要用到一般功能性函数,例

scala成长之路(6)函数入门

众所周知,scala作为一门极客型的函数式编程语言,支持的特性包括: 函数拥有"一等公民"身份: 支持匿名函数(函数字面量) 支持高阶函数 支持闭包 部分应用函数 柯里化 首先需要指出,在scala中有方法和函数对象两种形态,方法即是通过def关键字定义的函数,而函数对象则是通过将方法转换而来,或lambda赋值而来. 1. 从"一等公民"说起 很多稍微了解过函数式编程的人可能都听说过"一等公民"这种说法,但却很少有人能明明白白地说出究竟什么是&

scala成长之路(7)函数进阶——可能是史上最浅显易懂的闭包教程

由于scala中函数内部能定义函数,且函数能作为函数的返回值,那么问题来了,当返回的函数使用了外层函数的局部变量时,会发生什么呢?没错,就产生是闭包. 关于闭包的解释网上一大堆,但基本上都是照葫芦画瓢,一个模子刻出来的,说来说去都只讲了"内部函数引用外层函数的局部变量"这个刻板的定义,根本没降到精髓.精髓是什么?且看我一句话给你讲清楚: 闭包就是外层函数函数的对象,外层函数就是闭包的构造函数! 怎么样,是不是摸不着头脑?其实是这样,我们使用闭包的目的并不是为了引用外层函数的局部变量,这

来自我的破船大大的博客,记录他的iOS成长之路,与君同勉!

注1:这篇文章是我的iOS成长之路系列文章中的第三篇文章,第一篇文章:iOS成长之路-1-入门,第二篇文章:iOS成长之路-2-我的第一个iOS Demo. 通过两周时间来学习iOS,我慢慢的叩开了iOS开发的大门,接下来就是一个积累的过程,我主要经历了如下几个过程: 饱览群书 跟着项目一起成长 与同行交流 做一些分享 饱览群书 在初期,我认为多看书对于个人提升有很大的帮助,从某方面来说,这主要扩展了个人对iOS开发的理解广度(初期,先不要急于往最深处研究),接着把书上的讲解与动手编程结合起来,

XX老师的一次公开课讲座,成长之路,受益匪浅

其实本人也是一个毕业于三流的学校,且不说学校的好坏吧,学习这东西关键在于自己,俗话说:"师傅领进门,修行靠自己". 先声明下,本人文采不行不善于写作,请勿喷^_^ . 我的大学专业是计算机网络,大三之际,考虑到找工作的压力,我基本上没在学校上几节课,于是在外参加CCNP培训,经过自己的一翻努力,毕业前拿到了上海某企业的一家offer,当时印象中8个人面试,只录取2个人,当时我的心情无比的激动. 踏入软件测试行业,也是我的一次偶然的机遇,上海一年的工作,让我感觉到很迷茫,公司平台发展有限

从1.5k到18k, 一个程序员的5年成长之路

http://blog.csdn.net/lgg201/article/details/8637763 昨天收到了心仪企业的口头offer, 回首当初什么都不会开始学编程, 到现在恰好五年. 整天在社区晃悠, 看了不少的总结, 在这个时间点, 我也写一份自己的总结吧. 我一直在社区分享, 所以, 这篇总结也是本着一种分享的态度, 希望相比我还年轻的同学们, 可以从中找到一些让自己成长更快的文字. 先介绍下背景:1. 2008年3月开始学习编程, 目前2013年3月;2. 2009年6月计算机专业

张艾迪(创始人): 我的梦想与成长之路

The World No.1 Girl :Eidyzhang The World No.1 Internet Girl :Eidyzhang AOOOiA.global Founder :Eidyzhang AOOOiA global CEO:Eidyzhang Hello World Fouder:Eidyzhang story for Grow Up 年少的我拥有着梦想.创意.产品.学习着做CEO.学习着和巨头大叔们竞争.因为我知道AOOOiA.global就将要成为巨头互联网公司.因为AO

软件测试工程师成长之路:掌握软件测试九大技术主题

软件测试工程师成长之路:掌握软件测试九大技术主题 王顺 等 编著   ISBN 978-7-121-23996-0 2014年9月出版 定价:85.00元 432页 16开 内容提要 <软件测试工程师成长之路:掌握软件测试九大技术主题>以实际项目为原型.以关键理论与丰富实践为指导,贯彻了先进的项目管理理念与全程质量管理思想. <软件测试工程师成长之路:掌握软件测试九大技术主题>前9 章为软件测试九大技术主题分享,是众多资深软件工程师在软件测试领域的经验总结.知识升华与提高,展现众多