Scala安装与Windows环境配置:略
注
:Scala安装的路径不能包含空格和中文字符
Scala版本:2.12.10
IDEA配置Scala环境:参考IDEA配置Scala环境
注:"=>
"符号可以用在匿名函数
、高阶函数
、模式匹配
中。
数据类型描述:
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
所有值类型的超类
/**
* 一行的结尾可以省略分号。如果一行中有多个语句那么需要使用分号隔开。
*/
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello World!")
}
}
编程中可以通过键盘输入语句来接收用户输入的数据。
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 | 浮点数 |
/**
* 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
}
}
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("???")
}
}
/**
* 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
/**
* 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
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)
/**
* 函数的定义:
* 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.默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值
* 2.如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称亲。
*/
// 花括号前的 "=" 似乎加不加都可以
def fun3(a:Int = 18, b:Int) = {
println(a+b)
}
fun3(b=2)
可变参数理解为不定长数组,传递多个参数时用逗号分开,处理起来按照数组方式。
/**
* 可变参数个数的函数
* 注意:多个参数逗号分开
*/
def fun4(elements : Int*) = {
var sum = 8;
for(elem <- elements) {
sum += elem
}
sum
}
println(fun4(1,2,3,4))
=>
)—共有如下三种:
1.有参匿名函数
2.无参匿名函数
3.有返回值的匿名函数
/**
* 匿名函数
* 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))
/**
★ 嵌套函数, 记得调用内部函数
* 例如:嵌套函数求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))
偏应用函数是一种表达式,不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。如下场景中,一个参数是完全相同,另一个参数不同,在这样一个情况之下,我们可以使用偏应用函数来进行优化。
/**
★ 偏应用函数
*/
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")
函数的参数是函数,或者函数的返回类型是函数,或者函数的参数和函数的返回类型是函数的函数。
/**
* 高阶函数
★ 函数的'参数'是函数
* 函数的'返回'是函数
* 函数的'参数'和'返回'都是函数
*/
// 函数的参数是函数
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))
// 上面被注释掉的写法尽量不要写,下划线多了很容易看不明白
柯里化–颗粒化,将参数变成颗粒散落简而言之就是将参数拆拆拆。函数柯里化所做的事情:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。如果写成公式文字就是这样。
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