scala学习笔记(二):入门
语言输出
package com.rzp.service object PrintDemo { def main(args: Array[String]): Unit = { var str1:String = "Hello" var str2:String = " world" println(str1+str2) var name:String = "tom" var age:Int = 10 var sal:Float = 10.67f var height:Double = 180.15 //格式化输出 %.3保留3位 printf("名字=%s 年龄是%d 薪水%f 身高%.3f",name,age,sal,height) println("\n=================================================") //使用$输出(类似el表达式) println(s"个人信息: \n名字$name \n年龄$age \n薪水$sal") println("\n=================================================") //可以对变量做简单的运算 println(s"个人信息: \n名字${name} \n年龄${age} \n薪水${sal10}") } }
printf
printf 格式化输出
%d 十进制数字
%s 字符串
%c 字符
%e 指数浮点数
%f 浮点数
%i 整数(十进制)
%o 八进制
%u 无符号十进制
%x 十六进制
%% 打印%
% 打印%
以上部分摘自:https://blog.csdn.net/A_A_Forever/article/details/91456663
生成文档
-
和Java类似,可以生成文档,使用命令scaladoc
格式规范
变量的定义
编译器:逃逸分析
新的编译器里,对象不一定放在堆或者栈里面,会堆对象做分析,如果可能有多个引用,会放在堆里,如果只是临时用,对象也有可能放在栈里面。
类型推导
-
scala不写类型也会自动推导。
-
但是scala是强类型语言,定义以后不能改变了。
package com.rzp.service object VarDemo02 { def main(args: Array[String]): Unit = { //类型推导 var num = 10 //虽然没有定义,但是scala会推导为Int类型。 //可以看IDEA的提示来证明是Int //可以用isInstanceOf方法判断 println(num.isInstanceOf[Int]) } }
VAR和VAL
val相当于final,修改就会报错。
为什么设计val和var:
实际编程中,通常是读取对象的属性,或者修改对象的属性,但是很少会改变对象本身。这种情况下可以使用val,因为val是线程安全的,效率较高。
比如以下的例子,通常不需要给一个新的Dog对象,只是改对象的属性。
加号
数据类型
-
Scala中没有基本数据类型,所有的都是对象(类似Java的包装类和引用类)。
package com.rzp.datatype object TypeDemo01 { def main(args: Array[String]): Unit = { var num1:Int = 10 //Int这些都是对象,并且已经给了大量的类型转换方法 //在scala中,如果一个方法没有形参,可以省略括号 println(num1.toChar) } }
-
在scala中,有一个根类型Any,是所有类的父类。
-
一切皆为对象,分为AnyVal(值类型),AnyRef(引用类型)
-
Null是Scala的特别类型,只有一个值null,是Bottom class,是所有AnyRef的子类。
-
Nothing,也是一个Bottom Class,是所有类的子类。开发中可以把Nothing类型的值可以返回给任意变量或者函数,主要在抛出异常的时候使用。
package com.rzp.datatype object NothingClassT { def main(args: Array[String]): Unit = { } //比如开发中,异常中断时可以返回Nothing,说明这个方法没有正确返回 def sayHello: Nothing = { throw new Exception("抛出异常") } }
-
Scala中仍然遵守低精度向高精度可以自动转换----隐式转换(implicit conversion)
常用数据类型
整型
-
注意第三个,可以理解为后面的数默认为int,数值超过int了,就报错了,加个l就可以了。
拓展
Int为什么是这个数值区间:
-
Int的存储空间是2进制下32位数。
-
使用第一位0和1代表正数和负数,因此最大的数是2的31次方-1 = 2147483647。
-
而正常负数也应该 -2147483647。
-
但是因为不需要同时有正0和负0两个重复的值。
-
因为把-0这一位借给了 -2147483648
浮点类型
字符类型
布尔
Unit Null Nothing
使用细节和注意事项
1) Null类只有一个实例对象,null,类似于Java中的null引用。null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal: 比如 Int, Float, Char, Boolean, Long, Double, Byte, Short)
2) Unit类型用来标识过程,也就是没有明确返回值的函数。类似于Java里的void。Unit只有一个实例“ ()”,这个实例也没有实质的意义
3) Nothing,可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容。
拓展
-
Scala中可以字符串*3
-
10 max 2
-
字符串下标获取
自动类型转换
强制类型转换
值类型和String类型转换
-
唯一需要注意的就是String转成基本值类型时,必须是正确的类型才能转(比如12.5不能转成Int)
标识符
运算符
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
1)算术运算符
2)赋值运算符
3)比较运算符(关系运算符)
4)逻辑运算符
5)位运算符
优先级
拓展
控制台输入
package com.rzp.inputcon import scala.io.StdIn object InputDemo { def main(args: Array[String]): Unit = { println("请输入姓名") val name = StdIn.readLine() println("请输入年龄") val age = StdIn.readInt() println("请输入姓名") val sal = StdIn.readDouble() printf("用户信息为 name=%s,age=%d,sal=%.2f",name,age,sal) } }
流程控制
顺序控制
分支控制
关于第二点,具体示例
package com.rzp.inputcon object IfElseDemo { def main(args: Array[String]): Unit = { val age = 11 val res = if (age > 20) { println("hello age > 20") 9 + 10 "yes ok" } println(res) //age >20 ----> "yes ok" //age <20 ----> "()" } }
Switch,后续补充
For循环控制
for-to循环双闭合
package com.rzp.inputcon object ForDemo { def main(args: Array[String]): Unit = { for (i <- 1 to 10) println("Hello World") var list = List("hello",30,52,"sdfa") for(item <- list){ println(s"item:$item") } } }
for-until循环左闭右开
object ForDemo2 { def main(args: Array[String]): Unit = { for (i <- 1 until 11){ println(s"Hello World ${i}") } } }
循环守卫
引入变量
嵌套循环
scala支持在一个括号内写两个循环,但是实际业务中外层循环和内层循环业务不同,这个可能很少用。
package com.rzp.inputcon object ForDemo3 { def main(args: Array[String]): Unit = { for (i <- 1 to 3;j<- 1 to 3){ println(s"i=${i} and j = ${j}") } } }
循环返回值
package com.rzp.inputcon object ForDemo4 { def main(args: Array[String]): Unit = { //yield就是把后面的内容放到集合Vector中,返回给res val res = for (i<- 1 to 100) yield { if(i%2==0){ i }else{ "不是偶数" } } println(res) } }
{}代替()
控制步长
package com.rzp.inputcon object StepForDemo { def main(args: Array[String]): Unit = { for (i <- 1 to 10) { println(s"i=${i}") } //步长控制为2 //方式1 println("==========================================") //def apply(start: Int, end: Int, step: Int): Range.Exclusive = new Range.Exclusive(start, end, step) for (i <- Range(1, 10, 2)) { println(s"i=${i}") } //方式2 println("==========================================") for (i <- 1 to 10 if i % 2 == 1){ println(s"i=${i}") } } }
While循环控制
Break
-
break()会抛出异常,被Breakable处理
package com.rzp.whileloop import util.control.Breaks._ object WhileLoopDemo { def main(args: Array[String]): Unit = { var n = 1 //breakable,是一个高阶函数--->可以接收函数的函数就是高阶函数 /** * def breakable(op: => Unit): Unit = * try op catch { case ex: BreakControl if ex eq breakException => } * (op: => Unit) 表示接收的参数是一个没有输入,也没有返回值的函数,相当于传入的是一个代码块。 * try op catch就是捕获breakException这个异常, */ breakable{ while (n <= 20){ n += 1 println("n="+n) if (n == 18){ //break会抛出breakException /** * def break(): Nothing = throw breakException */ break() } } } //如果没有breakable捕获异常,会直接中断程序,走不到这里 println("123") } }
Countinue