
20柯理化柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。是把接受多个参数的函数变成接受一个参数的......
20柯理化
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
是把接受多个参数的函数变成接受一个参数的函数;
柯理化的两种表现形式:
以加法函数为例:
defcurring(x:Int)(y:Int)=x+y
defcurring(x:Int)=(y:Int)=x+y
在柯理化形式的基础上,固定一个参数,传入一个参数
scaladefcurring(x:Int)(y:Int)=x+ycurring:(x:Int)(y:Int)Intscalacurring(4)(5)res23:Int=9//第一种方式scalavalfunc1=curring(5)_func1:Int=Int=function1scalafunc1(4)res25:Int=9//第二种方式scalavalfunc2=(x:Int)=curring(x)(5)func2:Int=Int=function1scalafunc2(4)res26:Int=9scaladefcurring(x:Int)=(y:Int)=x+ycurring:(x:Int)Int=Int//第三种方式scalavalfunc3=(x:Int)=curring(x)(5)func3:Int=Int=function1scalafunc3(4)res27:Int=9
柯里化函数,配合implicit关键字使用
//定义带有隐式参数的add方法//implicit修饰参数,代表该参数是隐式参数scaladefadd(a:Int)(implicitb:Int=5)=a+badd:(a:Int)(implicitb:Int)Int//直接传参scalaadd(4)(5)res22:Int=9scalaadd(4)(10)res24:Int=14//执行时,首先找当前环境是否有和隐式参数类型相同的隐式值,如果找到,用隐式值作为隐式参数//如果没找到,看隐式参数是否有默认值,如果有,使用默认值//如果还没找到,那就抛异常//当前环境没有和隐式参数类型相同的隐式值,隐式参数有默认值,使用默认值//4+5(默认值)scalaadd(4)res25:Int=9//定义隐式值scalaimplicitvalb1:Int=20b1:Int=20//当前环境有和隐式参数类型相同的隐式值,使用隐式值//4+20(隐式值)scalaadd(4)res26:Int=24//通过implicitly[Int]可提取出当前环境的隐式值并赋给变量scalavalc:Int=implicitly[Int]c:Int=20//定义String类型隐式值scalaimplicitvalb2:String="aa"b2:String=aascalaadd(4)res27:Int=24//定义Int类型隐式值,当前环境有两个Int类型的隐式值scalaimplicitvalb3:Int=30b3:Int=30//由于当前环境有两个Int类型的隐式值,调用时不知道找哪个,所以报错scalaadd(4)console:16:error:ambiguousimplicitvalues:bothvalueb1oftype=Intandvalueb3oftype=IntmatchexpectedtypeIntadd(4)^//由于当前环境已乱套,可通过退出重进解决scala:quitC:\Users\(JavaHotSpot(TM)64-BitServerVM,_131).:
在开发环境中使用柯里化和implicit,切记不能在同一个类中使用
packageutil//隐式成员是单独放在一个地方,使用的时候引入objectMyPredef{//定义隐式值1implicitvalb1:Int=10//定义隐式值2implicitvalb2:Int=20}packageday03objectCurringDemo{//定义带有隐式参数的方法defadd(a:Int)(implicitb:Int=5)=a+bdefmain(args:Array[String]):Unit={println(add(4)(1))println(add(4))//引入隐式值之后,当前环境就有隐式值了(add(4))//当前环境有两个Int类型隐式值,报异常////println(add(4))}}海汼部落原创文章,原文链接:()