文章目录
Scala day02
流程控制(While,For)
While循环
- 与if语句不同,while语句没有返回值,即整个while语句的结果是Unit类型()
- 任何的语法结构都有值
赋值语句的值也是Unit
package com.gc.scala.day02
/**
* author guochao
* date 2021/4/22 9:51
*/
object WhileDemo {
def main(args: Array[String]): Unit = {
var i: Int = 0
val r: Unit = while (i < 10) {
println(i)
i += 1
i
}
println(r)
}
}
For循环
范围数据循环方式1(to)
基本语法
for(i <- 1 to 3){
print(i + " ")
}
println()
(1)i 表示循环的变量,<- 规定to
(2)i 将会从 1-3 循环,前后闭合,[1,3]
package com.gc.scala.day02
/**
* author guochao
* date 2021/4/22 9:56
*/
object For1 {
def main(args: Array[String]): Unit = {
/*val a:String ="abc"
for (c <-a){//遍历容器
println(c)
}*/
//使用for输出1-100
for (i <- 1 to 100) {
println(i)
}
for (i <- 1 to 100 by 2) {
println(i)
}
for (i <- 1 to 100 reverse) { //逆转,100到1
println(i)
}
}
}
范围数据循环方式2(until)
基本语法
for(i <- 1 until 3) {
print(i + " ")
}
println()
(1)这种方式和前面的区别在于i是从1到3-1,[1,3)
(2)即前闭合后开
循环守卫
基本语法
for(i <- 1 to 3 if i != 2) {
print(i + " ")
}
println()
说明:
(1)循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为true则进入循环体内部,为false则跳过,类似于continue。
(2)上面的代码等价
for (i <- 1 to 3){
if (i != 2) {
print(i + "")
}
}
package com.gc.scala.day02
/**
* author guochao
* date 2021/4/24 15:59
*/
object For2 {
def main(args: Array[String]): Unit = {
//输出1-100的奇数
//循环守卫
for (i <- 1 to 100 if i % 2 == 1) {
println(i)
}
for (i <- 1 until 3) { //[1,3)
println(i)
}
for (i <- 1 to 100 if i % 2 == 0; j = i * i if j < 10000; k = j * j) {
println(s"i=$i,j=$j,k=$k")
}
}
}
循环步长
基本语法
for (i <- 1 to 10 by 2) {
println("i=" + i)
}
说明:by表示步长
2)案例实操
需求:输出1到10以内的所有奇数
for (i <- 1 to 10 by 2) {
println("i=" + i)
}
输出结果
i=1
i=3
i=5
i=7
i=9
引入变量
基本语法
for(i <- 1 to 3; j = 4 - i) {
println("i=" + i + " j=" + j)
}
说明:
(1)for推导式一行中有多个表达式时,所以要加;来隔断逻辑
(2)for推导式有一个不成文的约定:当for推导式仅包含单一表达式时使用圆括号,当包含多个表达式时,一般每行一个表达式,并用花括号代替圆括号,如下
for {
i <- 1 to 3
j = 4 - i
} {
println("i=" + i + " j=" + j)
}
2)案例实操
上面的代码等价于
for (i <- 1 to 3) {
var j = 4 - i
println("i=" + i + " j=" + j)
}
循环返回值
- 基本语法
val res = for(i <- 1 to 10) yield i
println(res)
说明:将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字
2. 案例实操
需求:将原数据中所有值乘以2,并把数据返回到一个新的集合中。
object TestFor {
def main(args: Array[String]): Unit = {
var res = for( i <-1 to 10 ) yield {
i * 2
}
println(res)
}
}
输出结果:
Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
package com.gc.scala.day02
/**
* author guochao
* date 2021/4/24 16:19
*/
object For5 {
def main(args: Array[String]): Unit = {
//得到一个序列: 1 4 9 16 .....100*100
val r: IndexedSeq[Int] = for (i <- 1 to 100) yield {
i * i
}
println(r)
// "abcd"=>"AbBbCc"
val s: IndexedSeq[String] = for (c <- "abcd") yield c.toString.toUpperCase + c
println(s.mkString(""))
//更加函数式
println("abcd".map(c => c.toString.toUpperCase + c).mkString(""))
}
}
函数
函数定义
val 函数变量名 :函数类型 = (参数名:参数类型, 参数名:参数类型…) => 函数体
val sum: (Int, Int) => Int = (x: Int, y: Int) => x + y
方法定义
def 方法名(参数名:参数类型, 参数名:参数类型) : [return 返回值类型] ={函数体}
def add(a:Int,b:Int=3,c:Int):Int=a+b+c
函数和方法的区别
- 核心概念
(1)为完成某一功能的程序指令(语句)的集合,称为函数。
(2)类中的函数称之方法。 - 案例实操
(1)Scala语言的语法非常灵活,可以在任何的语法结构中声明任何的语法
(2)函数没有重载和重写的概念;方法可以进行重载和重写
(3)scala中函数可以嵌套定义
object TestFunction {
// (2)方法可以进行重载和重写,程序可以执行
def main(): Unit = {
}
def main(args: Array[String]): Unit = {
// (1)Scala语言的语法非常灵活,可以在任何的语法结构中声明任何的语法
import java.util.Date
new Date()
// (2)函数没有重载和重写的概念,程序报错
def test(): Unit ={
println("无参,无返回值")
}
test()
def test(name:String):Unit={
println()
}
//(3)scala中函数可以嵌套定义
def test2(): Unit ={
def test3(name:String):Unit={
println("函数可以嵌套定义")
}
}
}
}
方法转换成函数(_)
package com.gc.scala.day02
/**
* author guochao
* date 2021/4/24 17:15
*/
object High3 {
def main(args: Array[String]): Unit = {
//把方法转化成函数,没有环境,就必须手动完成
val add1:(Int,Int)=>Int=add _
//这个时候也是把方法转成了函数,是Scala自动完成的
val add2:(Int,Int)=>Int=add
println(add1(10, 20))
println(add2(10, 20))
val r: Int= foo(add _ )
println(r)
// foo1(add1 )
}
def add1():Unit=println("add1....")
def foo1(op:() => Unit):Unit=op()
def foo(op:(Int,Int)=>Int):Int={
op(10,20)
}
def add(a:Int,b:Int):Int=a+b
}
函数声明
- 函数声明
(1)函数1:无参,无返回值
(2)函数2:无参,有返回值
(3)函数3:有参,无返回值
(4)函数4:有参,有返回值
(5)函数5:多参,无返回值 - 案例实操
package com.atguigu.chapter06
object TestFunctionDeclare {
def main(args: Array[String]): Unit = {
// 函数1:无参,无返回值
def test(): Unit ={
println("无参,无返回值")
}
test()
// 函数2:无参,有返回值
def test2():String={
return "无参,有返回值"
}
println(test2())
// 函数3:有参,无返回值
def test3(s:String):Unit={
println(s)
}
test3("jinlian")
// 函数4:有参,有返回值
def test4(s:String):String={
return s+"有参,有返回值"
}
println(test4("hello "))
// 函数5:多参,无返回值
def test5(name:String, age:Int):Unit={
println(s"$name, $age")
}
test5("dalang",40)
}
}
函数参数
- 案例实操
(1)可变参数
(2)如果参数列表中存在多个参数,那么可变参数一般放置在最后
(3)参数默认值
(4)带名参数
object TestFunction {
def main(args: Array[String]): Unit = {
// (1)可变参数
def test( s : String* ): Unit = {
println(s)
}
// 有输入参数:输出 Array
test("Hello", "Scala")
// 无输入参数:输出List()
test()
// (2)如果参数列表中存在多个参数,那么可变参数一般放置在最后
def test2( name : String, s: String* ): Unit = {
println(name + "," + s)
}
/*
可变参数一般放置在最后
def test2( s: String*,name : String ): Unit = {
println(name + "," + s)
}
*/
test2("jinlian", "dalang")
// (3)参数默认值
def test3( name : String, age : Int = 30 ): Unit = {
println(s"$name, $age")
}
// 如果参数传递了值,那么会覆盖默认值
test3("jinlian", 20)
// 如果参数有默认值,在调用的时候,可以省略这个参数
test3("dalang")
def test4( sex : String = "男", name : String ): Unit = {
println(s"$name, $sex")
}
// scala函数中参数传递是,从左到右
// 一般情况下,将有默认值的参数放置在参数列表的后面
// test4("wusong")
//(4)带名参数
test4(name="ximenqing")
}
}
- 位置参数:在Java和Scala中,默认传递函数参数,是按照位置来的
package com.gc.scala.day02
/**
* author guochao
* date 2021/4/24 16:34
*/
object Fun4 {
def main(args: Array[String]): Unit = {
println(add(1, 2, 3))
println(add(10, 20, 3))
println(add(100, 20, 3))
// println(add(100,20)) 位置参数
println(add(10, c = 100))
}
def add(a:Int,b:Int=3,c:Int):Int=a+b+c
// def add(a:Int,b:Int,c:Int=3):Int=a+b+c
}
高阶函数
定义:参数为函数的函数称为高阶函数
object TestFunction {
def main(args: Array[String]): Unit = {
//高阶函数————函数作为参数
def calculator(a: Int, b: Int, operater: (Int, Int) => Int): Int = {
operater(a, b)
}
//函数————求和
def plus(x: Int, y: Int): Int = {
x + y
}
//方法————求积
def multiply(x: Int, y: Int): Int = {
x * y
}
//函数作为参数
println(calculator(2, 3, plus))
println(calculator(2, 3, multiply))
}
}
匿名函数
1.匿名函数:
没有名字的函数,就是匿名函数
用处:
1.作为实参,直接传递给高阶函数
2.直接作为高阶函数的返回值
package com.gc.scala.day02
/**
* author guochao
* date 2021/4/24 17:23
*/
// 快捷键
// 自动格式化:alt+ctrl+l
object High4 {
def main(args: Array[String]): Unit = {
val a:()=>Unit=()=>println("aaaa")
foo(a)
foo(()=>{println("匿名函数")})
}
def foo(f: () => Unit): Unit ={
f()
}
}
/*
* 1.匿名函数:
没有名字的函数,就是匿名函数
用处:
1.作为实参,直接传递给高阶函数
2.直接作为高阶函数的返回值*/
闭包
一个函数,如果访问了外部的局部变量,则这个函数和他访问的局部变量称为一个闭包,
闭包会阻止外部局部变量的销毁,可以把局部变量的使用延伸到函数的外部
package com.gc.scala.day02
/**
* author guochao
* date 2021/4/24 17:45
*/
object Closure {
def main(args: Array[String]): Unit = {
val f:Int=>Int=foo()
val r:Int=f(20)//能够访问到a,是因为闭包的存在
println(r)
}
def foo()={
var a:Int=10
(b:Int)=>a+b
}
}
/*一个函数,如果访问了外部的局部变量,则这个函数和他访问的局部变量称为一个闭包,
闭包会阻止外部局部变量的销毁,可以把局部变量的使用延伸到函数的外部*/