小白学scala日记day2——方法和函数


方法和函数的区别

 1. 定义的语法不同
方法: def 方法名字(参数列表): 返回值类型 = { 方法体 }
函数: val 函数变量: 函数的类型(可以不设置) = (函数的参数列表) => { 函数体 }
 2. 定义的位置不同
方法: 一般定义在类内、特质内、或者在某一个object内
函数: 一般定义在类内、特质内、object内、方法内
3.方法不能做为最终表达式出现,而函数可以
4. 方法名是方法调用,而函数名只是代表函数对象本身 (函数必须使用()进行调用才能执行)
5. 方法可以转换为函数,所以一般也不必严格区分
- 自动转换:在需要函数的地方,如果传递一个方法,Scala能够自动把方法转换为函数
- 手动转换:手动使用神奇的下划线_ 将方法被转化成函数

# 不管方法和函数调用时加上()都没问题,以下情况除外
scala> def m0=1
m0: Int

scala> m0
res265: Int = 1

scala> m0()
<console>:15: error: Int does not take parameters
       m0()
         ^

案例:

函数:

object Function {
  def main(args: Array[String]): Unit = {
    // 1. 定义一个Scala的函数
    //    Scala的函数是需要依靠某一个变量的
    //    将这个函数给某一个变量进行赋值
    //    此时 calculator就是一个变量,函数类型的变量
    //    (Int, Int) => Int
    val calculator = (a: Int, b: Int) => a + b
    // 2. 使用这个函数
    println(calculator(10, 20))

    // 3. 定义一个Scala的函数
    //    如果左侧的函数变量的类型已经确定,在右侧的实现部分,可以不写参数的类型
    val calculator2: (Int, Int) => Int = (x, y) => x + y
    println(calculator2(10, 20))

    // 4. 进阶1:
    //    如果函数的实现中,参数只用到了一次,在实现部分,可以省略掉参数的声明部分,使用_来替代参数
    // val calculator3: Int => Unit = x => println(x)
    val calculator3: Int => Unit = println(_)
    val calculator4: Int => Int = _ * 2
    println(calculator4(10))


    // 5. 进阶2:
    //    如果函数的实现中,参数只用到了一次,在实现部分,可以省略掉参数的声明部分,使用_来替代参数
    val calculator5: (Int, Int) => Int = _ + _
    println(calculator5(10, 20))
    val calculator6: (Int, Int, Int) => Int = _ + _ + _
    println(calculator6(10, 20, 30))

    // 6. 进阶3:
    //    如果函数的实现中,使用_来表示唯一使用到参数
    //    且这个参数,作为另外的一个函数或者方法的参数出现的
    //    此时,可以省略掉这个下划线和方法或者参数的小括号
    val calculator7: Int => Unit = println(_) //_作为println的参数
    val calculator8: Int => Unit = println

    // 7. 进阶4:
    val calculator9: (Int, Int) => Int = calculateMethod
    println(calculator9(10, 20))

    // 8. 进阶5:
    //    高阶函数,将一个参数或者返回值设置为其他的函数,就是一个高阶函数
    //
    // calculate(_ + _, 10, 20)
    // calculate(calculator5, 100, 200)
    // calculate(calculateMethod, 100, 200)

    // 9. 进阶6:
    // val cal: ((Int, Int)=>Int, Int, Int) => Unit = (calculator, x, y) => println(calculator(x, y))
    val cal: ((Int, Int) => Int, Int, Int) => Int = _ (_, _)
    cal(_ + _, 100, 200)

    // 10. 方法转函数, 直接在后面添加一个空格下划线即可
    val calculator10 = calculateMethod _


  }


  def calculate(calculator: (Int, Int) => Int, x: Int, y: Int): Unit = {
    // calculator: 是一个函数类型的变量,提供了对两个数字进行运算的逻辑
    // x
    // y
    println(calculator(x, y))
  }


  def calculateMethod(x: Int, y: Int): Int = x + y
}

方法:

/**
 * 1. 在定义方法的时候,方法的返回值类型可以不写,可以由实际返回的值进行推导。[不推荐]
 *    但是,有一个例外情况:当递归调用方法的时候,此时这个方法的返回值类型必须明确。
 *
 * 2. 如果方法体中的逻辑很简单,只有一行代码,此时大括号是可以省略不写的。而且,这种省略不写,是推荐的!
 *
 * 3. 如果一个方法是无参数的,在调用的时候可以不写小括号。[不推荐]
 *
 * 4. 如果一个方法是无参数的,在定义的时候可以省略小括号不写,此时在调用的时候,也不能写小括号。[不推荐]
 */
object Method {
  def main(args: Array[String]): Unit = {
    // 调用方法
    myFirstMethod()
    println(calculate(10, 20))
  }

  // 定义我的第一个方法
  def myFirstMethod(): Unit = println("这是我的第一个scala方法")

  def calculate(a: Int, b: Int): Int = a + b
  //重载
  def calculate(a: Int, b: Int, c: Int): Int = a + b + c


  // 如果在定义方法的时候,可以不写等号
  // 如果不写等号,此时不会通过右侧方法体的结果,来自动的推导方法的返回值类型,只适合没有返回值的方法
  def myTestMethod() {
    val a = 10
    val b = 20
     a + b
  }
}
object Method2 {
  def main(args: Array[String]): Unit = {

    println(calculate(10, 20))
    println(calculate(10, 20, 30))

    //
    println(calculate2(5, 10))

    // 调用方法时,传参的时候,可以使用带名参数
    println(calculate2(y = 10))
    println(calculate2(y = 5, z = 10, x = 20))

  }

  // 在定义方法的时候,scala允许某些参数是有默认值的
  // 有默认值的参数,在调用的时候,可以不进行值的设置
  def calculate(x: Int, y: Int, z: Int = 10): Int = {
    println(s"x = $x, y = $y, z = $z")
    x + y + z
  }

  // 有默认值的参数,在进行方法的调用的时候,默认传递的值其实也是要按照顺序进行赋值的
  def calculate2(x: Int = 10, y: Int, z: Int = 30): Int = {

    println(s"x = $x, y = $y, z = $z")
    x + y + z
  }
}
object Method3 {
  def main(args: Array[String]): Unit = {
    println(getSum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

    // 拓展:
    // 在Java中,变长参数可以直接传递一个数组值。但是在Scala中是不允许的
    val array = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    getSum(array:_*)// 展开数组得到每一个元素
  }

  def getSum(numbers: Int*): Int = {
    // 在scala中,变长参数的类型,也是数组类型的
    var sum = 0
    for (n <- numbers) {
      sum += n
    }
    sum
  }

  //递归
  def getFebonacci(index: Int): Int = {
    if (index == 1 || index == 2) {
      return 1 //写return因为此处不是整个结构的最后一句话
    }
    getFebonacci(index - 1) + getFebonacci(index - 2)
  }
}

 

方法转函数:

scala> def m1(x:Int,y:Int) = x + y
m1: (x: Int, y: Int)Int
scala> val f1=m1 _		//方式一:方法被转化成函数
f1: (Int, Int) => Int = <function2>
scala> val f1=m1(_,_)	//方式二:方法被转化成函数
f1: (Int, Int) => Int = <function2>
scala> val f1=m1			//不允许将方法直接赋值给变量,方法不是值,而函数与其他数据类型一样
<console>:12: error: missing argument list for method m1
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `m1 _` or `m1(_,_)` instead of `m1`.
       val f1=m1
              ^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值