整个文章围绕着对一段代码进行重构的目的,在逐步的把scala的一些语言知识娓娓道来,很有意思,下面记录一下整个重构过程
step1
// code-examples/IntroducingScala/upper1-script.scala
class Upper {
def upper(strings: String*): Seq[String] = {
strings.map((s:String) => s.toUpperCase())
}
}
val up = new Upper
Console.println(up.upper("A", "First", "Scala", "Program"))
* scala的注释风格和java一致
如果把上面的代码保存到upper10script.scala的文件中,然后执行
scala upper1-script.scala
文件会被编译,同时进行解释,得到如下结果
Array(A, FIRST, SCALA, PROGRAM)
* 如果在REPL中敲入代码,那么会立刻执行。
* 如果保存在一个文件中,然后用scala xxx.scala的方式的话,会先编译,然后运行
* 如果保存在一个文件中,可以先编译,然后得到class文件,然后运行
* 函数不需要显示的return,当然如果在一个程序中间需要return结果的话,就只好用return了。
为什么声明变量时把变量类型放在后面的,如 item:type, 因为这种情况下,编译器更容易分析,毕竟可以不写type
为什么scala中范型使用的是[],而不是<> ? 因为可以命名名称为< 的方法,为了避免二义性,不能使用 <>来做范型。
为什么方法的主体跟在等于号=后面呢,而不用{}呢?因为大伙好,参数列表,返回类型经常被省略,如果使用{},容易产生二义性,同时使用=,更加表明函数也是一种值。
Step2
// code-examples/IntroducingScala/upper2-script.scala
object Upper {
def upper(strings: String*) = strings.map(_.toUpperCase())
}
println(Upper.upper("A", "First", "Scala", "Program"))
This code does exactly the same thing, but with a third fewer characters.
代码变的更加简洁
* object,相当于一种单例模式,提供相当于static的静态变量,但是scala本身不支持static,因为在java中static本身并不绑定到任何object中,而scala中通过这种方式把一些静态信息绑定到object中,更加面向对象。
*_, 占位符
* Upper.upper(),这里因为Upper不是一个类,所以不需要new,而且这种写法很想java中静态方法的调用
Step3
// code-examples/IntroducingScala/upper3.scala
object Upper {
def main(args: Array[String]) = {
args.map(_.toUpperCase()).foreach(printf("%s ",_))
println("")
}
}
代码更加简洁了
* 现在upper 方法被重命名为main。因为Upper 是一个object,这个main 方法就像Java 类里的static main 方法一样。这个Upper 程序的入口。
在Scala,main 必须是一个object 的函数。(在Java,main 必须是一个类的静态方法。)命令行参数会作为一个字符串数组被传入应用程序,比如
args: Array[String]。