Scala简介
(斯嘎拉)Scalable Language(可伸缩的语言),基于jvm多范式编程语言
Scala的运行环境和java类似,也是依赖jvm的。
Scala支持多种编程风格
Scala下载安装
官网下载
https://www.scala-lang.org
配置环境变量
cmd输入scala查看是否配置成功
退出解释器
一:叉掉
二::quit
idea Scala插件
新建一个Demo01.scala(Object类型)
object Demo01 {
def main(args: Array[String]): Unit = {
print("hello scala!!!")
}
}
Scala语法
在 Scala 中,使用关键词 “var” 声明变量,使用关键词 “val” 声明常量。
var/val 变量名:变量类型 = 初始值
var myVar : String = "Foo"
var myVar : String = "Too"
在 Scala 中声明变量和常量不一定要指明数据类型,在没有指明数据类型的情况下,其数据类型是通过变量或常量的初始值推断出来的。
var myVar = 10;
val myVal = "Hello, Scala!";
所以,如果在没有指明数据类型的情况下声明变量或常量必须要给出其初始值,否则将会报错。
命名规范
标识符
Scala 对各种变量、方法、函数等命名时使用的字符序列称为标识符。
命名规则:
- 首字符为字母,后续字符任意字母和数字,美元符号,可后接下划线_ 。
- 数字不可以开头。
- 首字符为操作符(比如+ - * / ),后续字符也需跟操作符 ,至少一个(反编译) 。
- 操作符(比如±*/)不能在标识符中间和最后。
- 用反引号…包括的任意字符串,即使是关键字(39个)也可以 [true]。
- 包名:尽量采取有意义的包名,简短,有意义。
- 变量名、函数名 、方法名 采用驼峰法。
控制语句
if语句
if(布尔表达式){
//如果布尔表达式为true 则执行该语句块
}
//实例
object Test{
def main(args:Array[String]){
var x = 10;
if(x < 20){
println("x < 20");
}
}
}
if…else 语句
if 语句后可以紧跟 else 语句,else 内的语句块可以在布尔表达式为 false 的时候执行。
if(布尔表达式){
// 如果布尔表达式为 true 则执行该语句块
}else{
// 如果布尔表达式为 false 则执行该语句块
}
惰性赋值
sql语句很繁杂,如果不马上使用,且放进了jvm中会导致资源占用
lazy sql:String
类型 | 说明 |
---|---|
Any | 所有类型的父类,它有两个子类AnyRef与AnyVal |
AnyVal | 所有数值类型的父类 |
AnyRef | 所有对象类型(引用类型)的父类 |
Unit | 表示空,Unit是AnyVal的子类,它只有一个的实例{%em%}(){%endem%}它类似于Java中的void,但scala要比java更加面向对象 |
Null | Null是AnyRef的子类,也就是说它是所有引用类型的子类。它的实例是{%em%}null{%endem%}可以将null赋值给任何对象类型 |
Nothing | 所有类型的子类,不能直接创建该类型实例,某个方法抛出异常时,返回的就是Nothing类型,因为Nothhing是所有类的子类,那么它可以赋值为任何类型 |
键盘录入
导包
import scala.io.StdIn
#接收数据
StdIn.readLine()
StdIn.readInt()
println("请录入一个字符串")
var s = StdIn.readLine()
println("请录入一个数字")
var i = StdIn.readInt()
^相同为0 不同为1
~补码取反 转反码
下滑线初始化成员变量
更简洁的初始化成员变量的方式,使代码更简洁
用法:
在定义var类型的成员变量时,可以使用_ 来初始化成员变量
- String =>null
- Int =>
- Boolean => false
- Double => 0.0
val类型的成员变量必须自己手动初始化
// 要告诉它你需要的是什么类型
var age:int = _
var name:String = _
for循环
for(i <- 表达式/数组/集合){
//逻辑代码
}
守卫
for表达式中可以添加if判断语句,这个if判断就称之为守卫
for(i <- xxx if 表达式){
//逻辑代码
}
for(i <- 1 to 10 if i%3 == 0 ) println(i)
for推导式
for循环有返回值,在for循环体中,可以使用yield表达式构建出一个集合(可以简单理解为一组数据),我们把使用yield的for表达式称之为推导式
val v = for(i <- 1 to 10) yield i + 10
println(v)
while
while(判断条件){
//循环体
//控制条件
}
while( i <= 10){
println(i)
i = i+1
//Scala没有i++这种写法
}
do while循环
do{
//循环体
//控制条件
}while(判断条件)
do{
print(i)
i=i+1
}while(i < 10)
break continue
需要使用时,要导包
import sacla.until.control.Breaks._
breakable{
for(i <- 1 to 10)
if(i == 5) break() else println(i)
}
实现break是用braakable{}将整个for表达式包起来
实现continue是用breakable{}将for表达式的循环体包含起来就可以了
for(i <- 1 to 10){
breakable{
if(i%3 == 0) break() else println(i)
}
}
九九乘法表
for (i <- 1 to 10){
for(j <- 1 to i){
print(i+"*"+j+"="+(i*j)+" ")
}
println()
}
方法与函数
Scala 中使用 val 语句可以定义函数,def 语句定义方法。
class Test{
def a(x:Int) = x+3
val b = (x:Int) => x+3
}
语法
def functionName ([参数列表]) : [return type] = {
function body
return [expr]
}
主构造器
object ClassDemo01 {
class Person(val name: String = "张三", val age: Int = 23) {
//在主构造器中输出“调用主构造器”
println("调用主构造器")
}
def main(args: Array[String]): Unit = {
//创建空对象打印属性值
val p1 = new Person()
println(s"p1: ${p1.name},${p1.age}")
//创建全参对象,并打印属性值
val p2 = new Person("李四",age = 24)
println(s"p2: ${p2.name},${p2.age}")
//创建对象,仅指定年龄,打印属性值
val p3 = new Person(age = 30)
println(s"p3:${p3.name},${p3.age}")
}
}
//创建空对象打印属性值
val p1 = new Person()
println(s"p1: ${p1.name},${p1.age}")
//创建全参对象,并打印属性值
val p2 = new Person("李四",age = 24)
println(s"p2: ${p2.name},${p2.age}")
//创建对象,仅指定年龄,打印属性值
val p3 = new Person(age = 30)
println(s"p3:${p3.name},${p3.age}")
}
}
辅助构造器
主构造器以外的构造器都称为辅助构造器
- 定义辅助构造器与定义方法一样,也使用def关键字来定义
- 辅助构造器的默认名字是this,且不能修改
def this(参数名:类型,参数名:类型){
//第一行需要调用主构造器或者其他构造器
//构造器代码
}
辅助构造器的第一行代码,必须要调用主构造器或者其他辅助构造器
object ClassDemo02{
//定义Customer类,主构造器中指定:姓名,地址。
class Customer(val name:String ,val address:String){
//定义辅助构造器,接收一个数组类型的参数
def this(arr:Array[String]){
//第一行必须访问主构造器或者其他的辅助构造器
this(arr(0),arr(1))
}
}
def main(args:Array[String]):Unit = {
//通过辅助构造器创建Customer类的对象
val c = new Customer(Array("张三","北京"))
println(c.name,c.address)
}
}
单例对象
scala中是没有static关键字的,要想定义类似于ava中的static变量、static方法,就要使用到scala中的单例对象了,也就是obiect.
单例对象表示全局仅有一个对象,也叫孤立对象。定义单例对象和定义类很像,就是把class换成obiect.格式
注意:
- 在obiect中定义的成员变量类似于Java中的静态变量,在内存中都只有一个对象.
- 在单例对象中,可以直接使用单例对象名的形式调用成员
例子:
。定义一个Dog单例对象,保存狗有几条腿
。在main方法中打印狗腿的数量
参考代码
object 单例对象名[ ]
//定义一个单例对象
object ClassDemo01{
//定义单例对象Dog
object Dog{
//定义一个变量。用来保存够的腿数量
var leg_num = 4
}
//定义main方法,作为程序主入口
def main(args: Array[String]): Unit = {
println(Dog.leg_num)
}
}
单例对象中定义方法
单例对象中定义的成员方法类似于java中的静态方法
- 设计一个单例对象,定义一个能够打印分割线(15个减号)的方法
- 在main方法调用该方法,打印分割线
object ClassDemo01 {
// 设计一个单例对象定义一个能够打印分割线(15 个减号)的方法
// 在main方法调用该方法,打印分割线
//定义单例对象Line
object Line {
//定义一个变量。用来保存够的腿数量
def PrintLine():Unit= println("-"*15)
}
//定义main方法,作为程序主入口
def main(args: Array[String]): Unit = {
Line.PrintLine()
}
}
main方法
Scala程序中,如果要运行一个程序,必须有一个main方法。在java中main方法是静态的,而在scala中没有静态方法。所以在scala中,这个main方法必须放在一个单例对象。
main方法
def main(args: Array[String]): Unit = {
//方法体
}
object ClassDemo01 {
//定义main方法,作为程序主入口
def main(args: Array[String]): Unit = {
print("main方法")
}
}
继承App特质
创建object,继承App特质(Trait),然后将需要编写在main方法中的代码,写在object的构造方法体内。
object ClassDemo01 extends App {
def a():Unit={
print("hhh")
}
print("aa")
a()
}
伴生对象
java中,有时类同时有实例成员,又有静态成员
public class Generals{
private static String Name = "长矛";
public void toWarr(){
System.out.print("武将拿着"+Name+",上阵杀敌!");
}
public static void main(String[]args){
new Generals().toWar();
}
}
Scala中要实现类似效果,可以使用伴生对象来实现.
定义伴生对象
一个class和obiect具有同样的名字。这个obiect称为伴生对象,这个class称为伴生类
-
伴生对象必须要和伴生类一样的名字
-
伴生对象和伴生类在同一个scala源文件中
-
伴生对象和伴生类可以互相访问private属性
object ClassDemo01{
// 编写一个Generals类,有一个toWar方法
class Generals{
def toWar():Unit=print("武将拿着"+Generals.Name+"上阵杀敌!")
// 重名的单例对象 为伴生对象
}
object Generals{
private val Name = "长矛"
}
def main(args: Array[String]): Unit = {
// 创建伴生类的对象
val c = new Generals;
c.toWar();
}
}
private[this]访问权限
如果某个成员的权限设置为private[this],表示只能在当前类中访问。伴生对象也不可以访问
示例
- 定义一个Person类,包含一个name字段,该字段用private[this]修饰
- 定义Person类的伴生对象,定义printPerson方法。
- 测试伴生对象是否能访问private[this]权限的成员
object ClassDemo01{
// 定义一个Person类包含一个name字段
class Person(private[this] var name:String)
// 该字段用private[this] 修饰 定义Person类的伴生对象
object Person{
// 定义printPerson方法-测试伴生对象是否能访问private[this] 权限的成员
def printPerson(p:Person):Unit= println(p.name)
def main(args: Array[String]): Unit = {
var p = new Person("张三")
Person.printPerson(p)
}
}
}
验证了上述private[this]的作用
apply方法
在Scala中,支持创建对象的时候,免new 的动作,这种写法非常简便,优雅。要想实现 免new,我们就要通过伴生对象的apply方法来实现。
object 伴生对象名 {
def apply(参数名:参数类型,参数名:参数类型)=new 类(...)
}
创建对象
val 对象名 = 伴生对象名(参数1,参数2...)
object ClassDemo{
class Person(var name:String = "",var age:Int = 0){}
object Person{
def apply(name:String,age:Int) = new Person(name,age)
}
def main(ags:Array[Sting]):Unit = {
val P = Person("张三",23)
println(p.name,p.age)
}
}