wordpress 企业建站,宁波网站seo报价,建设企业网站电话,培训信息1. 函数 1.1 函数与方法 Scala 中函数与方法的区别非常小#xff0c;如果函数作为某个对象的成员#xff0c;这样的函数被称为方法#xff0c;否则就是一个正常的函数。 // 定义方法
def multi1(x:Int) {x * x}
// 定义函数
val multi2 (x: Int) {x * x}println(mult… 1. 函数 1.1 函数与方法 Scala 中函数与方法的区别非常小如果函数作为某个对象的成员这样的函数被称为方法否则就是一个正常的函数。 // 定义方法
def multi1(x:Int) {x * x}
// 定义函数
val multi2 (x: Int) {x * x}println(multi1(3)) //输出 9
println(multi2(3)) //输出 9 也可以使用 def 定义函数 def multi3 (x: Int) {x * x}
println(multi3(3)) //输出 9 multi2 和 multi3 本质上没有区别这是因为函数是一等公民val multi2 (x: Int) {x * x} 这个语句相当于是使用 def 预先定义了函数之后赋值给变量 multi2。 1.2 函数类型 上面我们说过 multi2 和 multi3 本质上是一样的那么作为函数它们是什么类型的两者的类型实际上都是 Int Int前面一个 Int 代表输入参数类型后面一个 Int 代表返回值类型。 scala val multi2 (x: Int) {x * x}
multi2: Int Int $$Lambda$1092/5943632151dd1a777scala def multi3 (x: Int) {x * x}
multi3: Int Int// 如果有多个参数则类型为参数类型参数类型 ...返回值类型
scala val multi4 (x: Int,name: String) {name x * x }
multi4: (Int, String) String $$Lambda$1093/10397327472eb4fe71.3 一等公民匿名函数 在 Scala 中函数是一等公民这意味着不仅可以定义函数并调用它们还可以将它们作为值进行传递 import scala.math.ceil
object ScalaApp extends App {// 将函数 ceil 赋值给变量 fun,使用下划线 (_) 指明是 ceil 函数但不传递参数val fun ceil _println(fun(2.3456)) //输出 3.0} 在 Scala 中你不必给每一个函数都命名如 (x: Int) 3 * x 就是一个匿名函数 object ScalaApp extends App {// 1.匿名函数(x: Int) 3 * x// 2.具名函数val fun (x: Int) 3 * x// 3.直接使用匿名函数val array01 Array(1, 2, 3).map((x: Int) 3 * x) // 4.使用占位符简写匿名函数val array02 Array(1, 2, 3).map(_ * 3)// 5.使用具名函数val array03 Array(1, 2, 3).map(fun)}1.4 特殊的函数表达式 1.4.1 可变长度参数列表 在 Java 中如果你想要传递可变长度的参数需要使用 String ...args 这种形式Scala 中等效的表达为 args: String*。 object ScalaApp extends App {def echo(args: String*): Unit {for (arg - args) println(arg)}echo(spark,hadoop,flink)
}
// 输出
spark
hadoop
flink1.4.2 传递具名参数 向函数传递参数时候可以指定具体的参数名。 object ScalaApp extends App { def detail(name: String, age: Int): Unit println(name : age)// 1.按照参数定义的顺序传入detail(heibaiying, 12)// 2.传递参数的时候指定具体的名称,则不必遵循定义的顺序detail(age 12, name heibaiying)}1.4.3 默认值参数 在定义函数时可以为参数指定默认值。 object ScalaApp extends App {def detail(name: String, age: Int 88): Unit println(name : age)// 如果没有传递 age 值,则使用默认值detail(heibaiying)detail(heibaiying, 12)
}2. 闭包 2.1 闭包的定义 var more 10
// addMore 一个闭包函数:因为其捕获了自由变量 more 从而闭合了该函数字面量
val addMore (x: Int) x more 如上函数 addMore 中有两个变量 x 和 more: x: 是一个绑定变量 (bound variable)因为其是该函数的入参在函数的上下文中有明确的定义 more: 是一个自由变量 (free variable)因为函数字面量本生并没有给 more 赋予任何含义。 按照定义在创建函数时如果需要捕获自由变量那么包含指向被捕获变量的引用的函数就被称为闭包函数。 2.2 修改自由变量 这里需要注意的是闭包捕获的是变量本身即是对变量本身的引用这意味着 闭包外部对自由变量的修改在闭包内部是可见的 闭包内部对自由变量的修改在闭包外部也是可见的。 // 声明 more 变量
scala var more 10
more: Int 10// more 变量必须已经被声明否则下面的语句会报错
scala val addMore (x: Int) {x more}
addMore: Int Int $$Lambda$1076/1844473121876c4f0scala addMore(10)
res7: Int 20// 注意这里是给 more 变量赋值而不是重新声明 more 变量
scala more1000
more: Int 1000scala addMore(10)
res8: Int 1010 2.3 自由变量多副本 自由变量可能随着程序的改变而改变从而产生多个副本但是闭包永远指向创建时候有效的那个变量副本。 // 第一次声明 more 变量
scala var more 10
more: Int 10// 创建闭包函数
scala val addMore10 (x: Int) {x more}
addMore10: Int Int $$Lambda$1077/11442516181bdaa13c// 调用闭包函数
scala addMore10(9)
res9: Int 19// 重新声明 more 变量
scala var more 100
more: Int 100// 创建新的闭包函数
scala val addMore100 (x: Int) {x more}
addMore100: Int Int $$Lambda$1078/6269558494d0be2ac// 引用的是重新声明 more 变量
scala addMore100(9)
res10: Int 109// 引用的还是第一次声明的 more 变量
scala addMore10(9)
res11: Int 19// 对于全局而言 more 还是 100
scala more
res12: Int 100 从上面的示例可以看出重新声明 more 后全局的 more 的值是 100但是对于闭包函数 addMore10 还是引用的是值为 10 的 more这是由虚拟机来实现的虚拟机会保证 more 变量在重新声明后原来的被捕获的变量副本继续在堆上保持存活。 3. 高阶函数 3.1 使用函数作为参数 定义函数时候支持传入函数作为参数此时新定义的函数被称为高阶函数。 object ScalaApp extends App {// 1.定义函数def square (x: Int) {x * x}// 2.定义高阶函数: 第一个参数是类型为 Int Int 的函数def multi(fun: Int Int, x: Int) {fun(x) * 100}// 3.传入具名函数println(multi(square, 5)) // 输出 2500// 4.传入匿名函数println(multi(_ * 100, 5)) // 输出 50000}3.2 函数柯里化 我们上面定义的函数都只支持一个参数列表而柯里化函数则支持多个参数列表。柯里化指的是将原来接受两个参数的函数变成接受一个参数的函数的过程。新的函数以原有第二个参数作为参数。 object ScalaApp extends App {// 定义柯里化函数def curriedSum(x: Int)(y: Int) x yprintln(curriedSum(2)(3)) //输出 5
}这里当你调用 curriedSum 时候实际上是连着做了两次传统的函数调用实际执行的柯里化过程如下 第一次调用接收一个名为 x 的 Int 型参数返回一个用于第二次调用的函数假设 x 为 2则返回函数 2y 返回的函数接收参数 y并计算并返回值 23 的值。 想要获得柯里化的中间返回的函数其实也比较简单 object ScalaApp extends App {// 定义柯里化函数def curriedSum(x: Int)(y: Int) x yprintln(curriedSum(2)(3)) //输出 5// 获取传入值为 10 返回的中间函数 10 yval plus: Int Int curriedSum(10)_println(plus(3)) //输出值 13
}柯里化支持多个参数列表多个参数按照从左到右的顺序依次执行柯里化操作 object ScalaApp extends App {// 定义柯里化函数def curriedSum(x: Int)(y: Int)(z: String) x y zprintln(curriedSum(2)(3)(name)) // 输出 5name
}