方法的基本语法
因为方法有返回值,所以可以像变量一样使用。
如:println(方法)
package tcode.chapter05
object $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.chapter05
object $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 = 10
val b =20
x+y+a+b
}
//如果方法体中有return关键字,返回值必须定义
def add4(x:Int,y:Int):Int = {
println("................")
val a = 10
val b =20
return 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.chapter05
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
object $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+y
def sum(y:Int,x:Int=50) = x+y
def 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.chapter05
object $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+y
val 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 = name
val add4 = add3
}
函数和方法的区别
方法与参数的区别
1)方法定义在类中可以实现重载,函数不可以重载
2)方法是保存在方法区,函数是保存在堆中
3)定义在方法中的方法可以称之为函数,不可以重载,函数是对象,函数名就是变量名,所以函数不可以重载[同一作用域不可以有同名变量]
方法与函数的联系
1)方法可以转成函数, 转换语法: 方法名 _
2)方法可以定义在任何位置,如果定义在方法内(同一作用域,如main方法内),此时就是函数、变量,也就是说不可以重载
package tcode.chapter05
object $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+z
println(sum(10, 20))
}
val func = (x:Int,y:Int) =>x+y
//val func = (x:Int,y:Int,z:Int) =>x+y+z
def add(x:Int,y:Int) = x+y
def add(x:Int,y:Int,z:Int) = x+y+z
def 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.chapter05
object $07_HightFunctionSample {
def main(args: Array[String]): Unit = {
val func = (x: Int, y: Int) => x * y
val func2 = (x: String, y: Int) => x * y
val 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 + 10
m1(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.chapter05
object $13_NoNameFunction {
/**
* 匿名函数的定义: 没有函数名的函数称之为匿名函数
* 匿名函数不能单独调用
* 匿名函数一般是作为值传递给高级函数使用
*/
def main(args: Array[String]): Unit = {
val func = (x:Int,y:Int) => x+y
println(func(20, 30))
//(x:Int,y:Int) => x+y
m1(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+z
func2<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 =1
while(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 /> }
}