scala详细笔记(四)scala基础语法之方法和函数详解

  1. 方法和函数的作用几乎是一样的,但是函数在使用的过程中更加灵活和多样化
  2. scala中函数是头等公民 . 可以作为方法的返回值和参数使用
  3. scala是一个集面向对象和面向函数于一身的多范式编程语言 , 灵活的函数是函数式编程的一种体现
  4. 函数的使用使代码更加的简介和灵活

1 函数 

scala中一种函数式编程语言 ,函数是scala中的头等公民,建议优先使用函数 , 函数实现的功能和方法一样 ,但是我们可以把函数理解成一种特殊的业务逻辑对象 ,所以函数可以作为参数和返回值.... 函数也是用来处理数据的代码封装 !

函数式编程是scalain编程语言的一大特点!

1.1 函数的定义

方式一

val| var 函数名称=(函数的参数列表) => 函数体

val add = (x: Int, y: Int) => {
  x + y
}
val parseStr = (str: String) => {
  str.toUpperCase()
}

//  函数体中的内容只有一行代码可以省略大括号
 var product = (x:Double) => x*x

    

 

函数可以作为最终的表达式存在,返回的内容就是函数的签名 签名(函数的名称,函数的参数,函数的返回值类型) 这种定义方式不需要指定返回值类型,编译器会自动推断

方式二

val | var 函数名称:(输入参数类型)=> 返回值类型 = (参数的引用)=> 函数体

/ 函数定义的第二种种方式
val add2:(Int,Int)=>Int=(x,y)=>{
  x+y
}
add2 函数名
(Int ,Int) 要处理的参数类型列表
=>Int  函数处理完数据的返回值类型
=(x,y) 传入实际参数的接收变量名
{x+y}  函数体 运算求和  
注意: 代码块的最后一行是函数的返回值 ,需要和=>(Int)类型保持一致

 

1.2 特殊没有参数的函数

val show:()=>Unit=()=>{
   println("show.....")
 }
 
 val  show2=()=>{
   println("show2......")
 }
 
 val get:()=>String=()=>{
   "给你们"
 }
 // 没有参数的函数 自动推断类型
val get2=()=>{
  ""
}

1.3 函数的细节

函数中的参数;列表可以有多个,也可以没有参数 ,没有参数的函数调用的时候不用写()

函数的参数和返回值可以是值类型,也可以是引用类型,

函数的返回值和参数是函数的时候称为高阶函数

函数的最后一行为推断函数返回值的重要依据 , 可以省略return

函数中可以在声明函数

1.3 例子

**
 * 函数和方法十分类似 在功能上的作用几乎是一样的
 *  一般在使用的时候建议优先使用函数 [函数是头等公民]
 *  1 不可变的  2 对象单独存在 3 可以作为方法的参数传递
 */
object Demo {

  // 定义一个方法
  def madd(x:Int ,y:Int)={x+y}
  //定义一个函数
  val fadd = (x:Int,y:Int)=>{x+y}
  // 方法和函数之间是可以转换的
  val ff = madd _

  def operation(i:Int,j:Int,f:(Int,Int)=>Int): Int ={
    f(i,j)
  }

  def main(args: Array[String]): Unit = {
    println(madd(1, 2))
    println(fadd(1, 2))
     // 在面向函数式编程中  函数类型的参数也可以传递对应的方法 (偷偷转换成了函数)
    println(operation(2, 3, madd)) //  参数三 函数   方法(偷偷转换成了函数)
    println(ff)  //<function2>
  //  println(madd)  // 方法是不能独立存在
    println(fadd) // <function2>

  }

}
object FunctionDemo1 {

  /**
   * 定义一个函数  字符串的拼接
   * 处理的数据 是两个String
   * 返回值    字符串
   */
  // 处理两个字符串  => {处理逻辑}
  val f1 = (str1: String, str2: String) => {
    str1 + " " + str2
  }

  val f2 = (x: Int, y: Int, z: Int) => {
    x + y + z
  }

 val f3 =  (str:String) =>{
    str.toUpperCase()
  }


  val f4 = (x:Double ,y:Double)=>{
    var res:Double = 0d
    if(x>y){
      res=x
    }else{
      res=y
    }
    res
  }
  // 没有返回值的函数
  val f5: String => Unit = (name:String) =>{
    println(s"hello $name")
  }


  def main(args: Array[String]): Unit = {
    val str = f1("aaa", "ccc")
    // 函数的调用和方法的调用一样
    println(str)
    println(f2(1, 2, 3))
    println(f3("hello"))
    println(f4(23, 101))
  }

}
object  FunctionDemo2 {
  /**
   *  对两个int类型的数据处理
   *  参数一 x
   *  参数二 y
   *  参数三 : 函数  指定怎么操作x y   处理两个Int
    */

  def operation(x:Int ,y:Int , f:(Int,Int)=>Int )={
    f(x,y)
  }
  val f1 = (x:Int ,y:Int)=>{
    x*y
  }
  val f2 = (x:Int ,y:Int)=>{
    x+y
  }
  val f3 = (x:Int ,y:Int)=>{
    x*x+y*y
  }

  def main(args: Array[String]): Unit = {
    // 调用方法
    /**
     * 参数三  传入什么样的函数  就怎么处理数据  代码更加灵活
     */
    val res = operation(2, 3, f1)
    // 匿名函数
    val res2 = operation(2, 3, (x:Int,y:Int)=>{x*10+y*10})
    println(res)

  }

}

 

 

2 方法

方法是逻辑片段的封装 ,可以处理一个或者多个数据 , 可以有返回值也可以没有没有返回值 ,提高了代码的复用性

2.1 方法的定义

def functionName ([参数列表]) : [return type] = {
   function body
   return [expr]
}
没有等号和方法体的方法称为抽象方法,抽象方法定义在抽象类和特质中

// 定义一个方法 有两个参数  有返回值
def add(x:Int , y:Int):Int={
  val sum = x + y
  sum
  // return 可以省略 , 代码块的最后一行就是这个方法的返回值
//  return sum
}

/**
  * 定义一个没有参数没有返回值的方法  Unit关键字代表没有返回值 类似于java中的void
  */
 def show()={
  println("show......")
}
/**
  * 如果方法没有参数  方法后面的() 可以省略  ,注意在调用的时候也不要书写小括号
  */
def show2={
  println("show......")
}
// 在抽象类或者特质中定义抽象方法
def m1

2.2 方法的调用

* 方法的调用和java中的调用方式不太一样
* 如果方法定义在object中 在本类直接方法名调用  在其他类中调用 object 对象名调用
* 如果方法定义在普通的class 类中 , 本类之间直接调用! 其他类中new 类 .方法调用

2.3 嵌套方法

嵌套的方法必须指定返回值类型

def  factorial(x:Int):Int={
  def fact(x:Int ,y:Int):Int={
    if(x<=1) y
    else fact(x-1 , x*y)
  }
  fact(x,1)
}

2.4 方法总结

注意方法的参数和返回值可以是函数 ,这样的方法称为高阶函数 ,高阶函数中详细讲解

1,定义方法的关键字,def

2,方法的返回值,最后一行的内容,如果是循环,那么返回值是 Unit学大数据上多易教育 

3,如果空参方法,定义的时候有(),调用的时候可以省略(),但是如果定义的时候没

有(),调用方法的时候,不能加()

4,方法的返回值类型,可以省略,但是特殊情况下,必须加上:

4.1,方法有 return 关键字

4.2,递归调用的方法。

5,方法不能最为最终的表达式存在,(空参的方法调用除外)

2.5 例子

class Demo1 {
  // 类中定义的方法
  def test1() = {
    println("test1........")
  }

  // 定义一个可变参数
  def add(args: Int*): Int = {
    var sum: Int = 0
    // 遍历传入的实参
    for (i <- args) {
      sum += i
    }
    sum
  }

  // 递归方法   递归的方法不能省略返回值类型  必须执行  否则报错
  def pro(x: Int): Int = {
    if (x <= 1) {
      1
    } else {
      // 递归 自己调用自己  一定要指定返回值类型
      x * pro(x - 1)
    }
  }

  // 方法有return 的必须执行返回值类型
  def test2(): Int = {
    return 2
  }


}
/**
 * 方法的声明
 * object中的内容都是静态的
 * 方法也是静态的方法
 * 1  本类中调用的时候直接方法名调用
 * 2  其他类中调用方法的时候
 * 3  class 类中的方法如何调用??
 */
object MethodDemo1 {
  /**
   * 定义一个求和的方法
   * 参数 两个 Int
   * 返回值 一个  Int
   * def 方法名(参数列表):返回值={方法体}
   * :返回值=  可以省略
   * ---------------------
   * 方法名add
   * 方法的参数列表( x:Int   ,  y:Int )
   * 方法的返回值 可以省略 , 方法体的最后一行就是方法的返回值   add(x:Int,y:Int)={方法体}
   * 不省略  :Int = {方法体}
   */
  def add(x: Int, y: Int): Int = {
    x + y
  }

  /**
   * 这个方法没有返回值  Unit 相当于void
   *
   * @param name
   */
  def sayHello(name: String) = {
    println(s"hello $name")
  }

  // 没有参数的方法
  def show() = {
    println("我好帅啊  ! 有个屁用!!")
  }

  // 没有参数的方法 () 可以省略
  def show2 = {
    println("我好帅啊  ! 有个屁用!!")
  }

  def concat(str1: String, str2: String): String = {
    s"$str1 : $str2"
  }

  def main(args: Array[String]): Unit = {
    println(add(1, 2))
    sayHello("班长")
    show()
    show2 // 方法在定义的时候没有()  就不要写() 调用
   val res =  concat("tom", "cat")
    println(res)
  }

}
/**
 * 对数组排序
 */
object SortArray {

  def main(args: Array[String]): Unit = {
    val arr = Array(11,3,45,32,44,13,66,41)
    // 对数组进行排序  返回一个有序的新的数组
    val rdd2 = arr.sorted
    // 数组的遍历  arr2.for
    for (elem <- rdd2) {
      println(elem)
    }
  }

}
object Test1 {
  def main(args: Array[String]): Unit = {
    // 调用object中的方法   静态方法
    MethodDemo1.sayHello("ZSS")
    // 调用类中的方法   普通方法
   // 创建对象 点方法
   val demo = new Demo1()
    demo.test1()
    val res = demo.add(1, 2, 3, 4, 5, 6)
    println(res)
    // 调用递归的阶乘方法
    println(demo.pro(4))

  }

}
def binarySearch(arr: Array[Int], find: Int): Int = {
  if (arr.length == 0) {
    println("数组为空")
    return -1
  }
  // 对待排的数组排序
  val sorted: Array[Int] = arr.sorted
// 起始位置所以
  var start = 0
// 检索的最后一个元素
  var end = arr.length - 1
  while (start <= end) {
    val midd = (start + end) / 2
    if (sorted(midd) > find) {
      end = midd - 1
    } else if (sorted(midd) < find) {
      start = midd + 1
    } else {
      println(s"$find in index :$midd")
      return midd
    }
  }
  return -1
}

3 方法和函数

3.1 互相转换

def add(x: Int, y: Int) = {
  x + y
}
// 将方法转换成函数
val f = add _

当我们将方法作为参传递的时候 ,其实底层是将方法自动转换成函数

3.2 区别

在函数式编程语言中,函数是“头等公民”,它可以像任何其他数据类型一样被传递

函数可以当成值来进行传递,方法的参数和返回值都可以是函数。

函数和变量,类,对象, 是一个级别的。

区别和联系:

  1. 方法用 def 关键字定义,函数的标识 =>
  2. 方法不能作为最终的表达式存在,但是函数可以,返回函数的签名信息
  3. 方法和函数调用的时候都需要显示的传入参数

4,函数可以作为方法的参数,和返回值类型。

猜你喜欢

转载自blog.csdn.net/qq_37933018/article/details/106909727