Scala学习之路二

1 scala语言特点

可拓展

  • 面向对象
  • 函数式编程

兼容JAVA

  • 类库调用
  • 互操作

语法简洁

  • 代码行短
  • 类型推断
  • 抽象控制

静态类型化

  • 可检验
  • 安全重构

支持并发控制

  • 强计算能力
  • 自定义其他控制结构

2 scala与Java关系

  1. 都是基于JVM虚拟机运行的

Scala编译之后的文件也是.class,都要转换为字节码,然后运行在JVM虚拟机之上。

  1. Scala和Java相互调用

在Scala中可以直接调用Java的代码,同时在Java中也可以直接调用Scala的代码

  1. Java 8 VS Scala
 - Java 8(lambda)没有出来之前,Java只是面向对象的一门语言,但是Java8出来以后,Java就是一个面向对象和面向函数的混合语言了。
 - 首先我们要对Scala进行精确定位,从某种程度上讲,Scala并不是一个纯粹的面向函数的编程语言,有人认为Scala是一个带有闭包的静态面向对象语言),更准地说,Scala是面向函数与面向对象的混合。
 - Scala设计的初衷是面向函数FP,而Java起家是面向对象OO,现在两者都是OO和FP的混合语言,是否可以这么认为:Scala =FP+OO,而Java = OO+ FP?

由于面向对象OO和面向函数FP两种范式是类似横坐标和纵坐标的两者不同坐标方向的思考方式,类似数据库和对象之间的不匹配阻抗关系,两者如果结合得不好恐怕就不会产生1+1>2的效果。
面向对象是最接近人类思维的方式,而面向函数是最接近计算机的思维方式。如果你想让计算机为人的业务建模服务,那么以OO为主;如果你希望让计算机能自己通过算法从大数据中自动建模,那么以FP为主。所以,Java可能还会在企业工程类软件中占主要市场,而Scala则会在科学计算大数据分析等领域抢占Java市场,比如Scala的Spark大有替代Java的Hadoop之趋势。

3 scala解释器

Scala解释器读到一个表达式,对它进行求值,将它打印出来,接着再继续读下一个表达式。这个过程被称做读取read–求值eval–打印print–循环loop,即:REPL。
从技术上讲,scala程序并不是一个解释器。实际发生的是,你输入的内容被快速地编译成字节码,然后这段字节码交由Java虚拟机执行。正因为如此,大多数scala程序员更倾向于将它称做 REPL。

4 scala变量的定义

​ scala的变量定义分为两种方式,分别需要使用关键字val和var。

- val
  val a = 3
- var
  var a = 3

​ val和var都可以用来定义变量,唯一的区别就在于,val定义的变量是不可变,而var定义的变量是可变的。不可变的量确实类似常量(被final修饰的变量),但不叫常量,只能叫不可变量的量。

​ 在开发过程中,能使用val就使用val,var尽量不用,因为scala编程的特点,是在创建变量的时候可以省略数据类型,val有助于进行类型的推断。var在操作过程中不利于变量的类型推断。
一个完整的变量的定义如下:

val v:Int = 3

其中val为变量修饰符,v为变量名,Int为v的数据类型,其中需要将变量名和数据类型使用:连接,= 右侧为变量的值。

5 scala数据类型

scala支持的数据类型如下:
在这里插入图片描述
说明:
·scala拥有和java一样的数据类型,和java的数据类型的内存布局完全一致,精度也完全一致。需要说明一点的是Any和AnyRef,其中Any是对象的超类(运行时的一个概念,比如 val p = new Person() ,引用p指向的对象有一个父类Any),AnyRef是类的超类(class Person{}, 该类Person有一个隐含的超类AnyRef),实例/对象是类的具体化。

6 scala操作符说明

scala的操作符合java一模一样:略。

  1. 在scala调用一些方法或者函数的时候,如果方法或者函数是空参的,可以省略掉().
  2. 在scala中一行表示的结尾不像java需要使用";",scala可以省略

7 scala的流程控制结构

7.1 if表达式

scala中的if表达式,基本和java中的if表达式一模一样,唯一的区别就是scala中的if、if-else、if-elseif-else有返回值!

       scala> val age = 18
age: Int = 18

scala> if(age > 16) "adult" else "child"
res17: String = adult

scala> val ret = if(age > 16) "adult" else "child"
ret: String = adult

scala> println("ret = " + ret)
ret = adult

scala> var result = ""
result: String = ""

scala> if(age > 16) result = "adult" else result = "child"

scala> println("result= " + result)
result= adult

scala> if(age > 16) "adult" else 123
res21: Any = adult

记住:scala中任意的表达式,都有返回值。
如果else丢失了
if(x>0) 1
那么有可能if语句没有输出值,但是在Scala中,每个表达式都有值,这个问题的解决方案是引入一个Unit类,写作(),不带else语句的if语句等同于if(x>0) 1 else ()

​scala的返回值可以省略return关键字,表达式的最后一句话,作为表达式的返回值返回。return关键字通常使用在函数中进行逻辑的终止,比如循环。

var f = 3
var n = 10
var m = 1
val d = if(n < 18){f = f + n ; m = m +n ; f+m}

===> d=24

注意:前面提到过,scala中的语句终止就是换行,也就是一行一个语句,此时便可以省略";",但是当一行有多条语句的时候,就应该使用";"分隔。在表达式块中同样可以使用换行作为一条语句的分隔。

​如果if循环体{}中只有一条语句,是可以省略{},但是如果大家查看过阿里巴巴编程规范中话,其建议哪怕只有一条语句也写上{},会显得结构很清晰。

7.2 while循环

object whileLoop {
	def main(args: Array[String]): Unit = {
		var sum = 0
		var n = 1
		while(n <= 10) {
			sum += n
			//++/--自增/自减运算符在scala中不支持,因为已经被scala集合的对应函数所占据了
//			n++
			n += 1
		}
		println("sum = " + sum)
	}
}

注意:error: value ++/-- is not a member of Int

scala中不能直接对一个变量执行自增/减,++/–是scala集合的一个函数。

7.3 do while循环

object doWhileLoop {
	def main(args: Array[String]): Unit = {
		var sum = 0
		var n = 1
		do {
			sum += n
			n += 1
		} while (n <= 10)
		println("sum = " + sum)
	}
}

7.4 循环练习

登录用户名密码的游戏:三次机会,从控制台输入用户名密码,如果成功登录,返回登录成功,失败,则反馈错误信息!

object whileLoopTest {
	def main(args: Array[String]): Unit = {
		//从控制台输入使用readLine()已经过时
//		readLine()//StdIn.readLine
		val user = "goodera"
		val passwd = "123456"
		var count = 3
		while(count > 0) {
			count -= 1
			val username = StdIn.readLine("请输入您的用户名:")
			val pwd = StdIn.readLine("请输入您的密码:")
			if (user == username && passwd == pwd) {
				println("欢迎" + username + "登录xxx官网~")
				count = -1
                //return
			} else {
				println("用户名或密码有误,请重试,还有" + count + "次机会~")
			}
		}
	}
}

7.5 循环的终止

在java中终止循环有关键字,continue,break,return,但是在scala中没有前两者continue和break。该如何终止循环呢?

​scala中有三种方式来结束循环:

  1. 使用return语句来控制循环结束
  2. 使用循环结束的条件来进行控制,比如上例中的count >= 0
  3. 还可以使用breakable函数体来进行控制
object whileLoopTest {
	def main(args: Array[String]): Unit = {
		val user = "goodera"
		val passwd = "123456"
		var count = 3

		breakable {
			while(count > 0) {
				count -= 1
				val username = StdIn.readLine("请输入您的用户名:")
				val pwd = StdIn.readLine("请输入您的密码:")
				if (user == username && passwd == pwd) {
					println("欢迎" + username + "登录xxx官网~")
					break
				} else {
					println("用户名或密码有误,请重试,还有" + count + "次机会~")
				}
			}
		}
	}
}

7.6 for循环

​ 在java中有2中写法,普通的for循环for(变量;条件;自增或自减){循环体}和增强型for(类型 变量 : 集合) {}。

​ scala中并没有像java中普通for循环的语法结构,更像是高级for循环。

for (变量 <- 集合) {
}

将上述的while循环使用for循环改写:

/*
	java的for循环
	for(int a = 0初始化①; a < 10条件判断②; a++变量改变③) {
		//循环体
		业务逻辑④
	}
	1->2->4->3->2->4->3...
	高级for循环foreach
	for(类型 变量 : 集合) {
		xxxx
	}
	scala中没有像java中的第一种for循环,scala中的for循环,有点类似java中的高级for循环,
	结构如下:
	for(变量 <- 集合) {

	}
 */
object forLoop {
	def main(args: Array[String]): Unit = {
		/*
			将前面的while循环案例适用for循环实现
			scala中生成一个集合可以使用整型变量 to/until 数字
			会生成一个返回
			to: 1 to 5/1.to(5) 包含
				scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)
			until: 1 until 5/1.until(5) 不包含
				scala.collection.immutable.Range = Range(1, 2, 3, 4)
		 */
		val range = 1.to(10)
		var sum = 0
		for(n <- range) {
			sum += n
		}
		println("sum = " + sum)
	}
}
val range = 1.to(10)
var sum = 0
for(n <- range reverse) {
    println("n=" + n)
}

说明:添加reverse主要就是向进行循环的反转

7.7 循环的嵌套

/*
	循环的嵌套
	打印矩阵
	*****
	*****
	*****
	3行 * 5列
	循环的嵌套中:外循环控制行,内循环控制每一行对应的列
 */
object loopNest {
	def main(args: Array[String]): Unit = {
		for(i <- 1 to 3) {
			for(j <- 1 to 5) {
				print("*")
			}
			println
		}
		println("----------打印一个三角形-------------")
		for(i <- 1 to 5) {
			for(j <- 1 to 5) {
				if(j <= i)
					print("*")
			}
			println
		}
		println("----------改写打印一个三角形-------------")
		for(i <- 1 to 5) {
			for(j <- 1 to i) {
				print("*")
			}
			println
		}
		println("----------改写打印一个三角形-------------")
		for(i <- 1 to 5) {
			for(j <- i to 5) {
				print("*")
			}
			println
		}
		println("----------scala for嵌套写法-------------")
		for(i <- 1 to 5; j <- 1 to i) {
			print("*")
			if(i == j) {
				println
			}
		}
		println("----------scala for嵌套写法-------------")
		for(i <- 1 to 5; j <- 1 to 5; if j <= i) {
			print("*")
			if(i == j) {
				println
			}
		}
	}
}

scala打印9*9乘法口诀表:

object multipTable {
	def main(args: Array[String]): Unit = {
		for(i <- 1 to 9; j <- 1 to 9; if j <= i) {
//			print(j + "*" + i + "=" + (i * j) + "\t")
			print(s"${j}*${i}=${i * j}\t")
			if(i == j) {
				println
			}
		}
	}
}

8 scala异常控制

scala的异常体系,在很大程度上沿用java的异常体系的,只不过在书写结构上略有差异。

/**
  * scala异常控制
  */
object exceptionDemo {
	def main(args: Array[String]): Unit = {
		try {
//			var i = 1 / 0
			//lazy 懒加载 或者延迟加载 被lazy所修饰的变量,之后再第一次被调用的时候才会进行初始化
			lazy val num = Integer.valueOf("abcd")
//			println(num)
//			val file = new FileInputStream("abedefg")
		} catch {
			case e: ArithmeticException => {
				println(e.getMessage)
			}
			case e1: NumberFormatException => {
//				println(e1.getMessage)
				e1.printStackTrace()
			}
			case _:Exception => {//_下划线代表上述没有匹配到的其他的异常
				println("文件找不到")
//				throw new RuntimeException("RuntimeException")
			}
		}
	}
}

上述代码,在执行过程中出现异常:

java.lang.ArithmeticException: / by zero

在java中学习了两种异常的处理方式:throws和try-catch。scala中throws和java中的一模一样,将异常转交给调用者进行处理。try-catch则意味着自己要进行处理,但是编写的方式和java不一样。

case e: ArithmeticException => {
    println(e.getMessage)
}

说明:上面的案例中,更进一步的学习了一个关键字lazy(懒加载),被lazy所修饰的变量,只有当第一次被使用的时候才会进行初始化,没有使用之前只是记录了存在,检查语法结构是否正确。可以节省一定的资源空间。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值