1、Block块语句
object Demo04Block {
def main(args: Array[String]): Unit = {
/*
{} 块语句
最后一个值或表达式作为块语句的返回值
*/
val age = 20
val info = if (age > 1) {
println("块语句!!!")
"hhhhhhh"
1
}
println(info)
}
}
2、yield 礼让,构建新集合
将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字
object Demo01Yield {
def main(args: Array[String]): Unit = {
for (i <- 1 to 10){
print(i)
}
println()
println("************")
//yield 礼让 可以构建一个新的集合
val value = for (i <- 1 to 10) yield i * 10
println(value) // Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
// ArrayBuffer是可变的数组
val buffer = (for (i <- 1 to 10) yield i * 10).toBuffer
println(buffer) // ArrayBuffer(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
}
}
3、scala函数式编程,函数与方法
object Demo03Function {
def main(args: Array[String]): Unit = {
/*
方法也称为函数
函数没有 重写重载 的概念
函数的几种写法
*/
def sum(a: Int, b: Int): Int = {
a + b
}
// 函数无法重载
// def sum(): Unit ={
//
// }
println(sum(5, 3))
/* 无参无返回值 */
def f1() = {
}
/* 有一个参数,无返回值 */
def f2(a: Int) = {
}
/* 无参无返回值,写参数的小扩号和返回类型都可以省略不写 */
def f3 = {
println("简化版!!!")
}
/* 两个参数,有返回值 */
def f4(name: String,age: Int): String = {
s"$name $age"
}
println(f4("zhangsan",18))
}
}
class Test {
/*
类中的函数称为方法
方法可以 重写 重载
*/
def sum(a: Int, b: Int): Int = {
a + b
}
def sum() = {
}
}
4、函数参数分类及使用
(1)可变参数
(2)如果参数列表中存在多个参数,那么可变参数一般放置在最后
(3)参数默认值
(4)带名参数
object Demo05FuncParam {
def main(args: Array[String]): Unit = {
/*
函数参数的使用:
默认参数 传名参数 可变参数
*/
/* 调用下方的函数 */
println(f1("zhangsan",18,"八达岭"))
println(f1("函数的默认参数",20))
println(f2("lisi",18,"宝泉"))
println(f2(age = 22,name = "函数的传名参数",addr = "方特"))
f3("秦始皇","赵匡胤","李世民","朱元璋")
println()
f3("虞姬","甄姬","蔡文姬")
println()
// 打印十遍字符串内容
println("a"*10)
}
/* 创建函数的时候参数指定默认值,当调用的时候可以传值,如果不传使用默认的值 */
def f1(name: String,age: Int,addr: String = "八大里"): String = {
s"$name $age $addr"
}
/* 带名参数,传递参数的时候可以不按照参数的顺序,但是必须要带着参数的名称 */
def f2(name: String,age: Int,addr: String): String = {
s"$name $age $addr"
}
/* 可变参数,变长参数 参数的个数不确定 */
def f3(name: String*) = {
print("函数的可变参数: ")
for (a <- name){
print(a + " ")
}
}
}
object Demo08CallByName_Value {
def main(args: Array[String]): Unit = {
/* 传值函数,传入的是函数的返回值 */
sum(10,func01(100))
println("-------------")
/* 传名函数,传入的是函数名称,当被调用的时候出才执行 */
sum1(10,func01)
}
def func01(num:Int): Int ={
println("Num: "+num)
num
}
//call by value: 传值函数,传入的是函数的返回值
def sum(a:Int,b:Int): Unit ={
println("开始计算求和")
println(a+b)
}
//call by name: 传名函数,传入的是函数名称,当被调用的时候出才执行
def sum1(a:Int,f:(Int)=>Int){
val b = 100
println("开始计算求和")
println(a+f(b))
}
}
5、函数至简原则
(1)return可以省略,Scala会使用函数体的最后一行代码作为返回值
(2)返回值类型如果能够推断出来,那么可以省略
(3)如果函数体只有一行代码,可以省略花括号
(4)如果函数无参,则可以省略小括号。若定义函数时省略小括号,则调用该函数时,也需省略小括号;若定时函数时未省略,则调用时,可省可不省。
(5)如果函数明确声明Unit,那么即使函数体中使用return关键字也不起作用
(6)Scala如果想要自动推断无返回值,可以省略等号
(7)如果不关心名称,只关系逻辑处理,那么函数名(def)可以省略
(8)如果函数明确使用return关键字,那么函数返回就不能使用自行推断了,需要声明返回值类型
6、高阶函数
定义:参数为函数的函数称为高阶函数
object Demo07Func {
def main(args: Array[String]): Unit = {
/*
把函数当做参数来传递
*/
def sum1(a: Int,b: Int): Int = {
return a + b
}
def sum2(a: Int,b: Int): Int = {
return a * b
}
/* 第三个参数是函数 */
def sum3(a: Int,b: Int,aaa:(Int,Int) => Int): Int = {
return aaa(a,b)
}
println(sum3(3,3,sum1)) // 6
println(sum3(3,3,sum2)) // 9
}
}
7、匿名函数
没有名字的函数就是匿名函数,可以直接通过函数字面量(表达式)来设置匿名函数,函数字面量定义格式如下
object Demo08Func {
def main(args: Array[String]): Unit = {
/*
匿名函数
val 函数名称 =(参数列表) => {函数体}
var f1 = (a: Int,b: Int) => { a + b }
*/
var f1 = (a: Int,b: Int) => {
a + b
}
println("加了变量接收的匿名函数: " + f1(1,1))
/* 第三个参数是函数 */
def f2(a: Int,b: Int,aaa:(Int,Int) => Int): Int = {
aaa(a,b)
}
/* 调用,第三个参数直接输入一个匿名函数 */
println(f2(3,3,f1)) // 6
println(f2(3,3,(a: Int,b: Int) => a * b)) // 9
println("************")
/* 匿名函数的应用场景 */
val array = Array(1, 2, 3, 4, 5, 6)
array.map(i => i * 10).foreach(println(_)) // 10 20 30 40 50 60
println("************")
// _ 代表每一个元素
array.map(_ * 10).foreach(println(_)) // 10 20 30 40 50 60
println("************")
def f3(num: Int): Int = {
num * 10
}
array.map(f3).foreach(println(_)) // 10 20 30 40 50 60
}
}
8、函数闭包
闭包:就是一个函数和与其相关的引用环境(变量)组合的一个整体(实体)
object Demo09ClosePackage {
def main(args: Array[String]): Unit = {
/* 闭包 引入外部变量 */
val num = 10
def sum(a: Int): Int = {
// 引入外部变量 num
a + num
}
println("引入外部变量结果为: " + sum(10)) // 20
}
}
9、函数柯理化
函数柯里化:将一个接收多个参数的函数转化成一个接受一个参数的函数过程,可以简单的理解为一种特殊的参数列表声明方式。
object Demo10Currying {
def main(args: Array[String]): Unit = {
/* 这是两个参数的函数 */
def sum(a: Int,b: Int): Int = {
a + b
}
/*
柯里化:将原来两个参数的函数拆分为以原来第一个参数为参数的函数
返回的新的函数再以原来第二个参数为参数的函数
*/
def sum1(a: Int)(b: Int): Int = {
a + b
}
def sum2(a: Int)(b: Int)(c: Int): Int = {
a + b + c
}
println(sum(10,20)) // 30
println(sum1(10)(20)) // 30
println(sum2(10)(20)(30)) // 60
}
}
10、递归
一个函数/方法在函数/方法体内又调用了本身,我们称之为递归调用
object Demo11jiecheng {
def main(args: Array[String]): Unit = {
/*
阶乘运用递归思想
所谓递归,直白的说就是自己调用自己
*/
def test(num: Int): Int = {
if (num == 1){
num
}else{
num * test(num - 1)
}
}
println(test(5)) // 120
}
}
11、lazy 惰性求值,懒加载
当函数返回值被声明为lazy时,函数的执行将被推迟,直到我们首次对此取值,调用,该函数才会执行。这种函数我们称之为惰性函数。
import scala.io.Source
object Demo12lazy {
def main(args: Array[String]): Unit = {
/*
懒加载
只有被调用的时候才会执行
*/
var age = 20
println(age) // 20
lazy val res = if (age > 18) {
age = 100
s"现在的 age is $age"
}
println("调用前age是: " + age) // 20
/* 此时懒加载被调用了 */
println(res) // 现在的 age is 100
println("调用后的age是: " + age) // 100
/*
懒加载应用场景:
当在创建大的变量,或者执行比较耗时的程序 比如读写数据
*/
val source = Source.fromFile("E:/快捷键.txt")
val lines: Iterator[String] = source.getLines()
for (line <- lines){
println(line)
}
}
}