文章目录
变量和数据类型
一、注释
Scala 注释使用和Java完全一样
注释是一个程序员必须要具有的良好编程习惯,将自己的思想通过注释先整理出来,再用代码去体现。
1)基本语法
(1) 单行注释: //
(2) 多行注释: /**/
(3) 文档注释: /**
*
*/
2) 代码示例
注意: 要是在 object 里面的函数的话就不用创建对象, 直接像python一样直接输出就好了
package scala_xuexi01
class test_zhushi {
def hanshu():Unit={
println("这是一个测试的函数")
}
}
/*
这是一个多行注释,/ 然后回车就可以了
测试注释
*/
object test_zhushi{
/**
* 这是程序的入口方法
* 这个跟多行注释挺像的,**回车就行了
* @param args
*/
def main(args: Array[String]): Unit = {
//这是一个单行注释,打印输出
println("hello")
val aex = new test_zhushi()
aex.hanshu()
hanshu2() //要是函数是在 object类里面的话,跟python一样直接调用就行了,不用创建对象
}
def hanshu2():Unit={
println("这是第二个测试的函数")
}
}
3) 代码规范
(1) 使用一次 tab 操作,实现缩进,默认整体向右边移动,用shift+tab 整体向左移
(2) 或者使用ctrl +alt + L 来进行格式化
(3) 运算符两个习惯性各加一个空格,比如: 2 + 4 * 5
(4) 一行最长不超过80个字符,超过的请使用换行显示,尽量保持格式优雅
二、变量和常量 (重点)
常量: 在程序执行的过程中,其值不会被改变的变量
0) 回顾:Java 变量和常量方法
变量类型 变量名称 = 初始值 int a = 10
final 常量类型 常量名称 = 初始值 final int b = 20
1) 基本语法
var 变量名[: 变量类型] = 初始值 var i:int = 10
val 常量名[: 常量类型] = 初始值 val j:Int = 20
注意:能使用常量就不使用变量
常量:在程序执行过程中,不会被改变的值就被称为常量 主要是因为scala是函数式编程语言,在数学中的思想,定义了一个值本来就是不会被改变的,所以说推荐使用常量
2) 代码示例
(1) 声明变量时,类型可以省略,编译器自动推导,即类型推导
(2) 类型确定后,就不能修改,说明Scala 是强数据类型语言
(3) 变量声明时,必须要有初始值
(4) 在声明定义一个变量时,可以使用 var 或者 val 来修饰,var 修饰的变量可改变,val 修饰的变量不可改
package scala_xuexi01
class test_val {
}
object test_val{
def main(args: Array[String]): Unit = {
//声明一个变量通用语法
var a:Int = 10
// (1) 声明变量时,类型可以省略,编译器自动推导,即类型推导
var a1 = 10 //可以不要类型,系统会自动判断
val b1 = 23
// (2) 类型确定后,就不能修改,说明Scala 是强数据类型语言
val a2 = 15 //a2类型为int
//a2 = "hello" 上面已经确定了是int整数类型,下面重新赋值为字符串类型是不行的
// (3) 变量声明时,必须要有初始值
// val a3:Int 其他语言里面可以先把变量放在那里,不设定值,在scala里面不能这个样子,必要要有初始值z
// (4) 在声明定义一个变量时,可以使用 var 或者 val 来修饰,var 修饰的变量可改变,val 修饰的变量不可改
var a4 = 20
a4 = 25
val a5 = 20
//a5 = 24 使用val定义的变量的值是不能更改的,var的可以
var h = new Student("aex",19) //还能调用其他类里面的
// h = new Student("hello",20) //就连对对象里面的参数都不能改,使用val定义的
h = new Student("hello",20) //var 定义的可以改变对象里面参数的值
val bob = new Student("bob",21)
bob.age = 24 //在前面的Stuedent 吧这个age参数给改为 var 就可以改变值
h.shuchu() //甚至可以调用其他类文件里面的函数
}
}
三、标识符的命名规范
Scala 对各种变量,方法,函数等命名时使用的字符序列称为标识符。即:凡是自己可以起名字的地方都叫标识符。
1) 命名规则
Scala 中的标识符声明,基本和Java是一致的,但是细节上会有所变化,有以下三种规则:
(1) 以字母或者下划线开头,后接字母,数字,下划线
(2) 以操作符开头,且只包含操作符(+ - * / # !等) 注意:只能有操作符,不然+2都不理解是啥意思,到底是名称还是数字+2
(3) 用反引号’…’ 包含的任意字符串,即使是Scala关键字 (39个) 也可以,加粗的这些关键字是Scala有,java没有的
- package,import,class,object,train,extends,with,type,for
- private,protected,abstract,sealed,final,implicit,lazy,override
- try,catch,finally,throw
- if,else,match,case,do,while,for,return,yield
- def,val,var
- this,super
- new
- true,false,null
2) 代码示例
package scala_xuexi01
class test_biaoshifu {
}
object test_biaoshifu{
def main(args: Array[String]): Unit = {
// (1) 以字母或者下划线开头,后接字母,数字,下划线
val hello:String = ""
val Hello123 = ""
val _abc = 13
// val h-b = "" //这种命名方法是错的,系统会不清楚是不是运算符,但是IDEA不会报错
// val 132abc = 12 这种命名也错的,不能以数字开头
// (2) 以操作符开头,且只包含操作符(+ - * / # !等) 注意:只能有操作符,不然+2都不理解是啥意思,到底是名称还是数字+2
val + = "sda" //以操作符为为变量没有问题,但是只能有操作符不能加字母或者数字,+2这种
println(+)
// (3) 用反引号'.....' 包含的任意字符串,即使是Scala关键字 (39个) 也可以
// val if = "132" 要是直接把关键字变量的话会报错
val `if` = "132" //使用关键字当变量,加上反引号就可以了
println(`if`)
}
}
四、字符串输出
1) 基本语法
(1) 字符串,通过 + 号连接
(2) printf 用法:字符串,通过 % 传值
(3) 字符串模板 (插值字符串) : 通过$ 获取变量值
2) 代码示例
1,printf : 使用% 占位符 如果是%d的话就是数值类型,如果是%s的话就是字符串类型,然后后面传参数就行
2,字符串模板(插值字符串): s"" 表示这个字符串模板,然后里面是${} 里面传入变量就行
package scala_xuexi01
//测试 字符串输出
class test_zifushuchu {
}
object test_zifushuchu{
def main(args: Array[String]): Unit = {
// (1) 字符串,通过 + 号连接
val name:String = "aex"
val age:Int = 19
println(age + "岁的" + name + "在学Scala")
// * 用于将一个字符串复制多次拼接
println(name * 3) //将这个name 变量的值进行三次相加,相当于也是字符串拼接
// (2) printf 用法:字符串,通过 % 传值
// 这个百分号是占位符,在scala里面是%,具体是d还是s看是什么类型,数值类型是d,字符串类型是s,然后后面传参数就行
printf("%d岁的%s在学习Scala",age,name) //代表想要用某种格式化方法,对模型进行设置的这样一种应用
println()
// (3) 字符串模板 (插值字符串) : 通过$ 获取变量值
println(s"${age}岁的${name}在学习Scala") //s"" 是一个整体代表是模板字符串。里面直接${}里面放变量就行
val num:Float = 2.3456f // 模型是Doulue类型的,要想转浮点类型在后面加一个f就不会报错了
println(f"${num}%2.2f") //f是格式化模板字符串,s是变量直接填进来,一般还是直接使用s的
println(raw"${num}%2.2f") //row的话后面的%后面的不会解析成要做格式化,只会按照原始的样子输出
//三引号表示字符串,保持多行字符串的原格式输出 使用s""" 然后回车,中间会有一个分隔符
val sql = s"""
|select *
|from
|where
|name = ${name}
|and
|age =aeg > ${age}
|""".stripMargin //这是字符串本身的一个方法,表示我们可以忽略编辑
println(sql)
}
}
五、控制台标准输入
在编程中,需要接受用户输入的数据,就可以使用键盘输入语句来获取
1) 基本语法
StdIn.readLine()
、StdIn.readShort()
、StdIn.readDouble()
2) 代码示例
在Scala 里面输入使用 StdIn 类下面的 readLine 这个是字符串类型,还有其他各种类型的比如readInt 这是整数型 然后用一个变量接收,下面使用字符串模板输出
需求:可以从控制台接收用户信息,【姓名,年龄,薪水】
package scala_xuexi01
import scala.io.StdIn
class test05_StdIn {
}
object test05_StdIn{
def main(args: Array[String]): Unit = {
//输入
println("请输入您的大名:")
val name = StdIn.readLine() //引入StdIn类下面的,readLine 是字符串类型的
println("请输入你的芳龄:")
val age = StdIn.readInt() //引入StdIn方法下面的 readInt()方法,是数值类型的
// 控制台输入输出
println(s"欢迎${age}岁的${name}同学")
}
}
六、读写文件
在scala 中要读取文件数据的话,使用scala.io.Source 下面的Source 模块,然后有一个fromFile()方法里面是要读取文件的路径,然后使用foreach(print) 方法,把里面的数据打印出来,不然只是读取了数据没输出出来
在scala 中没有专门提供写入文件数据的工具,因为java里面都有,在scala里面是可以直接调用java的类和包的,所有可以直接用 Java里面的PrintWriter 方法 里面new File ()方法 里面是要写入文件的路径 ,然后创建一个变量对象接收,然后直接用创建的对象.write() 方法直接在里面写入要写入的数据 ,最后再用对象.close() 方法,关闭文件,这个close() 方法最后一定要有,不然新建的文件里面没有数据
1) 代码示例
package scala_xuexi01
import java.io.{File, PrintWriter}
import scala.io.Source
// 读写文件
class test06_file {
}
object test06_file{
def main(args: Array[String]): Unit = {
// 1,从文件中读取数据
Source.fromFile("D:\\Scala02\\src\\main\\resources\\test.txt").foreach(print) //里面读取文件的路径
// 2,将数据写入文件
//使用 java 里的 PrintWriter() 类,然后创建一个新的对象 new File方法,里面的路径和读的那个文件一样
//写完之后那个路径下就会多出一个output.txt文件,里面会有write 方法写入的数据
val writer = new PrintWriter(new File("D:\\Scala02\\src\\main\\resources\\output.txt"))
writer.write("hello scala from java writer") //然后用write变量去调用write方法
writer.close()
}
}
七、数据类型(重点)
1) 回顾Java 数据类型
Java 基本类型:char、byte、short、int、long、float、double、boolen
Java引用类型:(对象类型)
由于Java有基本类型,而且基本类型不是正真意义的对象,即使后面产生了基本类型的包装类,但是任然存在基本数据类型,所以Java语言并不是真正意思的面向对象
Java 基本类型的包装类:Character、Byte、Short、Integer、Float、Double、Boolen
注意:Java中基本类型和引用类型没有共同的祖先
2) Scala数据类型
-
Scala中一切数据都是对象,
都是Any的子类
。 -
Scala中数据类型分为两大类:数值类型(AnyVal)、引用类型(AnyRef)、
不管是值类型还是引用类型都是对象
-
Scala数据类型任然遵守,
低精度的值类型向高精度值类型,自动转换
(隐式转换) -
Scala中的StringOps是对Java中的String增强
-
Unit:对应Java中的void,用于方法返回值的位置,表示方法没有返回值。
Unit是一个数据类型
,只有一个对象就是()
。Void不是数据类型,只是一个关键字 -
Null是一个类型
,只有一个对象就是null,它是所有引用类型(AnyRef)的子类
-
Nothing
,是所有数据类型的子类
,主要是在一个函数没有明确返回值时使用,因为这样我们可以把抛出的返回值,返回给任何的变量或者函数
下面是是Scala数据类型的关系图,都是Any类
下面的,然后下面分为AnyVal
值数据类型和AnyRef
引用数据类型
八、整数类型(Byte、Short、Int、Long)
Scala的整数类型就是用于存放整数类型的,比如12,30,3456等
1) 整形分类
数据类型 | 描述 |
---|---|
Byte[1] | 8位有符号补码整数,数值区间为 -128 到 127 |
Short[2] | 16位有符号补码整数,数值区间为 -32768 到 32767 |
Int[4] | 32位有符号补码整数,数值区间为 -2147483648 到 2147483647 |
Long[8] | 64 位有符号补码整数,数值区间为 -9223372036854775808 到 9223372036854775807 = 2的(64-1)次方-1 |
2) 代码示例
在整形数字里的话默认是Int类型的,如果超出了的Int数值范围正负21亿的话在数字后面加一个大写的L,就会认定为Long类型的,如果要转换类型的话在计算的数字后面加一个.toByte
,toInt
,toShort
想转换成什么类型就用什么方法
package scala_xuexi01
// 数据类型
class test07_DataType {
}
object test07_DataType{
def main(args: Array[String]): Unit = {
// 1,整数类型
val a1:Byte = 127
// val a2:Byte = 128 //Byte类型的范围在-128到127之间,要是超出了127就会报错
val a3 = 14 //要是定义的是一个整数的话,那么默认是Int类型的
// val a4 = 13123131321 要是超出了正负21亿的话,Int也会报错,就只有Long类型的了,长整型
val a5:Long = 13123131321L //如果想不报错的话,直接在后面加一个大写的L表示这个一个长整型
}
val b1:Byte=10
println(b1)
// val b2:Byte= b1+20 //默认是Int 类型改为Byte的话 直接运行会报错
val b2:Byte= (b1+30).toByte //正确的运行的使用括号括起来,然后.要转换的类型 就不会报错了
println(b2)
}
九、字符类型
字符类型可以表示单个字符,字符类型是Char
1) 基本语法
(1) 字符常量是用单引号 ''
括起来的单个字符
(2) \t
一个制表位,实现对齐功能
(3) \n
换行符
(4) \\
表示 \ 第一个\是表示转义
(5) \"
表示" 跟上面那个一样 \ 表示转义
2)代码示例
package scala_xuexi01
// 数据类型
class test07_DataType {
}
object test07_DataType{
def main(args: Array[String]): Unit = {
// 1,整数类型
val a1:Byte = 127
// val a2:Byte = 128 //Byte类型的范围在-128到127之间,要是超出了127就会报错
val a3 = 14 //要是定义的是一个整数的话,那么默认是Int类型的
// val a4 = 13123131321 要是超出了正负21亿的话,Int也会报错,就只有Long类型的了,长整型
val a5:Long = 13123131321L //如果想不报错的话,直接在后面加一个大写的L表示这个一个长整型
}
val b1:Byte=10
println(b1)
// val b2:Byte= b1+20 //默认是Int 类型改为Byte的话 直接运行会报错
val b2:Byte= (b1+30).toByte //正确的运行的使用括号括起来,然后.要转换的类型 就不会报错了
println(b2)
//2、字符类型
val c1:Char = 'a' //注意char 类型的是单引号,要是用引号就是String类型的了
println(c1)
val c2:Char = '9'
println(c2)
//控制字符
val c3:Char = '\t' //制表符
val c4:Char = '\n' //换行符
println("abc" + c3 + "def") //制表符中间会空两个格的作用
println("abc" + c4 + "def") //换行符两个数据中间直接换行
//转义字符
val c5 = '\\' //表示\ 自身 转义之后就是剩下一个\
val c6 = '\"' //表示"
println("abd" + c5 + "def")
println("abd" + c6 + "def")
//字符变量底层保存 ASCII 码
val i1:Int = c1
val i2:Int = c2
println("i1:" + i1) //查看底层字符表示的数字
println("i2:" + i2) //查看字符底层表示转换的ASCII码
val c7:Char = (i1 + 1).toChar //
println(c7)
val c8:Char = (i2 - 1).toChar //
println(c8)
}
十、布尔类型
1) 基本说明
(1) 布类型也叫Boolean 类型,Boolean 类型数据只允许取true 和 false
(2) boolen 类型占1个字节
2) 代码示例
package scala_xuexi01
// 数据类型
class test07_DataType {
}
object test07_DataType{
def main(args: Array[String]): Unit = {
// 1,整数类型
val a1:Byte = 127
// val a2:Byte = 128 //Byte类型的范围在-128到127之间,要是超出了127就会报错
val a3 = 14 //要是定义的是一个整数的话,那么默认是Int类型的
// val a4 = 13123131321 要是超出了正负21亿的话,Int也会报错,就只有Long类型的了,长整型
val a5:Long = 13123131321L //如果想不报错的话,直接在后面加一个大写的L表示这个一个长整型
}
val b1:Byte=10
println(b1)
// val b2:Byte= b1+20 //默认是Int 类型改为Byte的话 直接运行会报错
val b2:Byte= (b1+30).toByte //正确的运行的使用括号括起来,然后.要转换的类型 就不会报错了
println(b2)
//2、字符类型
val c1:Char = 'a' //注意char 类型的是单引号,要是用引号就是String类型的了
println(c1)
val c2:Char = '9'
println(c2)
//控制字符
val c3:Char = '\t' //制表符
val c4:Char = '\n' //换行符
println("abc" + c3 + "def") //制表符中间会空两个格的作用
println("abc" + c4 + "def") //换行符两个数据中间直接换行
//转义字符
val c5 = '\\' //表示\ 自身 转义之后就是剩下一个\
val c6 = '\"' //表示"
println("abd" + c5 + "def")
println("abd" + c6 + "def")
//字符变量底层保存 ASCII 码
val i1:Int = c1
val i2:Int = c2
println("i1:" + i1) //查看底层字符表示的数字
println("i2:" + i2) //查看字符底层表示转换的ASCII码
val c7:Char = (i1 + 1).toChar //
println(c7)
val c8:Char = (i2 - 1).toChar //
println(c8)
//布尔类型
//一般用在逻辑判断里面
val isTrue:Boolean = true //只有true 和 false 两种取值
val isFalse:Boolean = false
println(true)
println(false)
}
十、Unit类型,Null类型,Nothing类型(重点)
1) 基本说明
空类型 : 空值就是Unit
空引用是 null
数据类型 | 描述 |
---|---|
Unit | 表示无值,和其他语言中void相等。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成() |
Null] | null,Null 类型只有一个实例值 null |
Nothing | Nothing 类型在Scala的类层最低端;它是任何其他类的子类型。当一个函数我们确定没有正常的返回值,可以用Nothing来h指定返回类型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它的函数或者变量(兼容性) |
Long[8] | 64 位有符号补码整数,数值区间为 -9223372036854775808 到 9223372036854775807 = 2的(64-1)次方-1 |
2) 代码示例
//4、空类型
// 4.1 空值Unit
def m1():Unit = {
println("m1被调用执行")
}
val a:Unit = m1() //因为这个Unit是一个空返回值,所以输出出来就会有m1后面的那个括号
println(a)
//4.2 空引用Null
//val n:Int = null //一个值类型不能接受空引用
var student:Student = new Student("alice",10) //之前定义过的Student类
student = null //这样用类对象类型赋值为null的话是没有问题的
println(student)
//4.3 Nothing
def m2(n:Int):Int = {
if(n==0) //如果不为0的话,下面就会输出传入的参数,如果n为0,会抛出异常
throw new NullPointerException
else
return n
}
val b = m2(0) //因为上面抛出异常,程序已经中断了,所以这里接受不到,会抛出一个空值异常
println(b)
十一、数据类型自动转换
当Scala 程序正在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这个就是自动类型转换(隐式转换),数据类型按精度(容量) 大小排序为:
1) 基本说明
(1) 自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算
(2) 把精度大的数值类型赋值给精度小的数值类型时,就会报错
,反之就会进行自动转换
(3) (byte,sort) 和 char 之间不会相互自动转换
(4) byte,short,char 他们三者可以计算,在计算时首先转换为int类型
2) 代码示例
package scala_xuexi01
//scala类型转换
class test08_typezhuanhuan {
}
object test08_typezhuanhuan{
def main(args: Array[String]): Unit = {
// (1) 自动提升原则:有多种类型的数据混合运算时,系统首先`自动将所有数据转换成精度大的那种数据类型,然后再进行计算`
val a1:Byte = 10
val b1:Long = 2353L
val result:Long = a1+b1 //因为上面是Byte 和 Long 的数字相加,Long的精度比Int大,所以只有用Long
val result11:Int = (a1+b1).toInt //如果非要想要Int类型的话,那就括起来.toInt方法转换
println(result)
println(result11)
// (2) `把精度大的数值类型赋值给精度小的数值类型时,就会报错`,反之就会进行自动转换
val a2:Byte = 10
val b2:Int = a2 //可以直接把低精度的值赋值给高精度的,没有问题
//val c2:Byte = b2 //但是如果高精度的赋值给低精度的就会报错
// (3) (byte,sort) 和 char 之间不会相互自动转换
val a3:Byte = 10
val b3:Char = 'b'
val c3:Byte = b3.toByte //要想转的话只有通过方法进行强制转换
println(c3)
// (4) byte,short,char 他们三者可以计算,`在计算时首先转换为int类型`
val a4:Byte = 12
val b4:Short = 25
val c4:Char = 'c' //这个字符类型的和数值类型进行计算的话,默认会转换为Int类型的数值,也就是底层的ASCll码
val result4 = a4 + b4 + c4 //他们之间可以进行计算,默认转换为Int类型
println(result4)
}
}