Scala的学习
Scala:Scala将面向对象和函数式编程结合成一种简洁的高级语言
Scala语言的特点:1.Scala是一门多范式的编程语言,支持面向对象和函数式编程。(多范式,就是多种编程方法)
2. Scala的源码通过scalac编译器编译为Java的字节码文件(class),然后运行在JVM上
使用Scala必须要有Java
1.Scala的安装
一般情况下IDEA默认不支持Scala的开发,需要安装Scala的插件
插件可以从jetbrains.com下载
将从本地安装Scala插件(插件得是适应IDEA版本)
然后创建maven工程,maven是不支持Scala开发,需要引入Scala框架
在项目上点击Add FrameWork Support, 选择Scala
创建项目的源文件目录
右键点击main目录->New->点击Diretory -> 写个名字(比如scala)
右键点击scala目录->Mark Directory as->选择Sources root
2.hello world案例
由于Scala是完全面向对象的,并没有静态语法,因此采用伴生对象单例的方式调用方法
3.变量和数据类型
常量:在程序执行的过程中,其值不会被改变的变量
注意:java中的final如果加static才会被存放在常量池中,否则作为不可修改的变量存在堆栈中。
var 变量名 [: 变量类型] = 初始值 var i:Int = 10
val 常量名 [: 常量类型] = 初始值 val j:Int = 20
注意:能用常量的地方不用变量
案例实操:
(1)声明变量时,类型可以省略,编译器自动推导,即类型推导
(2)类型确定后,就不能修改,说明Scala是强数据类型语言。
(3)变量声明时,必须要有初始值
(4)在声明/定义一个变量时,可以使用var或者val来修饰,var修饰的变量可改变,val修饰的变量不可改。
(5)var修饰的对象引用可以改变,val修饰的对象则不可改变,但对象的状态(值)却是可以改变的。(比如:自定义对象、数组、集合等等)
字符串输出:
基本语法:
(1)字符串,通过+号连接
(2)重复字符串拼接 ex:println("nihao " * 3) => nihao nihao nihao
(3)printf用法:字符串,通过%传值。 ex : println("name : %s , age : %d" , name ,age)
(4)字符串模板(插值字符串):通过$获取变量值 ex: println(s"name : ${name},age : ${age}")
键盘输入:
StdIn.readLine()、StdIn.readShort()、StdIn.readDouble()
Scala中的数据类型(重点):
1) Scala中一切数据都是对象,都是Any的子类。
2)Scala中数据类型分为两大类:数值类型( AnyVal) 、引用类型(AnyRef),不管是值类型还是引用类型都是对象。
3) Scala数据类型仍然遵守,低精度的值类型向高精度值类型,自动转换(隐式转换)
4)Scala中的StingOps是对Java中的String增强
5)Unit:对应Java中的void,用于方法返回值的位置,表示方法没有返回值。Unit是一个数据类型,只有一个对象就是()。Void不是数据类型,只是一个关键字
6)Null是一个类型,只有一个对象就是null。它是所有引用类型(AnyRef)的子类。
7)Nothing,是所有数据类型的子类,主要用在一个函数没有明确返回值时使用,因为这样我们可以把抛出的返回值,返回给任何的变量或者函数。
Scala中的运算符,流程控制和Java没有大的区别
4.函数式编程
函数的基本语法:
函数的至简原则:
至简原则细节:
(1)return可以省略,Scala会使用函数体的最后一行代码作为返回值
(2)如果函数体只有一行代码,可以省略花括号
(3)返回值类型如果能够推断出来,那么可以省略(:和返回值类型一起省略)
(4)如果有return,则不能省略返回值类型,必须指定
(5)如果函数明确声明unit,那么即使函数体中使用return关键字也不起作用
(6)Scala如果期望是无返回值类型,可以省略等号
(7)如果函数无参,但是声明了参数列表,那么调用时,小括号,可加可不加
(8)如果函数没有参数列表,那么小括号可以省略,调用时小括号必须省略
(9)如果不关心名称,只关心逻辑处理,那么函数名(def)可以省略
函数的高阶使用:
1)函数可以作为值进行传递
2)函数可以作为参数进行传递
3)函数可以作为函数返回值返回
匿名函数:
基本语法:(x:Int)=>{函数体}
传递匿名函数至简原则:
(1)参数的类型可以省略,会根据形参进行自动的推导
(2)类型省略之后,发现只有一个参数,则圆括号可以省略;其他情况:没有参数和参数超过1的永远不能省略圆括号。
(3)匿名函数如果只有一行,则大括号也可以省略
(4)如果参数只出现一次,则参数省略且后面参数可以用_代替
5.面向对象
和Java的面向对象基本类似,这里重点说下Scala中的trait(特质)
Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。
Scala中的trait中即可以有抽象属性和方法,也可以有具体的属性和方法,一个类可以混入(mixin)多个特质。这种感觉类似于Java中的抽象类。
Scala引入trait特征,第一可以替代Java的接口,第二个也是对单继承机制的一种补充。
特质基本语法
一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素,所以在使用时,也采用了extends关键字,如果有多个特质或存在父类,那么需要采用with关键字连接。
1)基本语法:
没有父类:class 类名 extends 特质1 with 特质2 with 特质3 …
有父类:class 类名 extends 父类 with 特质1 with 特质2 with 特质3…
2)说明
(1)类和特质的关系:使用继承的关系。
(2)当一个类去继承特质时,第一个连接词是extends,后面是with。
(3)如果一个类在同时继承特质和父类时,应当把父类写在extends后。
3)案例实操
(1)特质可以同时拥有抽象方法和具体方法
(2)一个类可以混入(mixin)多个特质
(3)所有的Java接口都可以当做Scala特质使用
(4)动态混入:可灵活的扩展类的功能
(4.1)动态混入:创建对象时混入trait,而无需使类混入该trait
(4.2)如果混入的trait中有未实现的方法,则需要实现
在Java中的类不允许多继承(出现钻石问题,造成程序的混乱),而Scala中的trait可以多继承(通过特质叠加的手段,解决了钻石问题)
钻石问题:
Scala中的特质叠加:
Scala中的类型转换:
类型检查和转换
1)说明
(1)obj.isInstanceOf[T]:判断obj是不是T类型。
(2)obj.asInstanceOf[T]:将obj强转成T类型。
(3)classOf获取类模板。
6.Scala中的集合
1)Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。
2)对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本,分别位于以下两个包。
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable
3)Scala不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于java中的String对象
4)可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于java中StringBuilder对象
建议:在操作集合的时候,不可变用符号,可变用方法
元组
1)说明
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。
注意:元组中最大只能有22个元素。
2)案例实操
(1)声明元组的方式:(元素1,元素2,元素3)
(2)访问元组
(3)Map中的键值对其实就是元组,只不过元组的元素个数为2,称之为对偶
集合中的常用函数(重点)
(1)过滤
遍历一个集合并从中获取满足指定条件的元素组成一个新的集合
(2)转化/映射(map)
将集合中的每一个元素映射到某一个函数
(3)扁平化
(4)扁平化+映射 注:flatMap相当于先进行map操作,在进行flatten操作
集合中的每个元素的子元素映射到某个函数并返回新集合
6)分组(groupBy)
按照指定的规则对集合的元素进行分组
7)Reduce方法
Reduce简化(归约) :通过指定的逻辑将集合中的数据进行聚合,从而减少数据,最终获取结果。
8)Fold方法
Fold折叠:化简的一种特殊情况,可以添加初始值
wordCount案例
7.模式匹配
基本语法
模式匹配语法中,采用match关键字声明,每个分支采用case关键字进行声明,当需要匹配时,会从第一个case分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断。如果所有case都不匹配,那么会执行case _分支,类似于Java中default语句。
8.隐式转换
当编译器第一次编译失败的时候,会在当前的环境中查找能让代码编译通过的方法,用于将类型进行转换,实现二次编译
普通方法或者函数中的参数可以通过implicit关键字声明为隐式参数,调用该方法时,就可以传入该参数,编译器会在相应的作用域寻找符合条件的隐式值。
1)说明
(1)同一个作用域中,相同类型的隐式值只能有一个
(2)编译器按照隐式参数的类型去寻找对应类型的隐式值,与隐式值的名称无关。
(3)隐式参数优先于默认参数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本