scala入门2-方法、函数、高阶函数

方法、函数、高阶函数

1、方法

def method1(x:Int,y:Int):Int={x+y}
def 方法名(变量名:变量类型,...):返回值类型={方法体}

scala方法可以定义在方法中
    方法如果定义在类中是可以重载的
    方法如果定义在方法中是不可以重载的

2、方法简化原则

1)方法体只有一行,{}可以省略
2)返回值类型为Unit,=可以省略
3)方法体的最后一行作为返回值类型,则返回值类型可以省略
4)方法不需要参数,()可以省略

注意:
    1和2,不能同时省略
    方法体中有return关键字,则3不能省略
    4如果省略了,调用时也要省略()
    4如果没有省略,调用时()可省可不省

3、方法参数

java方法参数:
    1、public 返回值类型 方法名(类型 参数名,..) { 方法体 }
    2、可变参数: public 返回值类型 方法名(类型... 参数名) { 方法体 }
scala方法的参数
    1、正常形式: def 方法名(参数名:类型,..):返回值类型 = {方法体}
    2、默认值: def 方法名(参数名:类型=默认值,..):返回值类型 = {方法体}
        如果默认值单独使用,在定义方法的时候需要将默认值定义在参数列表最后面
    3、带名参数:
        指调用方法的时候将指定值传递给哪个参数:  方法名(参数名=值)
    4、可变参数: def 方法名(参数名:参数类型,..,参数名:参数类型*)
        可变参数必须定义在参数列表的最后面
        可变参数不能与默认值参数、带名参数一起使用
        可变参数不能直接传递集合,但是可以通过 集合名称:_*  的方式将集合的所有元素传递给可变参数
	//集合名称:_*  可将集合的所有元素传递给可变参数
	def main(args: Array[String]): Unit = {
	    val value = getDates(7, "/com/hive/user/warehouse/user_info")
	    println(getPaths(value: _*))
	}
	
	def getPaths(paths: String*): Unit = {
	    println(paths.toBuffer)
	}
	
	def getDates(n: Int, prefix: String) = {
	    val time = LocalDateTime.now()
	
	    for (i <- 1 to n) yield {
	    val time1 = time.plusDays(-i)
	    val str = time1.format(DateTimeFormatter.ofPattern("yyyyMMdd"))
	    s"$prefix/$str"
	    }
	}

4、函数

 定义方式:val或var 变量名 = (变量名:变量类型,...)=>{方法体}
    函数的返回值就是函数体的块表达式的结果值
    函数不可以重载,因为函数名其实就是变量名,同一作用域不能存在同名参数
	def main(args: Array[String]): Unit = {
	    var f1 = (x: Int, y: Int) => {
	    x + y
	    }
	    println(f1)
	    println(f1(1,2))
	    println(f2(3))
	    println(f3)
	    println(f3(1,3))
	}
	
	var f2 =(x:Int)=> x*10
	//方法就是函数,函数也是对象
	val f3 = new Function2[Int,Int,Int] {
	    override def apply(v1: Int, v2: Int): Int = {
	    v1+v2
	    }
	
	    override def toString(): String = "this is f3"
	}

5、函数简化

如果函数体中只有一行语句,{}可以省略
函数在调用的时候必须带上()

6、方法和函数的关联

  方法可以看成是函数,函数也是对象
   区别:
        1)方法可以重载,函数因为其实是对象,所以在同个作用域下不能重载
        2)方法在方法区,函数在堆区
    联系:
        1)方法可以转为函数: val或var 函数名=方法名 _
        2)如果方法定义在方法内,那它其实就是函数
	def main(args: Array[String]): Unit = {
	    //函数转为方法
	    var f1 = add _
	    //方法就是函数
	    add2(1, add)
	}
	
	def add(x: Int) = {
	    x * 10
	}
	
	def add2(x: Int, func: Int => Int) = {
	    func(x)
	}

7、高阶函数

    高阶函数:  以函数作为参数或者返回值的方法/函数称之为高阶函数
    匿名函数:没有名字的函数,不能单独使用,只能作为参数写在调用高阶函数的参数列表内(在简化中有示例)
    在方法的参数列表中定义函数,相当于在参数列表中有一个参数的类型是函数(因为函数也是对象)
        def 方法名(变量名:变量类型,..变量名:函数定义类型):返回值类型={方法体}

8、高阶函数简化

    调用高阶函数时:
        1、函数的可以直接写在方法参数列表里,相当于匿名函数
        2、函数的参数类型可以省略
        3、如果函数的参数在函数体中只使用了一次,可以用_代替
            注意1:多个参数的参数列表顺序和函数体内调用的顺序必须一样才可以简化
                2:单个参数并且在函数体中直接返回时,也不能简化
                3:参数在函数体中用()中使用,并且()内构成一个表达式时,也不能简化
        4、如果函数的参数只有一个,()可以省略
	 def main(args: Array[String]): Unit = {
	        val func = (x: Int, y: Int) => x + y
	        //普通方式
	        println(add(1, 2, func))
	        //简化1
	        println(add(1, 2, (x: Int, y: Int) => x + y))
	        //简化2
	        println(add(1, 2, (x, y) => x + y))
	        //简化3
	        println(add(1, 2, _ + _))
	        //简化3.1
	        //println(add(1, 2, (x, y) => y - x)) 不能简化为 println(add(1, 2, _ - _))
	        //简化3.2
	        //println(add2(1,x=>x)) 不能简化为 println(add2(1, _))
	        //简化3.3
	        //println(add2(1,x=>(x+2)*2)) 不能简化为 println(add2(1,(_+2)*2))
	        //简化4
	        println(add2(1, x => x + 1))
	    }
	
	    def add(x: Int, y: Int, func: (Int, Int) => Int) = {
	        func(x, y)
	    }
	
	    def add2(x: Int, func: Int => Int) = {
	        func(x)
	    }

9、函数柯里化和闭包

    1.柯里化:将一个参数列表内有多个个参数的函数转化成接受多个单参数列表的过程
    2.闭包:就是一个函数/方法和与其相关的引用环境(变量)组合的一个整体
	 	//柯里化,演变过程,add为普通单参数列表的函数,add2为两个参数列表,add3为三个参数列表
	    println(add(1, 2, 3))
	    //可以看出add2的返回值类型为一个函数,所以add2(1)为一个函数可以继续调用
	    println(add2(1)(2, 3))
	    //同理add3为嵌套的调用
	    println(add3(1)(2)(3))
	
	    //变量和方法b组成闭包
	    val i = 3
	
	    def b(x: Int) = {
	        x + i
	        }
	    }
	
	    def add(x: Int, y: Int, z: Int): Int = {
	        x + y + z
	    }
	
	    def add2(x: Int): (Int, Int) => Int = {
	        (y: Int, z: Int) => {
	        x + y + z
	        }
	    }
	
	    def add3(x: Int): Int => Int => Int = {
	        (y: Int) => {
	        (z: Int) => {
	            x + y + z
	        }
	        }
	    }

10、递归

与java的一样,必须要有跳出递归的判断条件
另外注意,递归的方法必须写返回值类型

11、惰性求值

加上关键字lazy后,该变量会在使用时才赋值,注意不能修饰var变量

12、控制抽象

    {}包裹的代码块,可以赋值给变量,也可以用来作为参数传给方法,此时这个{}就是控制抽象
    def 方法名(参数名:参数类型,...变量名: => 块表达式返回值类型) :返回值类型={方法体}
    其中[: =>块表达式返回值类型]就是控制抽象,后续调用时直接写变量名,不能写()
		def main(args: Array[String]): Unit = {
		    f1({
		        println("test f1")
		    })
		    //用抽象控制模仿for循环
		    loop(5)({
		        println("test loop")
		    })
		}
		
		def f1(op: => Unit) = {
		    op
		    op
		    op
		}
		
		def loop(x: Int)(op: => Unit): Unit = {
		    if (x > 0) {
		        op
		        loop(x - 1)(op)
		    }
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿-瑞瑞

打赏不准超过你的一半工资哦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值