Scala高阶函数与隐式转换
2017-06-12 16:36
309 查看
Scala 官网:http://www.scala-lang.org/
一、高阶函数
1、函数化简
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
/**
* ⑴接收其他函数作为参数的函数,被称作高阶函数(higher-order function);
* ⑵Scala中,由于函数是一等公民,因此可以直接将某个函数传入其他函数,作为参数;
* ⑶高阶函数的另外一个功能是将函数作为返回值;
* ⑷高阶函数可以自动推断出函数类型,而不需要写明类型;而且对于只有一个参数的函数,还可以省去其小括号;
* 如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,用_来替代即可;
* Array(2,3,5,6).map((x:Int)=>{x*3})
* Array(2,3,5,6).map((x)=>{x*3})
* Array(2,3,5,6).map((x)=>x*3)
* Array(2,3,5,6).map(x=>x*3)
* Array(2,3,5,6).map(_*3)
*/
object functionN extends App{
def myTest(x: Int, y: Int) = {
x * y + 20
}
def fun1(f: (Int, Int) => Int, a: Int, b: Int) = {
f(a, b)
}
println(fun1(myTest, 100, 5))
}
2、常见的高阶函数
二、隐式转换
1、隐式转换
⑴Scala提供的隐式转换和隐式参数功能,是非常有特色的功能,是Java等编程语言所没有的功能。它可以允许手动指定将某种类型的对象转换成其他类型的对象。
⑵Scala的隐式转换,其实最核心的就是定义隐式转换函数,即implicit conversion function。定义的隐式转换函数,只要在编写的程序内引入,就会被Scala自动使用。Scala会根据隐式转换函数的签名,在程序中使用到隐式转换函数接收的参数类型定义的对象时,会自动将其传入隐式转换函数,转换为另外一种类型的对象并返回。这就是隐式转换。
⑶隐式转换函数叫什么名字是无所谓的,通常不会由用户手动调用,而是由Scala进行调用。然而,如果要手动使用隐式转换,则需要对隐式转换函数进行导入。因此通常将隐式转换函数的名称命名为“one2one”的形式。
⑷要实现隐式转换,只要在程序可见的范围内定义隐式转换函数即可。Scala会自动使用隐式转换函数。隐式转换函数与普通函数唯一的语法区别就是,要以implicit开头,而且要指定函数返回类型。
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
class SpecialPerson(val name: String)
class Student1(val name: String)
class Older(val name: String)
object Implicit extends App{
var ticketNm = 0
def buySpecialTticket(spe: SpecialPerson) = {
ticketNm += 1
spe.name + "'s ticket number is " + ticketNm
}
implicit def object2SpecialPerson(obj: Object):SpecialPerson = {
//隐式转换函数需要使用implict声明
//隐式转换的函数名称习惯为:被转换类型2目标类型
//隐式转换函数需要显性的定义返回类型
println("************************")
if (obj.getClass == classOf[Student1]) {
val stu = obj.asInstanceOf[Student1]
new SpecialPerson(stu.name)
}
else if (obj.getClass == classOf[Older]) {
val old = obj.asInstanceOf[Older]
new SpecialPerson(old.name)
}
else new SpecialPerson("None")
}
println(buySpecialTticket(new Student1("bruce")))
}
2、隐式转换-加强类
⑴隐式转换强大之处就是可以在不知不觉中加强现有类型的功能。也就是说,可以为某个类定义一个加强版的类,并定义互相之间的隐式转换,从而让源类在使用加强版的方法时,由Scala自动进行隐式转换调用。
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
/**
* 隐式转换强大之处就是可以在不知不觉中加强现有类型的功能。
* 也就是说,可以为某个类定义一个加强版的类,并定义相互之间的隐式转换,
* 从而让源类在使用加强版的方法时,由Scala自动进行隐式转换为加强类,然后在调用该方法;
* @param name
*/
class Man(val name: String)
class SuperMan(val name: String) {
def emitLaser() = println("emiting laser......................")
}
object SuperMan extends App {
val bruce=new Man("bruce")
implicit def man2superman(man:Man):SuperMan={
new SuperMan(man.name)
}
bruce.emitLaser()
}
3、隐式转换作用域与发生时机
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
/**
* ⑴Scala默认会使用两种隐式转换:
* 一种是源类型,或者目标类型的伴生对象内的隐式转换函数;
* 一种是当前程序作用域内的可以用唯一标识符表示的隐式转换函数;
* ⑵如果隐式转换函数不在上述两种情况下的话,那么就需要手动使用import语法引入某个包下的隐式转换函数,
* 通常情况下,仅仅在需要进行隐式转换的地方,比如某个函数或者方法内,用import导入隐式转换函数,
* 这样可以缩小隐式转换函数的作用域,避免不必要的隐式转换;
* ⑶发生时机
* ①调用某个函数,但是给函数传入的参数的类型,与函数定义的接收参数类型不匹配;
* ②使用某个类型的对象,调用某个方法,而这个方法并不存在于该类型时;
* ③使用某个类型的对象,调用某个方法,虽然该类型有这个方法,但是给方法传入的参数类型,与方法定义的接收参数的烈性不匹配;
* @param name
*/
class Man2(val name: String)
object SuperMan2{
implicit def man22superman2(man:Man):SuperMan2={
new SuperMan2(man.name)
}
}
class SuperMan2(val name: String) {
def emitLaser() = println("emiting laser......................")
}
object Implicit extends App {
import com.example.scala.SuperMan2.man22superman2
val bruce=new Man("bruce")
bruce.emitLaser()
}
4、隐式参数
⑴所谓的隐式参数,指的是在函数或者方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的,用implicit修饰的对象,即隐式值,并注入参数。
⑵Scala会在两个范围内查找:一种是当前作用域内可见的val或者var定义的隐式变量;一种是隐式参数类型的伴生对象内的隐式值。
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
/**
* ⑴所谓的隐式参数,指的是在函数或者方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的,用implicit修饰的对象,即隐式值,并注入参数。
* ⑵Scala会在两个范围内查找:一种是当前作用域内可见的val或者var定义的隐式变量;一种是隐式参数类型的伴生对象内的隐式值。
*/
object implicitParse extends App{
def test(implicit value:String) =println("the value is "+value)
test("Scala")
implicit val name="bruce"
test
}
一、高阶函数
1、函数化简
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
/**
* ⑴接收其他函数作为参数的函数,被称作高阶函数(higher-order function);
* ⑵Scala中,由于函数是一等公民,因此可以直接将某个函数传入其他函数,作为参数;
* ⑶高阶函数的另外一个功能是将函数作为返回值;
* ⑷高阶函数可以自动推断出函数类型,而不需要写明类型;而且对于只有一个参数的函数,还可以省去其小括号;
* 如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,用_来替代即可;
* Array(2,3,5,6).map((x:Int)=>{x*3})
* Array(2,3,5,6).map((x)=>{x*3})
* Array(2,3,5,6).map((x)=>x*3)
* Array(2,3,5,6).map(x=>x*3)
* Array(2,3,5,6).map(_*3)
*/
object functionN extends App{
def myTest(x: Int, y: Int) = {
x * y + 20
}
def fun1(f: (Int, Int) => Int, a: Int, b: Int) = {
f(a, b)
}
println(fun1(myTest, 100, 5))
}
2、常见的高阶函数
二、隐式转换
1、隐式转换
⑴Scala提供的隐式转换和隐式参数功能,是非常有特色的功能,是Java等编程语言所没有的功能。它可以允许手动指定将某种类型的对象转换成其他类型的对象。
⑵Scala的隐式转换,其实最核心的就是定义隐式转换函数,即implicit conversion function。定义的隐式转换函数,只要在编写的程序内引入,就会被Scala自动使用。Scala会根据隐式转换函数的签名,在程序中使用到隐式转换函数接收的参数类型定义的对象时,会自动将其传入隐式转换函数,转换为另外一种类型的对象并返回。这就是隐式转换。
⑶隐式转换函数叫什么名字是无所谓的,通常不会由用户手动调用,而是由Scala进行调用。然而,如果要手动使用隐式转换,则需要对隐式转换函数进行导入。因此通常将隐式转换函数的名称命名为“one2one”的形式。
⑷要实现隐式转换,只要在程序可见的范围内定义隐式转换函数即可。Scala会自动使用隐式转换函数。隐式转换函数与普通函数唯一的语法区别就是,要以implicit开头,而且要指定函数返回类型。
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
class SpecialPerson(val name: String)
class Student1(val name: String)
class Older(val name: String)
object Implicit extends App{
var ticketNm = 0
def buySpecialTticket(spe: SpecialPerson) = {
ticketNm += 1
spe.name + "'s ticket number is " + ticketNm
}
implicit def object2SpecialPerson(obj: Object):SpecialPerson = {
//隐式转换函数需要使用implict声明
//隐式转换的函数名称习惯为:被转换类型2目标类型
//隐式转换函数需要显性的定义返回类型
println("************************")
if (obj.getClass == classOf[Student1]) {
val stu = obj.asInstanceOf[Student1]
new SpecialPerson(stu.name)
}
else if (obj.getClass == classOf[Older]) {
val old = obj.asInstanceOf[Older]
new SpecialPerson(old.name)
}
else new SpecialPerson("None")
}
println(buySpecialTticket(new Student1("bruce")))
}
2、隐式转换-加强类
⑴隐式转换强大之处就是可以在不知不觉中加强现有类型的功能。也就是说,可以为某个类定义一个加强版的类,并定义互相之间的隐式转换,从而让源类在使用加强版的方法时,由Scala自动进行隐式转换调用。
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
/**
* 隐式转换强大之处就是可以在不知不觉中加强现有类型的功能。
* 也就是说,可以为某个类定义一个加强版的类,并定义相互之间的隐式转换,
* 从而让源类在使用加强版的方法时,由Scala自动进行隐式转换为加强类,然后在调用该方法;
* @param name
*/
class Man(val name: String)
class SuperMan(val name: String) {
def emitLaser() = println("emiting laser......................")
}
object SuperMan extends App {
val bruce=new Man("bruce")
implicit def man2superman(man:Man):SuperMan={
new SuperMan(man.name)
}
bruce.emitLaser()
}
3、隐式转换作用域与发生时机
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
/**
* ⑴Scala默认会使用两种隐式转换:
* 一种是源类型,或者目标类型的伴生对象内的隐式转换函数;
* 一种是当前程序作用域内的可以用唯一标识符表示的隐式转换函数;
* ⑵如果隐式转换函数不在上述两种情况下的话,那么就需要手动使用import语法引入某个包下的隐式转换函数,
* 通常情况下,仅仅在需要进行隐式转换的地方,比如某个函数或者方法内,用import导入隐式转换函数,
* 这样可以缩小隐式转换函数的作用域,避免不必要的隐式转换;
* ⑶发生时机
* ①调用某个函数,但是给函数传入的参数的类型,与函数定义的接收参数类型不匹配;
* ②使用某个类型的对象,调用某个方法,而这个方法并不存在于该类型时;
* ③使用某个类型的对象,调用某个方法,虽然该类型有这个方法,但是给方法传入的参数类型,与方法定义的接收参数的烈性不匹配;
* @param name
*/
class Man2(val name: String)
object SuperMan2{
implicit def man22superman2(man:Man):SuperMan2={
new SuperMan2(man.name)
}
}
class SuperMan2(val name: String) {
def emitLaser() = println("emiting laser......................")
}
object Implicit extends App {
import com.example.scala.SuperMan2.man22superman2
val bruce=new Man("bruce")
bruce.emitLaser()
}
4、隐式参数
⑴所谓的隐式参数,指的是在函数或者方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的,用implicit修饰的对象,即隐式值,并注入参数。
⑵Scala会在两个范围内查找:一种是当前作用域内可见的val或者var定义的隐式变量;一种是隐式参数类型的伴生对象内的隐式值。
package com.example.scala
/**
* Created by Bruce on 2017/6/12.
*/
/**
* ⑴所谓的隐式参数,指的是在函数或者方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的,用implicit修饰的对象,即隐式值,并注入参数。
* ⑵Scala会在两个范围内查找:一种是当前作用域内可见的val或者var定义的隐式变量;一种是隐式参数类型的伴生对象内的隐式值。
*/
object implicitParse extends App{
def test(implicit value:String) =println("the value is "+value)
test("Scala")
implicit val name="bruce"
test
}
相关文章推荐
- Scala的函数,高阶函数,隐式转换
- scala中模式匹配、异常处理、高阶函数、偏函数、隐式转换
- scala中的隐式转换详解
- 65.Scala中隐式转换内幕操作规则揭秘、最佳实践及其在Spark中的应用源码解析
- 扒一扒scala隐式转换
- Scala学习笔记--隐式类型和隐式转换
- Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析之Scala学习笔记-51
- scala隐式转换总结
- Scala中隐式转换内幕操作规则揭秘
- scala的implicit关键字----不仅仅是隐式类型转换
- Scala 隐式转换案例(三)
- Scala入门到精通——第十九节 隐式转换与隐式參数(二)
- day5:Scala隐式转换和并发编程
- Scala 中的隐式转换 implicit
- Scala中的Implicit(隐式转换,隐式参数,隐式类)
- Scala之隐式转换
- scala中的隐式转换详解
- scala 隐式转换(一)
- scala总结(4) -- 隐式转换以及隐式参数
- Step into Scala - 26 - 隐式参数,隐式转换与 DSL