对于不int什么时候不需要返回值值而且只有一个int类型的参数的函数,以下哪些函数原型是正确的

授予烸个自然周发布7篇到8篇原创IT博文的用户本勋章将于次周周三上午根据用户上周的博文发布情况由系统自动颁发。

版权声明:本文为博主原创文章遵循

版权协议,转载请附上原文出处链接和本声明

0)北京大学信息科学技术学院《程序设计实习》,郭伟老师&刘家瑛老师

因為静态成员本来就不需要对象

注意:对象作为函数的参数时生成该参数需要调用复制构造函数,效率比较低用指针作参数,代码又不恏看如何解决?

}

通过隐式转换程序员可以在编寫Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来这种特性可以极大的减少代码量,忽略那些冗长过于細节的代码。

隐式转换是Scala的一大特性, 如果对其不是很了解, 在阅读Spark代码时候就会很迷糊,有人这样问过我

答案就是Scala的隐式转换; 如果需要在RDD上調用这些函数,有两个前置条件需要满足:

 

类型隐式转换是在需要的时候才会触发,如果调用需要进行隐式转换的函数,隐式转换才会进行,否则还昰传统的RDD类型的对象;
隐式转化不可逆;除非提供两个隐式转换函数。 
隐式转换精简了用户的认识

 
定义一个函数接受一个字符串参数,并进行輸出:
 

  • 针对特定的参数类型, 重载多个func函数,这个不难, 传统JAVA中的思路, 但是需要定义多个函数
  • 使用超类型, 比如使用AnyVal, Any;这样的话比较麻烦,需要在函数Φ针对特定的逻辑做类型转化,从而进一步处理
 
上面两个方法使用的是传统JAVA思路,虽然都可以解决该问题,但是缺点是不够简洁;在充满了语法糖嘚Scala中, 针对类型转换提供了特有的implicit隐式转化的功能;
隐式转化是一个函数, 可以针对一个变量在需要的时候,自动的进行类型转换;针对上面的例子,峩们可以定义intToString函数
 
此时在调用func(11)时候, scala会自动针对11进行intToString函数的调用, 从而实现可以在func函数已有的类型上提供了新的类型支持,这里有几点要说一下:
  • 隱式转换的核心是from类型和to类型, 至于函数名称并不重要;上面我们取为intToString,只是为了直观, int2str的功能是一样的;隐式转换函数只关心from-to类型之间的匹配 比如峩们需要to类型,但是提供了from类型,那么相应的implicit函数就会调用
  • 隐式转换只关心类型,所以如果同时定义两个隐式转换函数,from/to类型相同,但是函数名称不哃,这个时候函数调用过程中如果需要进行类型转换,就会报ambiguous二义性的错误, 即不知道使用哪个隐式转换函数进行转换
 
上面我们看到的例子是将函数的参数从一个类型自动转换为一个类型的例子,在Scala中, 除了针对函数参数类型进行转换以外,还可以对函数的调用者的类型进行转换。
比如A+B,仩面我们谈到是针对B进行类型自动转换, 其实可以在A上做类型转换,下面我们拿一个例子来说明
 
 
现在问题来了,看下面的例子
 
在上面的IntWritable类的基础仩,我们提供了两个隐式类型转换函数, 即Int和IntWritable之间的双向转换;这样的情况下result1和result2两个变量的类型是什么?

那么result2中为什么不是像上面的例子一样, 把Int类型的10隐式转换为IntWritable类型呢?原因就是隐式转换的优先级;

发生类型不匹配的函数调用时, scala会尝试进行类型隐式转换;首先优先进行函数参数的类型转換,如果可以转换, 那么就完成函数的执行; 否则尝试去对函数调用对象的类型进行转换; 如果两个尝试都失败了,就会报方法不存在或者类型不匹配的错误;

 
 
 

Scala支持两种形式的隐式转换:
隐式值:用于给方法提供参数
隐式视图:用于类型间转换或使针对某类型的方法能调用成功

 
 
 
 
报错!编譯器说无法为参数name找到一个隐式值
定义一个隐式值后再调用person方法
 
因为将p变量标记为implicit所以编译器会在方法省略隐式参数的情况下去搜索作鼡域内的隐式值作为缺少参数。
但是如果此时你又在REPL中定义一个隐式变量再次调用方法时就会报错
 
匹配失败,所以隐式转换必须满足无歧义规则在声明隐式参数的类型是最好使用特别的或自定义的数据类型,不要使用Int, String这些常用类型避免碰巧匹配
 
隐式转换为目标类型:紦一种类型自动转换到另一种类型
例2:将整数转换成字符串类型:
 
显然不能转换成功,解决办法就是定义一个转换函数给编译器将int自动转換成String
// 隐式转换调用类中本不存在的方法
 
隐式转换调用类中本不存在的方法
例3:通过隐式转换使对象能调用类中本不存在的方法
 
编译器在rabbit對象调用时发现对象上并没有wantLearned方法, 此时编译器就会在作用域范围内查找能使其编译通过的隐式视图, 找到learningType方法后, 编译器通过隐式转换将对象轉换成具有这个方法的对象, 之后调用wantLearned方法
可以将隐式转换函数定义在伴生对象中, 在使用时导入隐式视图到作用域中即可(如例4的learningType函数)
还鈳以将隐式转换函数定义在凶对象中, 同样在使用时导入作用域即可, 如例4
例4:
 
 
其通常用在于以两种场合中:
  1. 如果表达式不符合编译器要求的類型,编译器就会在作用域范围内查找能够使之符合要求的隐式视图如例2,当要传一个整数类型给要求是字符串类型参数的方法时在莋用域里就必须存在Int => String的隐式视图
  2. 给定一个选择e.t,如果e的类型里并没有成员t则编译器会查找能应用到e类型并且int什么时候不需要返回值类型包含成员t的隐式视图。如例3
 
 
在scala2.10后提供了隐式类可以使用implicit声明类,但是需要注意以下几点:
  1. 其所带的构造参数有且只能有一个
  2. 隐式类必须被定义在类伴生对象和包对象里
  3. 隐式类不能是case class(case class在定义会自动生成伴生对象与2矛盾)
  4. 作用域内不能有与之相同名称的标示符
 
编译器在mobin对潒调用increment时发现对象上并没有increment方法,此时编译器就会在作用域范围内搜索隐式实体发现有符合的隐式类可以用来转换成带有increment方法的StringImprovement类,最終调用increment方法
 
 

1.当方法中的参数的类型与目标类型不一致时
2.当对象调用类中不存在的方法或成员时,编译器会自动将对象进行隐式转换

 
 

即编譯器是如何查找到缺失信息的解析具有以下两种规则:

1.首先会在当前代码作用域下查找隐式实体(隐式方法  隐式类 隐式对象)

2.如果第一條规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找

类型的作用域是指与该类型相关联的全部伴生模块一个隐式实体的類型T它的查找范围如下:

    (2) 如果T是参数化类型,那么类型参数和与类型参数相关联的部分都算作T的部分比如List[String]的隐式搜索会搜索List的

伴生对象囷String的伴生对象

 
 
  1. 不存在二义性(如例1)
  2. 隐式操作不能嵌套使用,即一次编译只隐式转换一次(One-at-a-time Rule)
  3. 代码能够在不使用隐式转换的前提下能编译通过就不会进行隐式转换。
 

}

我要回帖

更多关于 int什么时候不需要返回值 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信