1)scala的安装:
Linux下:
解压文件,将其移动至/usr/local/share下:
mv scala-2.11.7 scala # 重命名 Scala 目录
mv /download/scalapath /usr/local/share # 下载目录需要按你实际的下载路径
配置环境变量:
sudo vim /etc/profile
在文件的末尾加入:
export PATH="$PATH:/usr/local/share/scala/bin"
:wq!保存退出,重启终端,执行 scala 命令,测试是否安装成功。
windows下:
配置环境变量:
变量名:SCALA_HOME 变量值:scala的安装目录
变量名:Path 变量值:%SCALA_HOME%\bin;%SCALA_HOME%\jre\bin; (放到Path的最前面)
变量名:ClassPath 变量值:.;%SCALA_HOME%\bin;%SCALA_HOME%\lib\dt.jar;%SCALA_HOME%\lib\tools.jar;
2)scala变量的声明:
使用关键词var声明变量:
var myVar : Int;
var myVar : String = "Foo";
使用关键词val声明常量:
val myVal : String;
val myVal : String = "Foo";
1)变量可以修改,常量不可以修改。
2)变量的类型在变量名之后等号之前声明。
3)如果没有指定变量的数据类型,则可以通过变量或常量的初始值来推断其数据类型。因此,在没有指明数据类型的情况下声明变量或常量时必须要进行初始化,否则将会报错。
eg:
var myVar = 10;
val myVal = "Hello, Scala!";
4)声明多个变量:
eg:
val xmax, ymax = 100; // xmax, ymax都声明为100
val (myVar1, myVar2) = Pair(40, "Foo");
3)scala函数的声明:
函数的声明:
def functionName ([参数列表]) : [return type]
注意:
1)如果没有写等于号和方法主体,那么声明的该方法会被隐式声明为抽象(abstract)函数。
2)Scala编译器无法推断出函数参数的类型,故必须显示地标明参数的类型。
函数的定义:
def functionName ([参数列表]) : [return type] = {
// do something..
return [expr]
}
举例:
def addInt(a:Int, b:Int) : Int = {
var sum:Int = 0;
sum = a + b;
return sum;
}
def printMe() : Unit = { // 函数没有返回值时,函数的返回值类型设为Unit(相当于java中的void)
println("Hello, Scala!")
}
4)scala数组的声明:
要点:Scala 语言中提供的数组是用来存储固定大小的同类型元素。
格式:var myArray:Array[String] = new Array[String](3); 或 var myArray = new Array[String](3); 或 var myArray = Array("alibaba", "Baidu", "Google");
最简单的scala for语句
for(i <- 1 to 10) {
println("i is " + i);
1 to 10
表示:在1到10间(包含1和10)循环
说明:本质上是一个方法,这个方法返回的是一个Range类型,它等价于:(1).to(10)
注:在scala中一切皆对象,因此,这里的1就是一个对象,它有一个to方法,返回一个Range。
举例:
object Test {
def main(args: Array[String]) {
var myList = Array(1.9, 2.9, 3.4, 3.5)
// 输出所有数组元素
for ( x <- myList ) {
println( x )
}
// 查找数组中的最大元素
var max = myList(0);
for ( i <- 0 to (myList.length - 1) ) {
if (myList(i) > max) max = myList(i);
}
println("最大值为 " + max);
}
}
5)scala访问修饰符:
private:
比Java中的private更严格;
private修饰的成员(方法或变量)只能在定义它的类或对象中使用。
protected:
比Java中的protected更严格;
protected修饰的成员只能在定义了该成员的类的子类中使用。
public:
如果没有指定任何的修饰符,则默认为public。
public修饰的成员在任何地方都可以被访问。
6)内部类:
内部类中的方法或变量只能在内部类中调用。
7)作用域保护:
格式:修饰符[]
例子:private[X] 成员名
说明:
1)这里的X指代某个所属的包、类或单例对象
2)作用:被private[X]标记的成员,只对X范围中的类可见,对其它的类都是private。
举例:
package bobsrocckets{
package navigation{
private[bobsrockets] class Navigator{
protected[navigation] def useStarChart(){}
class LegOfJourney{
private[Navigator] val distance = 100
}
private[this] var speed = 200
}
}
package launch{
import navigation._
object Vehicle{
private[launch] val guide = new Navigator
}
}
}
说明:
类Navigator被标记为private[bobsrockets]就是说这个类对包含在bobsrockets包里的所有的类和对象可见。
eg:从Vehicle对象里对Navigator的访问是被允许的,因为对象Vehicle包含在包launch中,而launch包在bobsrockets中,相反,所有在包bobsrockets之外的代码都不能访问类Navigator。
8)Scala中的匿名函数:
格式:(x, y) => {}
说明:箭头左边是参数列表,右边是函数体,参数的类型可以省略。
例子:
var addOne = (x:Int) => x+1
9)scala中的闭包:
概念:闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
例子:
var factor = 3;
val multiplier = (i:Int) => i * factor;
说明:匿名函数multiplier引用了函数外部定义的变量(factor),故这个匿名函数是一个闭包。
10)scala中的类:
说明:
1)Scala中的类不声明为public,一个Scala源文件中可以有多个类。
2)Scala中的类定义可以有参数,称为类参数。例如下面的 xc, yc,类参数在整个类中都可以访问。
3)使用new关键字来来实例化类,并访问类中的方法和变量。
4)Scala中没有static关键字。
5)Scala中的单例对象:
1>Scala中使用单例模式时,除了定义的类之外,还要定义一个同名的object对象。
注意:object对象不能带参数。
2>当单例对象与某个类共享同一个名称时,这个单例对象被称作是这个类的伴生对象(companion object)。
注意:必须在同一个源文件里定义类和它的伴生对象。
3>类被称为这个单例对象的伴生类(companion class)。
注意:类和它的伴生对象可以互相访问其私有成员。
定义一个类:
class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点: " + x);
println ("y 的坐标点: " + y);
}
}
例子:
// 伴生类 说明:这里的类构造方法是私有的
class Marker private(val color:String) {
println("创建" + this)
override def toString(): String = "颜色标记:"+ color
}
// 伴生对象:与类共享名字,可以访问类的私有属性和方法
object Marker{
private val markers: Map[String, Marker] = Map(
"red" -> new Marker("red"),
"blue" -> new Marker("blue"),
"green" -> new Marker("green")
)
def apply(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def getMarker(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def main(args: Array[String]) {
println(Marker("red"))
// 单例函数调用,省略了.(点)符号
println(Marker getMarker "blue")
}
}
执行以上代码,输出结果为:
$ scalac Marker.scala
$ scala Marker
创建颜色标记:red
创建颜色标记:blue
创建颜色标记:green
颜色标记:red
颜色标记:blue
11)Scala中的继承
概念:Scala使用extends关键字来继承一个类:
说明:
1)重写一个非抽象方法必须使用override修饰符。
2)只有主构造函数才可以往基类的构造函数里写参数。
3)在子类中重写超类的抽象方法时,你不需要使用override关键字。
4)继承会继承父类的所有属性和方法,Scala只允许继承一个父类。
例子:
import java.io._
class Point(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
}
}
class Location(override val xc: Int, override val yc: Int,
val zc :Int) extends Point(xc, yc){
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
println ("z 的坐标点 : " + z);
}
}
object Test {
def main(args: Array[String]) {
val loc = new Location(10, 20, 15);
// 移到一个新的位置
loc.move(10, 10, 5);
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
x 的坐标点 : 20
y 的坐标点 : 30
z 的坐标点 : 20
注意:Scala重写一个非抽象方法,必须用override修饰符。
例子:
class Person {
var name = ""
override def toString = getClass.getName + "[name=" + name + "]"
}
class Employee extends Person {
var salary = 0.0
override def toString = super.toString + "[salary=" + salary + "]"
}
object Test extends App {
val fred = new Employee
fred.name = "Fred"
fred.salary = 50000
println(fred)
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
Employee[name=Fred][salary=50000.0]
12)scala中的特征(trait):
概念:类似于java中的抽象类,可以定义属性和方法的实现。
说明:
1)特征也可以有构造器。
2)特征构造顺序:
构造器的执行顺序:
调用超类的构造器;
特征构造器在超类构造器之后、类构造器之前执行;
特质由左到右被构造;
每个特征当中,父特质先被构造;
如果多个特征共有一个父特质,父特质不会被重复构造
所有特征被构造完毕,子类被构造。
13)Scala中的异常处理:
抛出异常:Scala 抛出异常的方法和 Java一样,使用 throw 方法
在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码里,是一系列case字句:
例如:
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
object Test {
def main(args: Array[String]) {
try {
val f = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException =>{
println("Missing file exception")
}
case ex: IOException => {
println("IO Exception")
}
}
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
Missing file exception
14)Scala中的模式匹配
例子:
object Test {
def main(args: Array[String]) {
println(matchTest("two"))
println(matchTest("test"))
println(matchTest(1))
println(matchTest(6))
}
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
case _ => "many"
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
2
many
one
scala.Int
说明:
第一个 case 对应整型数值 1,
第二个 case 对应字符串值 two,第二个 case 对应字符串值 two,
第三个 case 对应类型模式,用于判断传入的值是否为整型,相比使用isInstanceOf来判断类型,使用模式匹配更好。
第四个 case 表示默认的全匹配备选项,即没有找到其他匹配时的匹配项,类似 switch 中的 default。
注意:
1)match 对应 Java 里的 switch,但是写在选择器表达式之后。即: 选择器 match {备选项}。
2)match 表达式通过以代码编写的先后次序尝试每个模式来完成计算,只要发现有一个匹配的case,剩下的case不会继续匹配。
15)Scala中的正则表达式
说明:
1)Scala 的正则表达式继承了 Java 的语法规则,Java 则大部分使用了 Perl 语言的规则。
2)Scala 通过 scala.util.matching 包种的 Regex 类来支持正则表达式。
例子:
import scala.util.matching.Regex
object Test {
def main(args: Array[String]) {
val pattern = "Scala".r
val str = "Scala is Scalable and cool"
println(pattern findFirstIn str)
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
Some(Scala)
说明:
实例中使用 String 类的 r() 方法构造了一个Regex对象。
然后使用 findFirstIn 方法找到首个匹配项。
如果需要查看所有的匹配项可以使用 findAllIn 方法。
你可以使用 mkString( ) 方法来连接正则表达式匹配结果的字符串,并可以使用管道(|)来设置不同的模式:
例子:
import scala.util.matching.Regex
object Test {
def main(args: Array[String]) {
val pattern = new Regex("(S|s)cala") // 首字母可以是大写 S 或小写 s
val str = "Scala is scalable and cool"
println((pattern findAllIn str).mkString(",")) // 使用逗号 , 连接返回结果
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
Scala,scala
如果你需要将匹配的文本替换为指定的关键词,可以使用 replaceFirstIn( ) 方法来替换第一个匹配项,使用 replaceAllIn( ) 方法替换所有匹配项,实例如下:
object Test {
def main(args: Array[String]) {
val pattern = "(S|s)cala".r
val str = "Scala is scalable and cool"
println(pattern replaceFirstIn(str, "Java"))
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
Java is scalable and cool
16)Scala中的提取器(Extractor)
概念:提取器是从传递给它的对象中提取出构造该对象的参数。
说明;Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。
提取器使用模式匹配
在我们实例化一个类的时,可以带上0个或者多个的参数,编译器在实例化的时会调用 apply 方法。我们可以在类和对象中都定义 apply 方法。
就像我们之前提到过的,unapply 用于提取我们指定查找的值,它与 apply 的操作相反。 当我们在提取器对象中使用 match 语句是,unapply 将自动执行,如下所示:
17)Scala中的文件 I/O
说明:Scala 进行文件写操作,直接用的都是 java中 的 I/O 类 (java.io.File):
例子:
import java.io._
object Test {
def main(args: Array[String]) {
val writer = new PrintWriter(new File("test.txt" ))
writer.write("hello world")
writer.close()
}
}
执行以上代码,会在你的当前目录下生产一个 test.txt 文件,文件内容为"菜鸟教程":
$ scalac Test.scala
$ scala Test
$ cat test.txt
hello world
从屏幕上读取用户输入:
有时候我们需要接收用户在屏幕输入的指令来处理程序。实例如下:
object Test {
def main(args: Array[String]) {
print("请输入: " )
val line = Console.readLine
println("谢谢,你输入的是: " + line)
}
}
执行以上代码,屏幕上会显示如下信息:
$ scalac Test.scala
$ scala Test
请输入: hello world
谢谢,你输入的是: hello world
读取文件内容:
使用 Scala 的 Source 类及伴生对象来读取文件。以下实例演示了从 "test.txt"文件中读取内容:
例子:
import scala.io.Source
object Test {
def main(args: Array[String]) {
println("文件内容为:" )
Source.fromFile("test.txt" ).foreach{
print
}
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
文件内容为:
test.txt文件中的内容
几点注意:
1)scala中没有i++和++i,只有 i = i + 1; 或 i += 1;
Scala基础
最新推荐文章于 2021-11-22 15:38:18 发布