scala函数
Scala函数定义
函数是Scala的核心
定义:
def 函数名([参数列表]):[返回值]={
函数图
return[表达式]
}
一、参数传递
传值调用(call-by-value)
传值调用时,参数只在调用时计算一次,后续重复使用计算的结果
传名调用(call-by-name)
传名调用时,参数在调用时不会计算,只有真正用到参数时才计算
* */
def squre(x: Int): Int = {
x * x
}
/*
例:定义一个没有返回值的函数,实现输入一个整数,打印金字塔。
例如输入10,打印如下:等边三角形
- */
for(i<- 1 to 9){
for(j<- 8-i to 0 by -1){
print(" ")
}
for(j<- 1 to 2*i-1){
print("*")
}
println()
}
例:打印出空的倒三角形
* */
// for (n <- 1 to 9) {
// if (n == 1) {
// for (m <- 1 to 9) {
// print("*")
// }
// }else {
//
// for (n <- 2 to n) {
// print(" ")
// }
// print("*")
//
// for (k <- 7-n to 0 by -1) {
// print(" ")
// }
// if(n<9){
// print("*")
// }
// }
// println()
// }
二、参数命名:
通常情况下,传入参数与函数定义的参数列表一一对应
命名参数允许使用任意顺序传入参数
def printName(name: String, gender: String): Unit = {
print("my name is:" + name + ",gender is:" + gender)
}
printName(gender = "nv", name = "yyy")
三、参数缺省值
Scala函数允许指定参数的缺省值,从而允许在调用函数时不指明该参数
def printName2(first: String = "John", last: String = "Smith") = {
println(first + " " + last)
}
//Prints "John Smith"
printName2()
四、匿名函数
指不含函数名称的函数
匿名函数定义:(参数列表)=>{函数体}
“=>”左边为参数列表
“=>”右边为函数体
如果函数体包括多条语句,应使用“{}”包含
* */
// val y = (x: Int) => x * x
// println(y(2))
// val y2 = () => {
// System.getProperty("user.dir")
// }
// print(y2())
//
//定义一个截取字符串首字母的函数字面量initial
val y3 = (x: String) => x(0)
println(y3("ysm"))
//定义一个去除字符串首尾空格的函数字面量trim
val y4 = (x: String) => for (i <- 1 to x.length - 2) {
println(x(i))
}
y4("you are beautiful")
println("===========================")
五、高阶函数
高阶函数可以将其他函数作为参数或者使用函数作为输出结果
常用高阶函数
map、foreach、 filter 、fold、foldLeft、foldRight、 reduce、 zip、 flatten、 flatMap
* */
//函数作为参数:
def doSquare(f: Int => Int, name: String): String = {
f(2) + name
}
println(doSquare(a => a * a, "ysm"))
println("===========================")
//函数作为返回值:
// def doSquares():Int=>Int={
// (x:Int) => x*x
// }
// doSquares()(2)
//
// def values(f:(Int)=>Int,name:String,low:Int,hight:Int)={
// for(i <- low to hight){
// println((low, f(i)))
// }
// }
// values(x=>x*x,"ysm",-5,5)
六、嵌套函数
Scala函数内可以定义函数,函数内的函数也称局部函数或者内嵌函数
// 使用函数嵌套实现阶乘运算
def add(i: Int): Int = {
if (i < 1) 1 else
i * add(i - 1)
}
println(add(9))
//编写Scala函数实现斐波纳契数列
def add2(i: Int): Int = {
if (i <= 2) 1 else add2(i - 1) + add2(i - 2)
}
println(add2(6))
七、柯里化(Currying)
方法可以定义多个参数列表,当使用较少的参数列表调用多参数列表的方法时,
会产生一个新的函数,该函数接收剩余的参数列表作为其参数。这被称为柯里化
* */
def curry(name: String)(gender: String)(age: Int) = {
name + gender + age
}
//新函数接收剩余的参数列表作为其参数
println(curry("yyy")("girl")(23))
println("===========================")
八、隐式参数
方法可以具有隐式参数列表,由参数列表开头的implicit 关键字标记
implict只能修改最尾部的参数列表,应用于其全部参数
Scala可自动传递正确类型的隐式值
通常与柯里化函数结合使用
* */
// 调用方法的时候优先级比较, 传参 > 隐式 > 默认(隐式函数定义在另一个包的类中,通过导包传入)
implicit var n1: Int = 10
implicit var s1: String = "yyy"
def f2(num: Int)(implicit num2: Int): Int = {
num + num2
}
def f3(name: String)(implicit name2: String): String = {
name + name2
}
println(f2(20)(40))
println(f3("sss"))
println("===========================")
九、隐式函数 – 数据类型转换
隐式函数也称隐式转换,使用implicit修饰的函数
implicit def double2Int(x: Double): Int = x.toInt
val i: Int = 3.5
val j: Double = 4.5
println(i)
println(j)
implicit def boolean2Int(x: Boolean): Int = if (x) 1 else 2
println(1 + true)
println("===========================")
十、隐式类
```scala
implicit class Test2Others(demo: Test) {
def sum(a: Int, b: Int): Int = {
println("a value:" + a)
println("b value:" + b)
a + b
}
def ji(a: Int, b: Int): Int = {
a * b
}
}
val test = new Test
test.sum(2, 3)
}
class Test() {
}
}
十一、总结
函数中嵌套定义函数<=>外层函数返回值为内层函数输入输出类型
=> 初步:外层def function1(参数名:参数返回值类型):(内层函数传入参数数据类型:内层函数返回值类型) = { def function2(xxx) = { } }
例:
def funTest2():(String,String)=>String = {
def funDemo(a:String,b:String):String={
a+b
}
funDemo
}
var result = funTest2()("yyy","sss")
println(result)
=> 进阶:可以将内层函数写成 匿名函数 的形式(更加简洁)
例:
def funTest3(num:Int):(Int,Int)=>Int = {
if (num % 2 == 0) (a, b) => a + b else (a, b) => a - b
}
println(funTest3(3)(4,5))
=> 进一步:可以用柯里化实现
例:
def funTest5(num:Int)(a:Int,b:Int):Int = {
if (num % 2 == 0) {
a+b
}
else {
a-b
}
}
println("函数5:"+funTest5(10)(4, 5))
十二、练习:实现一个和while功能相同的函数
方法一:匿名函数
def myWhile(condition: => Boolean): (=> Any) => Any = {
op => {
if (condition) {
op
myWhile(condition)(op)
}
}
}
var n = 10
myWhile(n > 0) {
println(n)
n -= 1
}
println("********************************")
方法二:柯里化
def myWhile2(condition: =>Boolean)(op: =>Any):Any ={
if(condition){
op
myWhile2(condition)(op)
}
}
//闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
//闭包通常来讲可以简单的认为是可以访问一个函数里面局部变量的另外一个函数。
var m = 10
myWhile(m > 0) {
println(m)
m -= 1
}
}