Scala教程
1.Scala基础语法
第一个Scala程序:
交互式模式编程:
调用解释不通过一个脚本文件作为一个参数会显示以下提示:
C:>scala
Welcome to Scala version 2.9.0.1
Typein expressions to have them evaluated.
Type:help for more information.
scala>
键入下列文字的Scala提示符,然后按Enter键:
scala> println("Hello, Scala!");
这将产生以下结果:
Hello,Scala!
脚本模式编程:
让我们来看一个简单的代码,用于打印简单的一句话:Hello, World!
objectHelloWorld{
/* This is my first java program.
* This will print 'Hello World' as the output
*/
def main(args:Array[String]){
println("Hello, world!")// prints Hello World
}
}
让我们来看看如何保存文件,编译并运行该程序。请按照以下的步骤:
1. 打开记事本,并添加上面代码。
2. 将文件保存为:HelloWorld.scala。
3. 打开命令提示符窗口,然后转到保存程序文件的目录。假设它是 C:>
4. 键入“scalac HelloWorld.scala”,然后按回车编译代码。如果代码中没有错误,命令提示符下将自动换到下一行。
5. 上面的命令将在当前目录中生成几个类文件。其中一个名称为HelloWorld.class。这是一个字节码可以运行在Java虚拟机(JVM)。
6. 现在,键入“scala HelloWorld”来运行程序。
7. 可以看到“Hello, World!”打印在窗口上。
C:> scalac HelloWorld.scala
C:> scala HelloWorld
Hello,World!
基础语法
关于Scala程序,这是非常要注意以下几点。
-
区分大小写 - Scala是大小写敏感的,这意味着标识Hello 和 hello在Scala中会有不同的含义。
-
类名 - 对于所有的类名的第一个字母要大写。
如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写。
示例:class MyFirstScalaClass -
方法名称 - 所有的方法名称的第一个字母用小写。
如果若干单词被用于构成方法的名称,则每个单词的第一个字母应大写。
示例:def myMethodName() -
程序文件名 - 程序文件的名称应该与对象名称完全匹配。
保存文件时,应该保存它使用的对象名称(记住Scala是区分大小写),并追加“.scala”为文件扩展名。(如果文件名和对象名称不匹配,程序将无法编译)。
示例: 假设“HelloWorld”是对象的名称。那么该文件应保存为'HelloWorld.scala“ -
def main(args: Array[String]) - Scala程序从main()方法开始处理,这是每一个Scala程序的强制程序入口部分。
Scala修饰符:
所有的Scala的组件需要名称。使用对象,类,变量和方法名被称为标识符。关键字不能用作标识符和标识是区分大小写的。Scala支持以下四种类型标识符:
文字标识符
字母数字标识符开始以字母或下划线,可以使用字母,数字或下划线。“$”字符在Scala中是保留关键字,标识符不能使用。以下是合法的字母标识符:
age, salary, _value, __1_value
以下是非法标识符:
$salary,123abc,-salary
运算符标识
运算符识别符由一个或多个运算符字符。操作字符是可打印的ASCII字符,如+, :, ?, ~ 或#。以下是合法的运算符标识:
+++:::<?>:>
Scala编译器将在内部“轧”操作符标识符使它们成为合法的Java标识符,并嵌入$字符。例如,所述标识符:->将内部表示为$colon$minus$greater。
混合标识符
混合标识符由一个字母数字识别符,随后是一个下划线和运算符标识。以下是合法的混合标识符:
unary_+, myvar_=
在这里,作为一个方法名unary_+定义了一个一元+运算符和myvar_=用来作为方法名称定义了一个赋值运算符。
立即数标识符
一个文字标识是包含在反引号(` . . . `)的任意字符串。以下是合法的文字标识:
`x``<clinit>``yield`
Scala关键字:
下面的列表显示在Scala中的保留字。这些保留关键字不可以被用作常量或变量,或任何其他的标识符名称。
abstract | case | catch | class |
def | do | else | extends |
false | final | finally | for |
forSome | if | implicit | import |
lazy | match | new | null |
object | override | package | private |
protected | return | sealed | super |
this | throw | trait | try |
true | type | val | var |
while | with | yield |
|
- | : | = | => |
<- | <: | <% | >: |
# | @ |
|
|
Scala中的注释
Scala支持单行和多行注释非常类似于Java。多行注释可以嵌套,但必须正确嵌套。可用的任何注释和所有字符都将被Scala编译器忽略。
objectHelloWorld{
/* This is my first java program.
* This will print 'Hello World' as the output
* This is an example of multi-line comments.
*/
def main(args:Array[String]){
// Prints Hello World
// This is also an example of single line comment.
println("Hello, world!")
}
}
空行和空格:
仅包含空格,可能带有注释行,被称为一个空行,并且Scala将会完全忽略它。标记可以通过空格和/或注释分开。
换行符:
Scala是面向行的语言,语句可以用分号(;)结束或换行符。分号在声明的结尾通常是可选的。可以键入一个想要的,如果语句出现其本身在一行。在另一方面,如果写在一行多个语句分号是必需的:
val s ="hello"; println(s)
Scala包:
包是一个代码命名的模块。例如,Lift 实用包net.liftweb.util。包声明是在源文件中的第一个非注释行,如下所示:
package com.liftcode.stuff
Scala的包可以被导入,使他们能够在当前编译范围内被引用。下面的语句是导入scala.xml包的内容:
import scala.xml._
可以导入封装的类和对象,例如,从scala.collection.mutable导入HashMap:
<iframe id="aswift_1" style="left: 0in; position: absolute; top: 0in;" name="aswift_1" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="728" height="15"> </iframe> <iframe id="aswift_2" style="left: 0in; position: absolute; top: 0in;" name="aswift_2" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="728" height="15"> </iframe> import scala.collection.mutable.HashMap
可以从一个单一封装的scala.collection.immutable包导入多个类或对象,例如,TreeMap和TreeSet:
import scala.collection.immutable.{TreeMap,TreeSet}
2. Scala IF...ELSE语句
if 语句:
if 语句包含一个布尔表达式后跟一个或多个语句。
语法:
一个 if 语句的语法:
if(Boolean_expression)
{
// Statements will execute if the Boolean expression is true
}
如果布尔表达式的值为true,那么if语句里面的代码模块将被执行。如果不是这样,第一组码if语句结束后(右大括号后)将被执行。
示例:
object Test {
def main(args: Array[String]) {
var x = 10;
if( x < 20 ){
println("This is if statement");
}
}
}
这将产生以下输出结果:
C:/>scalac Test.scala
C:/>scala Test
This is if statement
C:/>
if...else语句:
if语句可以跟着一个可选的else语句,当 else 块执行时,布尔表达式条件是假的。
语法:
if...else的语法是:
if(Boolean_expression){
//Executes when the Boolean expression is true
}else{
//Executes when the Boolean expression is false
}
示例:
object Test {
def main(args: Array[String]) {
var x = 30;
if( x < 20 ){
println("This is if statement");
}else{
println("This is else statement");
}
}
}
这将产生以下结果:
C:/>scalac Test.scala
C:/>scala Test
This is else statement
C:/>
if...else if...else语句:
if语句可以跟着一个可选的else if ... else语句,这是非常有用的使用 if...else if如果测试各种条件声明。
当使用 if , else if , else 语句有几点要牢记。
-
if可以有零或一个else,它必须跟在else if后面。
-
一个if 可以有零到多个else if,并且它们必须在else之前。
-
一旦一个 else if 匹配成功,剩余的else if或else不会被测试匹配。
语法:
if...else if...else的语法是:
if(Boolean_expression 1){
//Executes when the Boolean expression 1 is true
}else if(Boolean_expression 2){
//Executes when the Boolean expression 2 is true
}else if(Boolean_expression 3){
//Executes when the Boolean expression 3 is true
}else {
//Executes when the none of the above condition is true.
}
示例:
object Test {
def main(args: Array[String]) {
var x = 30;
if( x == 10 ){
println("Value of X is 10");
}else if( x == 20 ){
println("Value of X is 20");
}else if( x == 30 ){
println("Value of X is 30");
}else{
println("This is else statement");
}
}
}
这将产生以下结果:
C:/>scalac Test.scala
C:/>scala Test
Value of X is 30
C:/>
if ... else语句嵌套:
它始终是合法的嵌套 if-else 语句,这意味着可以使用一个 if 或 else if 在另一个if 或 else if 语句中。
语法:
语法嵌套 if...else 如下:
if(Boolean_expression 1){
//Executes when the Boolean expression 1 is true
if(Boolean_expression 2){
//Executes when the Boolean expression 2 is true
}
}
可以嵌套else if...else在if语句中,反之也可以。
3. Scala函数
数是一组一起执行任务的语句。可以将代码放到独立的功能。如何划分你的代码不同功能之间,但在逻辑上,划分通常是让每个函数执行特定的任务。
Scala有函数和方法,我们术语说的方法和函数互换用微小的差别。Scala方法是其中有一个名字,签名,任选一些注释,有的字节码,其中如在Scala中函数是可被分配给一个变量的完整对象类的一部分。换句话说,函数,其被定义为某些对象的一个成员,被称为方法。
函数定义可以出现在在源文件的任何地方,Scala允许嵌套函数的定义,那就是其他函数定义的内部函数定义。需要注意的最重要的一点是,Scala的函数名称可以类似+, ++, ~, &,-, -- , , /, : 等字符。
函数声明:
Scala的函数声明有如下形式:
def functionName ([list of parameters]) : [return type]
如果保留关闭等号和方法体的方法为隐式声明,抽象的封闭类型是抽象本身。
函数定义:
Scala函数定义有如下形式:
def functionName ([list of parameters]) : [return type] = {
function body
return [expr]
}
在这里,返回类型可以是任何有效的scala数据类型,参数列表将是用逗号和参数,返回值类型列表分离变量是可选的。非常类似于Java,一个返回语句可以在函数表达式可用情况下返回一个值。以下是这将增加两个整数并返回的函数:
object add{
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
函数,它不返回任何东西,可以返回这相当于在Java中void,并表示该函数不返回任何单元。Scala中不返回任何东西函数被称为过程。以下是语法
object Hello{
def printMe( ) : Unit = {
println("Hello, Scala!")
}
}
调用函数:
Scala提供了一些语法的变化来调用方法。以下是调用一个方法的标准方法:
functionName( list of parameters )
如果函数被对象的一个实例调用使用,那么使用类似于Java点标记如下:
[instance.]functionName( list of parameters )
object Test {
def main(args: Array[String]) {
println( "Returned Value : " + addInt(5,7) );
}
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
让我们编译和运行上面的程序,这将产生以下结果:
C:/>scalac Test.scala
C:/>scala Test
Returned Value : 12
C:/>
Scala函数是Scala编程的核心,这就是为什么Scala被假定为一个函数式编程语言。以下是Scala程序员理解相关Scala函数的一些重要的概念。
4.字符串的方法
以下是由java.lang.String类中定义,并且可以直接在Scala程序中使用方法列表:
SN | 方法及描述 |
1 | char charAt(int index) |
2 | int compareTo(Object o) |
3 | int compareTo(String anotherString) |
4 | int compareToIgnoreCase(String str) |
5 | String concat(String str) |
6 | boolean contentEquals(StringBuffer sb) |
7 | static String copyValueOf(char[] data) |
8 | static String copyValueOf(char[] data, int offset, int count) |
9 | boolean endsWith(String suffix) |
10 | boolean equals(Object anObject) |
11 | boolean equalsIgnoreCase(String anotherString) |
12 | byte getBytes() |
13 | byte[] getBytes(String charsetName |
14 | void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) |
15 | int hashCode() |
16 | int indexOf(int ch) |
17 | int indexOf(int ch, int fromIndex) |
18 | int indexOf(String str) |
19 | int indexOf(String str, int fromIndex) |
20 | String intern() |
21 | int lastIndexOf(int ch) |
22 | int lastIndexOf(int ch, int fromIndex) |
23 | int lastIndexOf(String str) |
24 | int lastIndexOf(String str, int fromIndex) |
25 | int length() |
26 | boolean matches(String regex) |
27 | boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) |
28 | boolean regionMatches(int toffset, String other, int ooffset, int len) |
29 | String replace(char oldChar, char newChar) |
30 | String replaceAll(String regex, String replacement |
31 | String replaceFirst(String regex, String replacement) |
32 | String[] split(String regex) |
33 | String[] split(String regex, int limit) |
34 | boolean startsWith(String prefix) |
35 | boolean startsWith(String prefix, int toffset) |
36 | CharSequence subSequence(int beginIndex, int endIndex) |
37 | String substring(int beginIndex) |
38 | String substring(int beginIndex, int endIndex) |
39 | char[] toCharArray() |
40 | String toLowerCase() |
41 | String toLowerCase(Locale locale) |
42 | String toString() |
43 | String toUpperCase() |
44 | String toUpperCase(Locale locale) |
45 | String trim() |
46 | static String valueOf(primitive data type x) |
5.Scala集合
Scala有一组丰富的集合库。集合是对事物的容器。这些容器可被测序,线性集像List, Tuple, Option, Map等集合的项目可具有元素的任意数量或有界到零个或一个元素(例如,Option)。
集合可能是严格或懒惰。懒集合有可能不消耗内存,直到他们被访问,就像范围元素。此外,集合可以是可变的(引用的内容可以更改)或不变(一个引用的东西指从未改变)。需要注意的是不可变的集合可能包含可变项。
对于一些问题,可变集合更好地工作,并为不可变集合更好地工作。如果有疑问,最好是先从一个不变的集合,如果需要可变进行更改。
本章给出最常用的集合类型对这些集合的信息和使用最频繁的操作。
SN | 集合使用说明 |
1 | Scala Lists |
2 | Scala Sets |
3 | Scala Maps |
4 | Scala Tuples |
5 | Scala Options |
6 | Scala Iterators |
6.Scala文件I/O
Scala打开文件是利用Java对象和java.io.File,它们都可在Scala编程中用来读取和写入文件。以下是写入文件的一个例子:
import java.io._
objectTest{
def main(args:Array[String]){
val writer =newPrintWriter(newFile("test.txt"))
writer.write("Hello Scala")
writer.close()
}
}
当上面的代码被编译和执行,它会创建一个有“Hello Scala”内容的文件。
C:/>scalac Test.scala
C:/>scala Test
C:/>
从屏幕读取一行:
有时需要从屏幕上读取用户输入,然后进行某些进一步的处理。下面的例子说明了如何从屏幕上读取输入:
objectTest{
def main(args:Array[String]){
print("Please enter your input : ")
val line =Console.readLine
println("Thanks, you just typed: "+ line)
}
}
当上面的代码被编译和执行,它会提示输入内容,并继续进行,直到按ENTER(回车)键。
C:/>scalac Test.scala
C:/>scala Test
scala Test
Please enter your input :Scalais great
Thanks, you just typed:Scalais great
C:/>
读取文件内容:
从文件中读取是非常简单的。可以使用Scala的Source 类和它配套对象读取文件。以下是这些显示如何从之前创建“test.txt”文件中读取内容的示例:
import scala.io.Source
objectTest{
def main(args:Array[String]){
println("Following is the content read:")
Source.fromFile("test.txt").foreach{
}
}
}
当上述代码被编译和执行时,它将读取test.txt文件并在屏幕上显示内容:
C:/>scalac Test.scala
C:/>scala Test
scala Test
Followingis the content read:
HelloScala
C:/>