当前位置: 首页 > 工具软件 > Scala.Rx > 使用案例 >

1.Scala基础—数据类型、标准输入、类和对象、分支循环、函数、匿名函数、高阶函数

杨和蔼
2023-12-01

第一章 Scala基础

1.0 前言

Scala安装与Windows环境配置:略
:Scala安装的路径不能包含空格和中文字符
Scala版本:2.12.10
IDEA配置Scala环境:参考IDEA配置Scala环境

注:"=>"符号可以用在匿名函数高阶函数模式匹配中。

1.1 数据类型

数据类型描述:
Byte 8bit的有符号数字,范围在-128 --127
Short 16bit有符号数字,范围在-32768 --32767
Int 32bit有符号数字,范围-2147483648到2147483647
Long 64bit有符号数字32 bit IEEE 754单精度浮点数
Double 64bit IEEE 754双精度浮点数
Char 16bit Unicode字符.范围U+0000到U+FFFFString字符串
Boolean 布尔类型
Unit 表示无值,和其他语言中void等同
Null 空值或者空引用
Nothing 所有其他类型的子类型,表示没有值
Any 所有类型的超类,任何实例都属于Any类型
AnyRef 所有引用类型的超类
AnyVal 所有值类型的超类

1.2 Hello World

/**
 * 一行的结尾可以省略分号。如果一行中有多个语句那么需要使用分号隔开。
 */

object HelloWorld {
 def main(args: Array[String]): Unit = {
   println("Hello World!")
 }
}

1.2 键盘标准输入

编程中可以通过键盘输入语句来接收用户输入的数据。
scala中输入数据只需要导入对应的包。

import scala.io.StdIn

object Test {
	def main(args: Array[String]) : Unit = {
		println("请输入姓名")
		val name = StdIn.readLine()
		println("请输入年龄")│
		val age = StdIn.readInt()
		printf("您输入的姓名是%s, 年龄是%d" , name, age)
	}
}
符号含义
%d十进制数字
%s字符串
%c字符
%e指数浮点数
%f浮点数

1.3 类和对象、伴生类和伴生对象

/**
 * var修饰变量,val修饰常量
 * scala中没有static关键字,就不存在static修饰的静态属性或者静态方法或者静态代码块
 * scala通过object来实现static的类似功能,在object中的所有属性和函数都是静态的
 * object中不能传递参数
 * 在同一个scala文件中,如果class和lobject名字一样,则称他们为伴生类和伴生对象,可以直接互相访问私有变量
 */

object HelloWorld {
  def main(args: Array[String]): Unit = {
    var stu = new Student("谢清照", 21)
    var stu2 = new Student("王页川", 20, "北京工业大学")
    println("name:" + stu.name + " age:" + stu.age + " shcool:" + stu.school)
    println("name:" + stu2.name + " age:" + stu2.age + " shcool:" + stu2.school)
  }
}

/**
 * 类的声明
 * 默认实现 getter 和 setter 方法
 * 参数格式:(变量名:类型)
 * 注:定义类时也可以不设置参数
 */
class Student(sname:String, sage: Int) {
  val name = sname
  val age = sage
  var school = "北京师范大学"

  // 重写构造器
  def this(sname:String, sage: Int, sschool: String) {
    this(sname, sage)
    school = sschool
  }
}

1.4 分支循环

1.4.1 if else

scala中有多分支这样三种顺序控制结构。

/**
 * StdIn键盘标准输入scala.io包下的
 */

def main(args : Array[String]): Unit = {
	printin("请输入年龄:")
	val age = StdIn.readInt()
	if(age >= 18 && age < 180) {
		println("成年")
	} else if(age > 0 && age < 18) {
		println(""未成年")
	} else {
		println("???")
	}
}

1.4.2 for,while,do…while

  • (1) to和until 的用法(不带步长,带步长区别)
/**
 * to和until
 * 例:
 * 1 to 1日返回 1到10 的Range数组,包含10
 * 1 until 10返回 1到10 Range数组,不包含10
 */
println(1 to 10 ) //打印1,2,3,4,5,6,7,8,9,10
println(1.to(10)) //与上面等价,打印1,2,3,4,5,6,7,8,9,18
println(1 to (18, 2)) //步长为2,从1开始打印,1,3,5,7,9
println(1.to(10, 2))
println(1 until 10) //不包含最后一个数,打印1,2,3,4,5,6,7,8,9
println(1.unti1(10)) //与上面等价

println(1 until(10, 3)) //步长为2,从1开始打印,打印1,4,7
  • (2) 创建for循环
/**
 * for 循环
 */
for(i <- 1 to 10) {
	println(i)
}

for(i <- 1 to 10; if i > 5 && if i%2 ==0) {
	println(i)
}

for(i <- 1 to 10) {
	if(if i > 5 && if i%2 ==0) 
		println(i)
}

注:scala中不能使用count++ , count–只能使用count = count+1 , count += 1

  • (3) while循环(两种方式),while() {}, do{} while()
// 将for中的符合条件的元素通过 yield 关键字返回成一个集合
val list= for(i <- 1 to 10; if(i >5)) yield i
// val list= for(i <- 1 to 10; if(i >5)) yield i % 2
for(w <- list){
	println(w)
}
/**
 * while 循环
 */
var index = 0
while(index < 180){
	println("第" + index + "次while循环")
	index += 1
)
index = 8
do{
	index +=1
	println("第" + index + "次do while循环")
} while(index <100)

1.5 函数

1.5.1 Scala函数的定义

/**
 * 函数的定义: 
 * scala自动将函数的最后一行最为返回值
 * {}只有一行语句时可以省略
 * 函数可以省略返回类型(隐式推断和显示判断)
 */
object HelloWorld {
	def main(args: Array[String]): Unit = {
  		def getMax(a:Int, b:Int) {
			if(a > b)
				a
			else
				b
		} 

		val result = getMax(1, 10)
		println(result)

		// 函数定义时没有括号,调用时也不需要括号
		test
  	}

    // 若函数没有参数,则括号可以省略
	def test: Unit = {
		println("Hello...")
	}
}

1.5.2 包含参数默认值的函数

  • 默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值。
  • 如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称。
/**
 * 包含黑默认参数值的函数
 * 注意:
 * 1.默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值
 * 2.如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称亲。
 */
// 花括号前的 "=" 似乎加不加都可以
def fun3(a:Int = 18, b:Int) = {
	println(a+b)
}
fun3(b=2)

1.5.3 可变参数个数的函数

可变参数理解为不定长数组,传递多个参数时用逗号分开,处理起来按照数组方式。

/**
 * 可变参数个数的函数
 * 注意:多个参数逗号分开
 */
def fun4(elements : Int*) = {
	var sum = 8;
	for(elem <- elements) {
		sum += elem
	}
	sum
}
println(fun4(1,2,3,4))

1.6 匿名函数(=>)

—共有如下三种:

1.有参匿名函数
2.无参匿名函数
3.有返回值的匿名函数

  • 可以将匿名函数返回给val定义的值。
  • 匿名函数不能显式声明函数的返回类型
/**
 * 匿名函数
 * 1.有参数匿名函数
 * 2.无参数匿名函数
 * 3.有返回值的匿名函数
 * 注意:
 * 可以将匿名函数返回给定义的一个变量
 */

//有参数匿名函数
val value1 = (a : Int) => {
	println(a)
}
value1(1)

//无参数匿名函数
val value2 = () => {
	println("我爱中国")
}
value2()

// 有返回值的匿名函数
val value3 = (a:Int, b:Int) => {
	a+b
}
println(value3(4, 4))

1.7 嵌套函数(了解即可)

/**
 ★ 嵌套函数, 记得调用内部函数
 * 例如:嵌套函数求5的阶乘
 */
def fun5(num : Int) = {
	def fun6(a:Int, b:Int) : Int = {
		if(a == 1) {
			b
		} else {
			fun6(a-1,a*b)
		}
	}
	fun6(num, 1)
	}
}
println(fun5(5))

1.8 偏应用函数(了解即可)

偏应用函数是一种表达式,不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。如下场景中,一个参数是完全相同,另一个参数不同,在这样一个情况之下,我们可以使用偏应用函数来进行优化。

/**
 ★ 偏应用函数
 */
def log(date:Date, s:String) = {
	println("date is " + date +", log is " + s)
}

val date = new Date()
log(date, "log1")
log(date, "log2")
log(date, "log3")

// 想要调用log,以上变化的是第二个参数,可以用偏应用函数处理
// 绑定了第一个date参数,第二个参数使用下划线替换缺失的参数列表
val logWithDate = log(date, _:String)
logWithDate("log11")
logWithDate("log22")
logWithDate("log33")

1.9 高阶函数(重要)

函数的参数是函数,或者函数的返回类型是函数,或者函数的参数和函数的返回类型是函数的函数。

  • 函数的参数是函数
  • 函数的返回是函数
  • 函数的参数和函数的返回是函数
/**
 * 高阶函数
 ★ 函数的'参数'是函数  
 * 函数的'返回'是函数  
 * 函数的'参数'和'返回'都是函数
 */

// 函数的参数是函数
def fun6(f:(Int,Int) => Int, a:Int) : Unit= {
	val result = f(2, 5)
	println(a * result)
}
def f7(v1:Int, v2:Int) : Int = {
	v1+v2
}
println(fun6(f7, 1))

// 函数的返回是函数
// 1,2,3,4相加
def fun8(a:Int, b:Int) : (Int, Int) => Int = {
	def fun9(v1:Int, v2:Int) : Int = {
		v1+v2+a+b
	}
	fun9
}
val fun10: (Int, Int) => Int = fun8(1, 2)
// println(fun10(3, 4))
println(fun8(1, 2)(3, 4))

//两者结合
def f12(f13:(Int,Int)=>Int) : (Int,Int) => Int = {
	f13
}
println(f12((a:Int,b:Int) => a+b)(20,30))
// println(f12(_+_)(20,30))
// 上面被注释掉的写法尽量不要写,下划线多了很容易看不明白

1.10 柯里化函数

柯里化–颗粒化,将参数变成颗粒散落简而言之就是将参数拆拆拆。函数柯里化所做的事情:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。如果写成公式文字就是这样。

fn(a, b, c, d)=>fn(a)(b)(c)(d);
fn(a, b, c, d)=>fn(a, b)(c)(d);
fn(a, b, c, d)=>fn(a)(b, c, d);

可以理解为高阶函数的简化。和我们文档中上面的函数的返回类是函数的例子进行比较。

// def fun7(a :Int, b: Int, c :Int , d : Int) ={
//     a+b+c+d
// }
// println(fun7(1,2,3,4))

/**
 * 柯里化函数
 */
def fun7(a:Int, b:Int)(c:Int, d:Int) = {
	a+b+c+d
}
println(fun7(1,2)(3,4)) // 执行完1+2得出3之后继续往下作为函数执行3+3+4最终求出结果10

声明:本文是学习时记录的笔记,如有侵权请告知删除!
原视频地址:https://www.bilibili.com/video/BV1qf4y1h7rX

 类似资料: