kotlin 第六章 函数和lambda表达式

6.1 函数入门

 6.2 函数的形参

  • 定义函数:fun 函数名(形参列表)[: 返回值类型] { 执行语句}
  • 函数名:第一个字母小写,后面每个单词首字母都大写
  • 返回值类型:返回值一个变量或者一个表达式,如果希望没有返回值,可省略返回值部分,或者用Unit来代表没有返回值
  • 形参列表:由零组到多组“形参名:参数类型,组合而成,参数间用“,”隔开
  • 函数的递归:函数体内调用它自身,被称为函数递归。递归一定要向已知方向进行。
  • 单表达式函数:函数只返回单个表达式,此时可以省略花括号并在等号后指定函数体,这种方式被称为单表达式函数。例子:fun area(x:Double, y:Double) : Double = x*y  可简写为fun area(x:Double, y:Double) = x*y 
  • 函数的形参:fun girth(width : Double, height : Double) : Double {   return 2*(width+height)} ,调用函数时1.可根据位置参数来调用------------》girth(3.5 , 4.8) 。2.根据命名参数来调用 girth(width = 3.5, height = 4.8) 或者 girth(height = 4.8, width = 3.5)。 3.混合使用位置参数和命名参数girth(3.5, heigth = 4.8),但是girth(width = 3.5,4.8)这样调用是错误的 。因为命名参数后面只能是命名参数。
  • 形参的默认值 格式---------- 形参名 : 形参类型 = 默认值。例子:fun  sayHi(name : String = "kotlin",message : String = "简单好学"){}--------调用1.直接使用默认值  sayHi(), 2. 使用message默认值 sayHi("黑旋风") ,3.都不使用默认值sayHi("黑旋风",“牛逼”), 只有name使用默认值 sayHi(message = "学起来开心快乐"),所以定义函数将带默认值的参数定义在形参列表的最后
  • 尾递归函数:定义--》当函数调用自身作为它执行的最后一行代码,且递归调用后没有更多的代码时,可使用尾递归语法。注意事项:尾递归不能再异常处理的try、catch、finally块中使用,需要用tailrec修饰。例如计算阶乘的函数:fun fact(n : Int) : Int {
  • if (n == 1){
  • return 1 }else { return n * fact(n -1)}
  • 个数可变的形参:定义函数时,在形参的类型前添加vararg修饰,则表明该形参可接受多个参数值。fun test (a : Int ,vararg books : String){} ,可变形参可在参数列表的任意位置,但是kotlin要求一个函数最多只能带一个个数可变的形参

 6.3 函数重载

  • 定义 : 如果程序包含了两个或者两个以上函数名相同,但是形参列表不同的函数,就被称为函数重载。
  • 重载的重要判断:形参个数不同,形参类型不通过
  • 不推荐用形参个数可变函数,容易造成错误

6.4 局部函数 

  • 定义:函数体内部定义函数称为局部函数
  • 特点:作用只在其封闭区间内,对外部隐藏(若局部函数被返回则作用域会变大)

6.5 高阶函数 

  • 函数类型:函数类型由函数的形参列表、->和返回值类型组成
  • 直接访问一个函数的引用,不是调用时需要在函数名前添加两个冒号,不能添加括号。myFun = ::add;

使用函数类型作为形参类型

fun map(data : Array<Int>, fn: (Int) -> Int) : Array<Int> {

    var result = Array<Int>(data.size,{0})
//遍历data数组的每个元素,并用fn函数对data[i]进行计算
//然后将计算结果作为新数组元素
for(i in data.indices){
    result[i] = fn(data[i])
}
return result
}

//定义一个计算平方的函数
fun square (n : Int) : Int {
 return n*n
}

//定义一个计算立方的函数
fun cube (n : Int) : Int{
return n*n*n
}

//定义一个计算阶乘的函数
fun factorial(n:Int) : Int{
    var result = 1
for(index in 2..n){
result *= index
}
return result
}

//调用
fun main (args : Array<String>){
    var data = arrayOf(3,4,9,5,8)
    
    map(data,::square)
    map(data,::cube)
    map(data,::factorial)
}
  • 使用函数类型作为返回值类型   代码略

6.6 局部函数与Lambda表达式 

  • Lambda表达式与局部函数的区别:1.Lambda表达式总是被大括号括着 2.定义Lambda表达式不需要fun关键字,无须指定函数名。3.形参列表(如果有的话)在->之前声明,参数类型可以省略。4.函数体(Lambda表达式执行体)放在->之后 5.函数的最后一个表达式自动被作为Lambda表达式的返回值,无须使用return 关键字。简单的例子:“square”->return {n:Int ->n*n}
  • Lambda表达式的脱离,作为参数传入的Lambda表达式可以脱离函数独立使用。

6.7 Lambda表达式 

  • Lambda表达式标准语法:{(形参列表)->//零到多条执行语句}
  • Lambda表达式可以在表达式后面直接调用
  • Lambda表达式若根据上下文能推出形参类型,可省略类型不写,若只有一个形参,可省略形参名和类型。
  • 如果函数的最后一个参数是函数类型,且打算传入一个Lambda表达式,那么允许在圆括号之外指定Lambda表达式。
    var list = listOf("Java","Kotlin", "Go")
    //普通形式
    
    var rt= list.dropWhile({e->e.length>3})
    
    //约定写法
    
    var rt = list.dropWhile(){it.lenght>3}
    
  • 如果一个函数既包含个数可变的形参,也包含函数类型的形参,那么就应该将函数类型的形参放在最后面。

6.8 匿名函数 

  • 定义:匿名函数与普通函数基本相似,只要将普通的函数名去掉就变成了匿名函数
  • 匿名函数的使用代替了Lambda表达式不能指定返回值类型的弊端
  • 匿名函数在系统可推断出形参参数类型是允许省略形参类型,但是普通函数则不可以
  • return  在匿名函数中return返回的是函数本身,Lambda表达式中return则返回它所在的函数

6.9 捕获上下文中的变量和常量 

扫描二维码关注公众号,回复: 5445046 查看本文章
  • 定义:Lambda表达式或匿名函数(以及局部函数,对象表达式)可以访问或修改其所在上下文中的常量和变量,这个过程被称为捕获。(不太懂)

6.10 内联函数 

  • 使用inline关键字修饰带函数形参的函数即可。
  • 特点:内联函数是以目标代码的增加为代价来节省时间的开销。什么时候使用内联函数:当被调用的Lambda表达式或函数只包含非常简单的执行代码(尤其是单表达式)就应该使用内联函数,反之则不可用。
  • 部分禁止内联:noinline 用于显式阻止某一个或某几个形参内联化。
  • 非局部返回

猜你喜欢

转载自blog.csdn.net/qq_34207101/article/details/88212543