Scala是什么,能做什么?
Scala是一门多范式的编程语言,一种类似java的编程语言 ,设计初衷是实现可伸缩的语言、并集成面向对象编程和函数式编程的各种特性。
目前,Scala 在国外比较火,Twitter 已经将自己全部的代码从 Ruby 转到了Scala。而且还有 Spark、Kafka、akka 这样的开源项目及 Twitter、Linkedin 等公司大力支持,所以本人很看好 Scala 这门语言。
Scala的基础语法
我整理了自己学习过程中感到有必要记录的东西,以防忘记
1. val 与 var
Scala 有两种定义变量的方式:val和var。
当val定义好变量之后,无法更改变量的值。类似于使用了Java的final来修饰变量。
scala> val param = "tony"
param: String = tony
scala> param = "monica"
:12: error: reassignment to val
param = "monica"
^
var定义的变量,可以多次修改变量的值
scala> var param = "tony"
param: String = tony
scala> param = "monica"
param: String = monica
scala> println (param)
monica
有一个建议,Scala 程序员崇尚使用val,不可变对象和没有副作用的方法。
2. 关于for循环
2.1 to关键字
跟Java不同,Scala 的for循环变得很简洁,直接使用to
关键词就可以了
scala> for (i<- 1 to 10) {
| println ("i is " + i)
| }
i is 1
i is 2
i is 3
i is 4
i is 5
i is 6
i is 7
i is 8
i is 9
i is 10
2.2 until关键词
也可以使用until
关键词
scala> for (i<- 1 until 10) {
| println("i is " + i)
| }
i is 1
i is 2
i is 3
i is 4
i is 5
i is 6
i is 7
i is 8
i is 9
可以看出,until和to的不同之处在于不包括最后一个元素。
2.3 遍历集合
读取根目录下所有文件
scala> val files = (new java.io.File(".")).listFiles()
scala> for (file <- files) {
| println(file)
| }
./.android
./.bash_history
./.bash_sessions
./.bashrc
./.CFUserTextEncoding
./.dir_colors
./.DS_Store
./.fonts
./.gdbinit
./.gimp
./.gitconfig
./.gitignore
./.gitignore_global
./.gradle
...
2.4 for循环和if条件语句一起使用
打印1到10,并且过滤出大于5的数字
scala> for (i<- 1 to 10 if i>5) {
| println(i)
| }
6
7
8
9
10
上面的代码,对于Java版本需要这样写
for (int i=1;i++;i<=10) {
if (i>5) {
System.out.println(i)
}
}
所以,在 Scala 的for循环语句中可以使用if语句来做for循环的条件过滤。
而且,for循环中还支持多个if条件,多个if之间需要用“;”来分割。
3. yield的用法
yield 会构造并返回与给定集合相同类型的集合。yield需要配合for循环来使用。
先看yield的用法
for {子句} yield {变量或表达式}
再举一些例子
scala> for (i<- 1 to 10) yield i
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> for (i<- 1 to 10) yield i*2
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
scala> val array = Array(1, 2, 3, 4, 5,6,7,8,9,10)
array: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> for (e<-array) yield e
res4: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> for (e <- array if e > 5) yield e
res5: Array[Int] = Array(6, 7, 8, 9, 10)
当for循环结束后, 会返回所有 yield 的值组成的集合。
再举一个例子,在/Users/tony/文件夹下存放了一个test文本文件。打印出该文本文件中包含Scala的整行内容。
/**
* Created by tony on 2017/2/2.
*/
object YieldDemo {
private val files = (new java.io.File("/Users/tony/")).listFiles
private def fileLines(file: java.io.File) =
scala.io.Source.fromFile(file).getLines.toList
def main(args: Array[String]): Unit = {
val lineLengths =
for {
file <- files
if file.getName.endsWith("test")
line <- fileLines(file)
trimmedLine = line.trim
if trimmedLine.matches(".*Scala.*")
} yield line
lineLengths.foreach(println)
}
}
4. class 与 object的区别
Scala中没有静态修饰符static,在object下的成员全部都是静态的,如果在类中声明了与该类相同的名字的object则该object是该类的“伴生对象”,可以理解把类中的static集中放到了object对象中,伴生对象和类文件必须是同一个源文件,可以用伴生对象做一些初始化的操作。这一点上 Scala 和 Kotlin 有些类似。
而且object不能提供构造器参数,也就是说object必须是无参的。
class的内容实在太大了,未来会单独写一篇笔记。
5. 类中getter/setter 方法
在Java中,通常将字段声明为私有的,然后添加公有的getter和setter方法来提供访问字段的接口。
然而,Scala 对每个字段都提供了getter和setter方法。
先看一个例子
/**
* Created by tony on 2017/2/2.
*/
class User {
var name:String = ""
}
object TestSetterAndGetter {
def main(args:Array[String]): Unit = {
val user = new User()
println ("user.name="+user.name) // 调用方法user.name()
user.name = "tony" // 调用方法user.name_=("tony")
println ("user.name="+user.name)
}
}
在上述例子中,User对象的getter和setter分别叫做name和name_=。
将这个简单的User类编译后,使用javap查看生成的字节码,可以证实这一点。
javap -private User.class
生成如下的Java代码
Compiled from "TestSetterAndGetter.scala"
public class com.safframework.test.User {
private java.lang.String name;
public java.lang.String name();
public void name_$eq(java.lang.String); // =号被翻译成了$eq
public com.safframework.test.User();
}
将上述例子中将User对象name的var改成val会变成什么呢?编译器会提示出错。使用val声明的字段,是只有getter,因为val声明的是不可变的。
总结
Scala 的语法跟 Kotlin 颇有相似之处,我是先学习了 Kotlin 再来学 Scala 的,所以对于 Scala 的语法毫无违和感。在这里,我整理了var、val的区别,for循环的使用,以及类的基础知识。
下一篇,我还是会继续整理 Scala 的基础语法相关内容。如果我有写得不正确的地方,请一定要告诉我。
先前的文章:
Scala学习笔记(一)