项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步
看到有资料是如此介绍scala的:有python一样的开发效率,还有java一样的运行性能。看到这个介绍,本宝宝非常好奇,scala到底是怎样做到的。so,开始我们的scala之旅吧!
1.scala环境的配置安装
在之前的文章已经提到过,http://blog.csdn.net/bitcarmanlee/article/details/51302630,具体就不在啰嗦了,需要配置环境的同学们请参考之前文章。
2.运行第一个scala程序
对于java程序来说,都有一个main函数入口。而且在真实的生产环境中,java代码要么放在一个容器中(比如最流行的tomcat),要么打成一个jar包然后用脚本去执行(比如mr相关的代码)。但是scala比较奇葩,因为他是编译型语言,所以支持java那样类似的运行方式。但是他又带有解释器,所以他也可以像python或者shell那样,将代码保存到一个脚本文件中去执行。
vim t1.scala
#!/usr/bin/env scala
println("Hello World!")
直接./t1.scala运行上面的代码,会输出"Hello World!"
也可以这样
vim t2.scala
#!/bin/bash
exec scala "$0" "$@"
!#
println("hello, " + args(0) + "!")
执行./t2.scala 小明
,会输出:
hello, 小明!
3.基本数据类型
Scala一共提供了9中数据类型,Scala的基本数据类型与java中的基本数据类型是一一对应的,这是Scala的数据类型全是类,并且头字母大写。唯一跟java不一样的地方在于,String也是基本类型的一种。
scala里的变量不需要显示指定类型,但是需要提前声明。Scala有一个很强大的类型自动推导功能,它可以根据右值及上下文自动推导出变量的类型。这一点很python很类似,python是由解释器完成这个工作。
如果没有特别的说明,下面的测试代码都是在eclipse里的worksheet完成的。
object demo {
val two = 1 + 1 //> two : Int = 2
val d = 1.2 //> d : Double = 1.2
val str = "18 " + "years old" //> str : String = 18 years old
val flag = true //> flag : Boolean = true
}
上面的val,表示是一个常量,定义以后无法修改,与java里的final类似。经常在函数式编程的相关资料里提到不可变性(immutable),可惜暂时实践经验还不太够,理解不够深刻。
与val对应的是var了。var就是我们常见的变量,是可以改变的对象。请看下面的简单例子:
var name = "james" //> name : String = james
name = "kobe"
如果将var改为val,后面那行会报错。
4.字符串相关
在任何一门编程语言中,字符串相关的操作都是大头。我们来看看scala中的字符串相关操作:
如果使用’'将字符包裹起来,那么这是一个字符:
var char = 'A' //> char : Char = A
char = '1'
如果用""包裹,则是字符串:
var helloWorld = "Hello World" //> helloWorld : String = Hello World
//要定义"Hello World",需要加上转义符
val helloWorldDoubleQuote = "\"Hello World\"" //> helloWorldDoubleQuote : String = "Hello World"
//如果希望能够原样输出字符串总的内容,则用三个引号"""将字符包裹
println(""" hello cruel world, \n \\\ \b \\, I an""")
//> hello cruel world, \n \\\ \b \\, I an
var chineseStr = "小明" //> chineseStr : String = 小明
println(chineseStr) //> 小明
Scala基于JVM平台,默认使用unicode,所以变量名是可以直接用中文的。而在Scala中,中文也是直接显示的,不像Python2一样会输出成unicdoe编码形式:\uxxxx。
5.基本类型的操作
scala中一切皆对象,所以scala中的一切操作都是对象的方法,包括最基本的算术操作。
var sumNum = 1 + 2 //> sumNum : Int = 3
var sumOther = (1).+(2) //> sumOther : Int = 3
上面两行代码的意思是一致的。Scala中的运算符其实是定义在对象上的方法(函数),所以1+2,其实执行的是(1).+(2)。当然,在不会引发歧义的情况下,小括号以及’.'是可以省略的,最后的结果也是一致的。
scala中的加减乘除以及求模等运算,与java是一致的。不再累赘了。
6.关系运算符
3 > -3 //> res0: Boolean(true) = true
3 < -3 //> res1: Boolean(false) = false
3 <= -3 //> res2: Boolean(false) = false
3 <= 3 //> res3: Boolean(true) = true
!(3<= -3) //> res4: Boolean = true
7.逻辑运算符
//逻辑与:&&
flag && true //> res5: Boolean = true
//逻辑或:||
flag || false //> res6: Boolean = true
//逻辑非:!
!flag //> res7: Boolean = false
8.位运算
// 00000001 1
// 00000010 2
// 00000011 3
//按位与
1 & 2 //> res8: Int(0) = 0
//按位或
1 | 2 //> res9: Int(3) = 3
//按位亦或
1 ^ 3 //> res10: Int(2) = 2
//按位取反
~1 //> res11: Int = -2
//左移
4 << 1 //> res12: Int(8) = 8
//右移
4 >> 1 //> res13: Int(2) = 2
9.对象比较
//基本类型比较
1 == 2 //> res8: Boolean(false) = false
1 != 2 //> res9: Boolean(true) = true
2 == 2 //> res10: Boolean(true) = true
//对象比较
List(1,2) == List(1,2) //> res11: Boolean = true
//不同类型比较
1 == 1.0 //> res12: Boolean(true) = true
//null值比较
null == List(1,2,3) //> res13: Boolean = false
Scala的与Java的有所区别。Java 里的既可以比较基本类型也可以比较引用类型。对于基本类型,Java 的比较值是否比较,与Scala相同。然而对于引用类型,Java 的==比较了引用的是否为同一个对象(比较内存址),也就是说这两个变量是否都指向于JVM 堆里的同一个对象。Scala 也提供了这种机制,名字是 eq。不过,eq和它的反义词ne,仅仅应用于 可以直接映射到Java的对象。
10.控制语句
Scala中支持if、while、for comprehension(for表达式)、match case(模式匹配)四大主要控制语句。Scala不支持switch和? :两种控制语句,但它的if和match case会有更好的实现。
if语句应该是所有编程语言中都实现了的最基本的控制语句。先看最简单的例子:
if("abc" == "abc") true else false //> res8: Boolean = true
if("abc" == "abc") 1 else 0 //> res9: Int = 1
if("abc" == "abc") 1 else false //> res10: AnyVal = 1
if("abc" == "ab") 1 //> res11: AnyVal = ()
需要注意的几个小点:
1.从上面的例子很容易看出,if表达式即使没有使用return语句,也是有返回值的。因为scala是函数式语言,函数式语言的一个特点就是表达式,函数式语言中所有语句都是基于“表达式”的,而“表达式”的一个特性就是它会有一个值。
2.上面的第三句,返回的两个类型不同。这个时候表达式的类型是AnyVal。
3.上面的最后一句,else表达式缺失,这个时候if语句没有输出值。但因为函数式编程的特点是每个表达式都有值,那怎么办了?为了解决这个问题,Scala提供了一个Unit类,写作()。最后一句其实等价于:if(“abc” == “ab”) 1 else ()
for语句简单实例:
for(i <- 1 to 3) println("num is: " + i) //> num is: 1
//| num is: 2
//| num is: 3
for(i <- 1 until 3) println("num is: " + i)
//> num is: 1
//| num is: 2
如果是to,则是包含末尾的数字;如果是until,则不包含末尾数字。
双层for循环:
for(i <-1 to 3; j <- 1 to 3) print((i*j) + " ")
//> 1 2 3 2 4 6 3 6 9
println() //>
还可以在for里加if条件
for(i <-1 to 3; j <- 1 to 3 if i==j) print((i*j) + " ")
//> 1 4 9
println() //>
match语句看上去好像相当强大,以后有时间了再慢慢琢磨。
11.集合与函数
这两部分内容在任何一门编程语言中都是重头戏。后续等研究深入一点之后再添加相关内容。