使用scala
解释器时,如果中途发现命令输入错误,想退出,可以输入两个“回车”退出当前命令:
scala> val multiline =
|
|
You typed two blank lines. Starting a new command.
使用scala
解释器时,如果中途发现命令输入错误,想退出,可以输入两个“回车”退出当前命令:
scala> val multiline =
|
|
You typed two blank lines. Starting a new command.
本文选自Deeper Look at the Apply Method in Scala:
In Scala, there is a language feature generally referred to as “The Apply Method” that has the following rules:
Any object that has an apply method can be called with the .apply omitted.
Functions are no more than objects.Let’s take a look at an example. Given the following abbreviated definition of class Array, and an instance a,
class Array{
def apply(index:Int) = { …some code to get from the array… }
}val a = new Array(whatever)
Then the following calls are essentially equivalent:
a.apply(7)
a(7)
在scala
中,main
函数必须定义在object
中(Java
中,main
函数必须是class
中的static
方法):
object Hello extends App{
override def main(args: Array[String]): Unit = {
......
}
}
或:
object Hello{
def main(args: Array[String]): Unit = {
......
}
}
其中应用程序的命令行参数通过Array[String]
传给main()
函数。
一言以蔽之,object
相当于Java
中的singleton
,trait
相当于Java
中的interface
。
Scala
语言有以下几个特性:
(1)Scala
代码运行在JVM
上,因此可以利用Java
语言的丰富资源。
(2)Scala
语言是一门“纯面向对象的编程语言(pure object-oriented programming(OOP) language
)”:每个变量都是对象,每个运算符都是方法;
(3)Scala
语言也是一门函数式编程语言(functional programming(FP) language
),因此可以把函数赋给变量。
在Scala
中,用val
声明一个变量是不可改变的(immutable,read-only
),而用var
声明一个变量是可改变的(immutable,read-write
)。同Java
类似,Scala
中许多变量实质上对分配在堆(heap
)上的对象(object
)的引用(reference
),所以可变或不可变指的是引用可不可以指向不同的对象,而并非指引用的对象本身是否可以改变。看下面这个例子:
scala> val array: Array[String] = new Array(5)
array: Array[String] = Array(null, null, null, null, null)
scala> array[0] = "Hello"
<console>:1: error: identifier expected but integer literal found.
array[0] = "Hello"
^
scala> array = new Array(2)
<console>:8: error: reassignment to val
array = new Array(2)
^
array
是一个val
类型变量,array
所指向数组的第一个元素可以改变(array[0] = "Hello"
),但是array
不能指向一个新的数组(array = new Array(2)
)。
这是一个简单的入门Scala
程序(iterate.scala
):
object Iterate {
def main (args: Array[String]) {
args.foreach(s => println(s))
}
}
在程序中,Iterate
被定义成object
。Scala
中object
是singleton
,也就是运行时只能产生一个Iterate
实例。
main
方法只能定义在object
中,传入到main
方法中的命令行参数是一个字符串数组:args: Array[String]
。main
方法可以看成是Java
类的static main
方法,即Iterate
程序的入口函数。
s => println(s)
是一个functional literal
,做的仅仅是打印s
而已。
执行这个程序:
[root@Fedora scala]# scala iterate.scala 1 2
1
2
可以看出打印了命令行参数。
在搭建Scala开发环境一文中可以看到不加任何参数直接运行scala
命令时,会启动REPL(Read,Eval,Print,Loop)
环境,然后就可以在这个环境里交互地执行Scala
代码。本文介绍如何运行Scala
脚本(script
)。
首先创建一个简单的Scala
脚本(hello.scala
):
print("Hello world!\n")
a)直接运行scala hello.scala
:
[root@Fedora scala]# scala hello.scala
Hello world!
b)在REPL
环境用load
命令运行hello.scala
:
[root@Fedora scala]# scala
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.8.0_45).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :load hello.scala
Loading hello.scala...
Hello world!
c)如果想把脚本编译成JVM byte code
(一组*.class
文件),可以使用scalac
程序(命令行选项是-Xscript <object>
,<object>
是“main class
”的名字,也即Java
程序的入口):
[root@Fedora scala]# scalac -Xscript hello hello.scala
[root@Fedora scala]# ls
hello$$anon$1.class hello.class hello$.class hello.scala
[root@Fedora scala]# scala hello
Hello world!
也可以用scalap
这个逆向分析工具分析一下hello.class
:
[root@Fedora scala]# scalap -cp . hello
object hello extends scala.AnyRef {
def this() = { /* compiled code */ }
def main(argv : scala.Array[scala.Predef.String]) : scala.Unit = { /* compiled code */ }
}
Scala
中的=>
符号可以看做是创建函数实例的语法糖。例如:A => T
,A,B => T
表示一个函数的输入参数类型是“A
”,“A,B
”,返回值类型是T
。请看下面这个实例:
scala> val f: Int => String = myInt => "The value of myInt is: " + myInt.toString()
f: Int => String = <function1>
scala> println(f(3))
The value of myInt is: 3
上面例子定义函数f
:输入参数是整数类型,返回值是字符串。
另外,() => T
表示函数输入参数为空,而A => Unit
则表示函数没有返回值。
在网上找到使用Intellij
搭建Scala
开发环境的官方文档,发现老的已经掉牙。索性自己写了一篇:Getting Started with Scala in IntelliJ IDEA 14.1,以给需要的朋友一个参考。