方法的基本语法

因为方法有返回值,所以可以像变量一样使用。
如:println(方法)
package tcode.chapter05object $01_MethodDefind {/*** 方法的定义基本语法: def 方法名(参数名:类型,....): 返回值类型 = {方法体}* 方法的方法体的块表达式的结果值类型必须与返回值类型匹配**/def main(args: Array[String]): Unit = {println(add(10, 20))}def add(x:Int,y:Int):Int = {x+y}}
至简原则—定义时
1、如果方法体只有一行语句,那么方法体的{}省略<br /> 2、如果将方法体的块表达式的结果值作为方法的返回值,那么方法的返回值类型可以省略<br /> 注意:如果方法体中有return关键字,返回值必须定义<br /> 3、如果方法不需要返回值,=可以省略[=与方法体的{}不能同时省略]<br /> 4、如果方法不需要参数,()可以省略<br /> 注意:<br /> 1、如果定义方法的时候没有(),在调用的时候不能带上()<br /> 2、如果定义方法的时候有(),那么在调用的时候()可有可无
package tcode.chapter05object $02_MethodSample {def main(args: Array[String]): Unit = {println(add2(10, 20))println(add3(10, 20))//如果定义方法的时候没有(),在调用的时候不能带上()hello2//如果定义方法的时候有(),那么在调用的时候()可有可无hello()hello}//标准形式def add(x:Int,y:Int):Int = {x+y}// 1、如果方法体只有一行语句,那么方法体的{}省略def add2(x:Int,y:Int):Int = x+y//2、如果将方法体的块表达式的结果值作为方法的返回值,那么方法的返回值类型可以省略def add3(x:Int,y:Int) = {println("................")val a = 10val b =20x+y+a+b}//如果方法体中有return关键字,返回值必须定义def add4(x:Int,y:Int):Int = {println("................")val a = 10val b =20return x+y+a+b}def printHello(msg:String):Unit = {println(s"hello:${msg}")}//如果方法不需要返回值,=可以省略[=与方法体的{}不能同时省略]def printHello2(msg:String) { println(s"hello:${msg}") }def hello():Unit = {println("hello..............")}//4、如果方法不需要参数,()可以省略def hello2 = println("hello...............")}
参数:
* 1、默认值参数: def 方法名(参数名:类型=默认值,...):返回值类型 = {...}<br /> * 默认值参数一般放在参数列表最后面<br /> * 2、带名参数: 在调用方法的时候指定将值传递给哪个参数<br /> * 3、可变参数: def 方法名(参数名:类型*):返回值类型 = {...}<br /> * 可变参数不能与默认值参数一起使用<br /> * 可变参数可以与带名参数一起使用<br /> * 如果想要将集合的所有元素传递给可变参数,需要通过 集合名:_* 的方式传递
可变参数作为某函数的返回值的时候,本质上是集合,例如用for将多个可变参数的值返回后就是一个集合
package tcode.chapter05import java.time.LocalDateTimeimport java.time.format.DateTimeFormatterobject $03_MethodParam {/*** @param args*/def main(args: Array[String]): Unit = {println(add(10, 20))println(add())println(add(100))println(sum(50))//带名参数: 在调用方法的时候指定将值传递给哪个参数println(sum2(y=50))println(sum3(x=50, z=1, 2, 3, 4, 10, 20, 30))val paths = getPath(7, "/gmall/user_info")readFiles(paths:_*)}//默认值参数: def 方法名(参数名:类型=默认值,...):返回值类型 = {...}def add(x:Int=10,y:Int=50):Int = x+ydef sum(y:Int,x:Int=50) = x+ydef sum2(x:Int=50,y:Int) = x+y//可变参数def sum3(x:Int,z:Int*) = s"${x}-${z.sum}"//sum3(10,20,30,40,50)//需求: 统计前7天的用户登录数///gmall/user_info/20210518///gmall/user_info/20210517///gmall/user_info/20210516///gmall/user_info/20210515///gmall/user_info/20210514///gmall/user_info/20210513///gmall/user_info/20210512//for作为最后一条语句,返回的是一个集合:def getPath(n:Int,pathPrex:String) = {//日期操作、jdbc操作、json、http操作//获取当前日期val currentTime = LocalDateTime.now()//获取前N天的日期for(i <- 1 to n) yield{val time = currentTime.plusDays(-i)val timestr = time.format(DateTimeFormatter.ofPattern("yyyyMMdd"))s"${pathPrex}/${timestr}"}// n个返回值,对应下面的paths:String*}def readFiles(paths:String*) = {//数据读取for(path<- paths){println(path)}}}
函数的基本语法:


函数的定义语法: val 函数名 = (参数名:参数类型,…) => { 函数体 } —>函数字面量,就是函数的值,字面量左边就是引用。
函数类型:(参数类型,…)=> 返回值类型
函数的返回值就是函数体块表达式的结果值
函数的简化(相比方法只有一条简化规则): 如果函数体中只有一行语句,那么函数体的{}可以省略
函数作为方法|函数的参数的调用:
函数在定义方法|函数体内的使用:
方法就是函数,函数也是对象,函数名就是函数对象的引用,所以调用函数的时候必须带上(),不带上,打印的时候会打印地址
函数就是对象的证明:与变量格式是一致的:
如变量:val name:String = “ldc”,省略变量名后:val name = “ldc”
函数: val add =函数字面量
可以看出格式是一致的
另外:所有函数都是继承Function类
package tcode.chapter05object $04_FunctionDefined {def main(args: Array[String]): Unit = {println(add(10, 20))println(add2(10, 20))println(add4(20,30))println(hello())}val add = (x:Int,y:Int) => {x+y}val add2 = (x:Int,y:Int) => x+yval hello = () => println("hello...")val add3 = new Function2[Int,Int,Int] {//函数体override def apply(x: Int, y: Int): Int = x+y}val name = "zhangsan"val name2 = nameval add4 = add3}
函数和方法的区别
方法与参数的区别
1)方法定义在类中可以实现重载,函数不可以重载
2)方法是保存在方法区,函数是保存在堆中
3)定义在方法中的方法可以称之为函数,不可以重载,函数是对象,函数名就是变量名,所以函数不可以重载[同一作用域不可以有同名变量]
方法与函数的联系
1)方法可以转成函数, 转换语法: 方法名 _
2)方法可以定义在任何位置,如果定义在方法内(同一作用域,如main方法内),此时就是函数、变量,也就是说不可以重载
package tcode.chapter05object $05_MethodAndFunction {def main(args: Array[String]): Unit = {add(10,20,30)val func2 = printHello _func2("haha")def sum(x:Int,y:Int) = x+y// def sum(x:Int,y:Int,z:Int) = x+y+zprintln(sum(10, 20))}val func = (x:Int,y:Int) =>x+y//val func = (x:Int,y:Int,z:Int) =>x+y+zdef add(x:Int,y:Int) = x+ydef add(x:Int,y:Int,z:Int) = x+y+zdef printHello(msg:String) = println(msg)}
高阶函数
定义:参数为函数的方法/函数称为高阶函数
高阶函数简写—调用时
//1、直接将函数值作为参数传递给高阶函数
//2、函数字面量的参数类型可以省略
//1、直接将函数值作为参数传递给高阶函数println(add(10, 20, (x: Int, y: Int) => x * y))//2、函数的参数类型可以省略println(add(10, 20, (x, y) => x + y))
//3、如果函数的参数在函数体中只使用了一次,那么可以用代替
1、函数的参数的使用顺序与定义顺序不一致,不可以用代替<针对函数的参数有多个的情况>
2、如果函数体中有嵌套[()],函数的参数在函数体的嵌套中以表达式的形式存在,不可以用_代替
如:
println(add(10, 20, (x, y) => (x + 10) * y)) 不可以println(add(10, 20, (x, y) => (x) * y)) 可以
3、如果函数只有一个参数,在函数体中直接返回参数,此时不可以用_代替<针对函数的只有一个参数的情况>
val f = (x: Int) => x + 10 不可val f = x=>x 不可
//4、如果函数只有一个参数,函数的()可以省略
package tcode.chapter05object $07_HightFunctionSample {def main(args: Array[String]): Unit = {val func = (x: Int, y: Int) => x * yval func2 = (x: String, y: Int) => x * yval name = "zhagnsan"println(add(10, 20, func))//1、直接将函数值作为参数传递给高阶函数println(add(10, 20, (x: Int, y: Int) => x * y))//2、函数的参数类型可以省略println(add(10, 20, (x, y) => x + y))//3、如果函数的参数在函数体中只使用了一次,那么可以用_代替// 1、函数的参数的使用顺序与定义的顺序不一致,不可以用_代替<针对函数的参数有多个的情况>// 2、如果函数体中有嵌套[()],函数的参数在函数体的嵌套中以表达式的形式存在,不可以用_代替// 3、如果函数只有一个参数,在函数体中直接返回参数,此时不可以用_代替<针对函数的只有一个参数的情况>println(add(10, 20, _ + _))//3.1 函数的参数的使用顺序与定义的顺序不一致,不可以用_代替println(add(10, 20, (x, y) => y - x))println(add(10, 20, _ - _))//3.2 如果函数体中有嵌套,函数的参数在函数体的嵌套中以表达式的形式存在,不可以用_代替println(add(10, 20, (x, y) => (x + 10) * y))//println(add(10, 20, ( _+10 ) *_ ))//( _+10 ) *_ ) 解析成 y=> (x=>x+10) * y//( _+10 ) 解析成 x=>x+10// 如果函数体中有嵌套,但是函数的参数在嵌套中不以表达式存在的时候,可以用_代替的println(add(10, 20, (x, y) => (x + 10) * y))println(add(10, 20, _ * _))//3.3 如果函数只有一个参数,在函数体中直接返回参数,此时不可以用_代替val f = (x: Int) => x + 10m1(10, f)//直接传递函数值println(m1(10, (x: Int) => x + 10))//函数参数类型可以省略println(m1(10, (x) => x + 10))// 使用_代替println(m1(10, _ + 10))println(m1(10, x => x))//不能简化println(m1(10, _))//m1(10,_ )解析的形式:val m2 = (func: (Int) => Int) => func(10)m2(x => x + 1)val func3 = m1(10, _)//m1(10,_ )//4、如果函数只有一个参数,函数的()可以省略println(m1(10, (x) => x + 10))println(m1(10, x => x + 10))}//高阶函数!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!def add(x: Int, y: Int, func: (Int, Int) => Int) = func(x, y)def m1(x: Int, func: Int => Int) = func(x)}
匿名函数
1)说明
没有名字的函数就是匿名函数,
可以直接通过函数字面量(λ表达式)来设置匿名函数,函数字面量定义格式如下。
2)案例实操
package tcode.chapter05object $13_NoNameFunction {/*** 匿名函数的定义: 没有函数名的函数称之为匿名函数* 匿名函数不能单独调用* 匿名函数一般是作为值传递给高级函数使用*/def main(args: Array[String]): Unit = {val func = (x:Int,y:Int) => x+yprintln(func(20, 30))//(x:Int,y:Int) => x+ym1(10,20,(x:Int,y:Int) => x+y)}def m1(x:Int,y:Int,func: (Int,Int)=>Int) = func(x,y)}
柯里化
def m1(x:Int,y:Int,z:Int) = x+y+z//柯里化def m2(x:Int)(y:Int)(z:Int) = x+y+z
package tcode.chapter05
object $14_Currying {
/*
柯里化: 有多个参数列表的方法称之为柯里化
*/
def main(args: Array[String]): Unit = {
println(m2(10)(20)(30))val func = m3(10)val func2 = func(20)<br /> val r = func2(30)println(r)m3(10)(20)(30)val func3 = m2 _<br /> val func4 = m3 _<br /> }
def m1(x:Int,y:Int,z:Int) = x+y+z
//柯里化
def m2(x:Int)(y:Int)(z:Int) = x+y+z
//柯里化的演变
def m3(x:Int) = {
val func = (y:Int) =>{val func2 = (z:Int) => x+y+zfunc2<br /> }func<br /> }
闭包
package tcode.chapter05
object $15_ClosePackage {
/*
闭包: 函数体中使用了外部变量的函数
@param args
/
def main(args: Array[String]): Unit = {
println(func(10))
}
val y = 10
//闭包
val func = (x:Int) => {
val z = 10
x+y
}
}
递归
package tcode.chapter05
object $16_Recursion {
/*
递归: 自己调用自己
满足两个条件才能称之为递归:
1、必须要有退出条件
2、必须定义返回值类型
定义递归函数的时候必须指定函数的类型
*/
def main(args: Array[String]): Unit = {
println(m1(5))<br /> println(func(5))<br /> }
val func:Int=>Int = (n:Int) => {
if(n==1) 1
else n * func(n-1)
}
def m1( n:Int ):Int = {
if( n ==1 ) 1
else n * m1(n-1)
}
}
惰性
package tcode.chapter05
object $17_Lzy {
/*
惰性求值: 变量不会立即初始化而是等到真正使用的时候才会初始化
语法: lazy val 变量名 = 值
@param args
*/
def main(args: Array[String]): Unit = {
lazy val name = "zhangsan"println(name)println("---------------")
控制抽象
空格=> 返回值类型
package tcode.chapter05
object $18_ControlAbstract {
/*
控制抽象:
用途: 只能作为方法的参数存在,不能单独使用
语法: 代码块没有标志符,所以没有类型,模仿函数,用空格代替标志符及其类型: 空格=> 返回值类型
控制抽象其实就是一个块表达式,=> 返回值类型 代表快表达式的结果值类型必须是指定类型
本质:没有参数的函数
*/
def main(args: Array[String]): Unit = {
var e =1while(e<=10){<br /> println(s"e=${e}")<br /> e=e+1<br /> 10<br /> }e = 1<br />// 调用: 控制参数就是代码块<br /> myWhile({<br /> e<=10<br /> })({<br /> println(s"e=${e}")<br /> e=e+1<br /> 10<br /> })<br /> }<br />//定义: 由参数可看出是控制抽象<br /> def myWhile(condition: => Boolean)(loop: => Unit):Unit = {if(condition){<br /> loop<br /> myWhile(condition)(loop)<br /> }
}
