scala和java或.NET都可以协同工作。Scala的主编译器,scalac,会生成在jvm上运行的class文件。然而,另一个编辑器则生成能在.NET CLR上运行的二进制文件。
scala和java代码可以实现互操作;
1. 下载、解压、环境变量;
可以直接把scala当做计算器使用:
res0是系统默认创建的一个临时变量,在后面也可以使用它,res1也是。
4. 定义方法(def)
5. scala脚本
hello.scala,内容是println("Hello, world, from a script!")
运行脚本:
>scala hello.scala
在unix系统中,也可以使用shell来调用此方法
scalatest.sh的内容:
>./scalatest.sh WILL
foreach以及for的使用:
scala没有操作符运算,所有的运算都是转化成对象中对应的方法来执行。例如:
greetStrings(0) = "Hello" 等同于greetStrings .update (0,"Hello")
print(greetString(i)) 等同于 print(greetStrings .apply(i) )
scala架构把所有东西都看做带有方法的对象。只有这些带有方法的对象,没有其他东西。
面向过程的好处:a. 方法与变量可靠、可重用;b. 所有进出方法的对象都要经过严格的类型检查。
这需要这些对象不可变,就像java中的String。在scala中Array本身是不可变的,但是其中的元素可变,所以它也是可变的。鉴于此,一个更加面向过程的、有序的对象就是List了。
创建一个List:val oneTwoThree= List(1, 2, 3)。这里不用new,因为单例scala.List中已经把List定义成了一个工厂方法。由于List是不可变的,所以:::之后的对象是有一个新的List。
还有一个临时向已有List中添加元素的方法:
9. Set和Maps
它们都有可变和不可变的包,使用的类名确实相同的。如:scala.collection.mutable.HashSet,scala.collection.immutable.HashSet
10. 理解类和单例类
要运行上面的入口类,不能仅仅通过scala WorldlyGreeter.scala,因为它以定义一个东西作为类的结束。一般scala默认返回最后一行的值,定义是没有值的。我们必须要编译这些类,并且运行它才行。
scala提供两种编译工具:scalac和fsc。相对于前者,fsc会在第一次连接jvm后建立一个守护线程,以后可以更快速地事先编译。他俩的使用方法相同:fsc WorldlyApp.scalaWorldlyGreeter.scala
执行过程是:
a. 以WorldlyApp的main方法为入口启动jvm;
b. WorldlyApp的main方法用new建立一个Greeter对象,把参数“hello”传进去:
c. Greeter的主构造方法使用“hello”初始化;
d. WorldlyApp将创建的Greeter实例赋值给本地wg;
e. 激发Greeter实例的greet方法;
f. Greeter实例的方法激发单例类Greeter的greet方法;
h. 单例类返回值,一次传递回去
总结:
scala承诺的高效与简洁可见一斑,可以提高java程序员的生成效率。目前,应该可以使用scala完成一些简单的任务,运行scala脚本什么的。
scala和java代码可以实现互操作;
1. 下载、解压、环境变量;
2. 进入shell:
- will@will-vm1:~$ scala
- Welcome to Scala version 2.11.0-RC1 (Java HotSpot(TM) Client VM, Java 1.6.0_45).
- Type in expressions to have them evaluated.
- Type :help for more information.
- scala>
可以直接把scala当做计算器使用:
- scala> 1 + 2
- res0: Int = 3
- scala> res0 * 4
- res1: Int = 12
res0是系统默认创建的一个临时变量,在后面也可以使用它,res1也是。
3. 定义变量(val , var)
- scala> val msg2:java.lang.String = "hello world"
- msg2: String = hello world //对常量的描述
- scala> val msg3:String = "hello world"
- msg3: String = hello world //可以自动识别类型,进行类型推理(type inference)
- scala> msg2 = "dfs" //val相当于final类型,immutable
- <console>:8: error: reassignment to val
- msg2 = "dfs"
- ^
- scala> var msg3:String = "hello world"
- msg3: String = hello world
- scala> msg3 = "hello yet" //var相当于变脸,mutable
- msg3: String = hello yet
4. 定义方法(def)
- scala> def max3(x: Int, y: Int)={if (x>y) x else y} //带参数的方法,返回值类型可以自己识别,不过良好的代码习惯,最好指定def max3(x: Int, y: Int) : Int={if (x>y) x else y},对于递归方法,必须指定!
- /* 参数必须指定类型,貌似scala唯独不会对方法的参数进行类型推理 */
- max3: (x: Int, y: Int)Int //对方法的描述
- scala> max3(234,3)
- res8: Int = 234
- scala> max3(234,334)
- res9: Int = 334
- scala> def greet()={println("hello world")} //无参数的方法
- greet: ()Unit
- scala> greet
- hello world
- scala> greet() //推荐编写习惯
- hello world
hello.scala,内容是println("Hello, world, from a script!")
运行脚本:
>scala hello.scala
在unix系统中,也可以使用shell来调用此方法
scalatest.sh的内容:
- #!/bin/sh
- exec scala $0 $@
- !#
- // Say hello to the first argument
- println("Hello, " + args(0) + "!")
>./scalatest.sh WILL
6. 过程控制
while和if
- var i = 0;
- while (i < args.length) {
- if (i != 0) {
- print(" "); //分号可有可无,良好习惯应该是有
- }
- print(args(i));
- i += 1;
- }
- println();
foreach以及for的使用:
- scala> myNumbers.foreach(x => println(x))
- 1
- 2
- 3
- scala> myNumbers.foreach((x: Int) => println(x))
- 1
- 2
- 3
- scala> myNumbers.foreach(println())
- <console>:9: error: type mismatch;
- found : Unit
- required: Int => ?
- myNumbers.foreach(println())
- ^
- scala> myNumbers.foreach(println) //If an anonymous function consists of one method application that takes a single argument,you need not explicitly name and specify the argument
- 1
- 2
- 3
- scala> myNumbers.foreach((x:Int) => print(cube(x))) //cube是前面自己定义的函数—— defcube(l : Int) : Int = {l*l*l}
- 1827
- scala> myNumbers.foreach((x:Int) => println(cube(x)))
- 1
- 8
- 27
- scala> for (num <- myNumbers) println(num) // <- 等同于 in,后面的block应该用{}包起来最好
- 1
- 2
- 3
7. 指定类型的数组Array
- val greetStrings: Array[String] = new Array<strong>[String]</strong>(3)
- greetStrings(0) = "Hello"
- greetStrings(1) = ", "
- greetStrings(2) = "world!\n"
- for (i <- 0<strong> to</strong> 2) //to 相当于 0.<strong>to(2)</strong> __scala没有操作符运算,所有的运算的都是转化成对象中对应的方法来执行。
- print(greetStrings(i))
greetStrings(0) = "Hello" 等同于greetStrings .update (0,"Hello")
print(greetString(i)) 等同于 print(greetStrings .apply(i) )
scala架构把所有东西都看做带有方法的对象。只有这些带有方法的对象,没有其他东西。
8. Lists和Tuples
- scala> val oneTwo = List(1, 2)
- oneTwo: List[Int] = List(1, 2)
- scala> val threeFour = List(3, 4)
- threeFour: List[Int] = List(3, 4)
- scala> val oneTwoThreeFour = oneTwo ::: threeFour //::: 连接两个List
- oneTwoThreeFour: List[Int] = List(1, 2, 3, 4)
- scala> println(oneTwo + " and" + threeFour + " were not mutated.")
- List(1, 2) and List(3, 4) were not mutated.
- scala> println("Thus, " +oneTwoThreeFour + " is a new List.")
- Thus, List(1, 2, 3, 4) is a new List.
这需要这些对象不可变,就像java中的String。在scala中Array本身是不可变的,但是其中的元素可变,所以它也是可变的。鉴于此,一个更加面向过程的、有序的对象就是List了。
创建一个List:val oneTwoThree= List(1, 2, 3)。这里不用new,因为单例scala.List中已经把List定义成了一个工厂方法。由于List是不可变的,所以:::之后的对象是有一个新的List。
还有一个临时向已有List中添加元素的方法:
- val twoThree = List(2, 3)
- val oneTwoThree = 1 :: twoThree //:: 只能在头部添加新元素
- println(oneTwoThree)
- List(1, 2, 3)
- scala> val one_fouer = oneTwoThree :: 4 //尾部报错
- <console>:9: error: value :: is not a member of Int
- val one_fouer = oneTwoThree :: 4
- ^
- scala> val one_fouer = 4 :: oneTwoThree //头部无恙
- one_fouer: List[Int] = List(4, 1, 2, 3)
- tuples可以包含不同类型的元素,不同于List以及Array。
- scala> val pair =(99, "Luftballons")
- pair: (Int, String) =(99,Luftballons) //类型可以在定义中自动识别,取决于参数
- scala>println(pair._1)
- 99
- scala>println(pair._2)
- Luftballons
9. Set和Maps
它们都有可变和不可变的包,使用的类名确实相同的。如:scala.collection.mutable.HashSet,scala.collection.immutable.HashSet
- importscala.collection.mutable.HashSet
- val jetSet = newHashSet<strong>[String]</strong> //指定类型
- jetSet +="Lear"
- jetSet +=("Boeing", "Airbus")
- println(jetSet.contains("Cessna")) //false
- ----------------------------------------------------------
- importscala.collection.mutable.HashMap
- val treasureMap=new HashMap<strong>[Int, String]</strong>
- treasureMap +=1-> "Go to island." //.+=()
- treasureMap +=2-> "Find big X on ground."
- treasureMap +=3-> "Dig."
- println(treasureMap(2))
- ---------------------------------------------------------------
- // Innumerals.scala有一个Map的工厂方法
- val romanNumeral=Map(1 -> "I", 2 -> "II", 3 -> "III",4-> "IV", 5 -> "V") //默认使用scala.collection.immutable.Map
- println(romanNumeral(4))
10. 理解类和单例类
- classFancyGreeter(greeting: String) { //直接在定义类时指定构造函数的参数
- def this(greeting:String) = this(greeting, 1) //相当于辅助构造函数,也可以在定义时使用,实现多个构造函数的机制
- if (greeting ==null) { //在类的body中进行参数检查,初始化实例时执行
- throw newNullPointerException("greeting was null")
- }
- def greet() = println(greeting)
- }
- val g = newFancyGreeter("Salutations, world")
- g.greet
- <span style="font-family: Arial, Helvetica, sans-serif;">
- </span>
- <span style="font-family: Arial, Helvetica, sans-serif;">scala中没有静态变量或方法,一般使用一个辅助此类的单例类来解决,也是它的同伴</span>
- // TheWorldlyGreeter class
- class <span style="color:#6600cc;">WorldlyGreeter</span>(greeting: String) { //普通类是class
- def greet() = {
- val worldlyGreeting =WorldlyGreeter.worldify(greeting) //直接使用单例类中的方法
- println(worldlyGreeting)
- }
- }
- // TheWorldlyGreeter companion object //合作者
- object <span style="color:#3333ff;">WorldlyGreeter </span>{ //单例类的关键字是object
- def worldify(s: String) = s + ",world!"
- }
- /* 以上的定义必须需要一个主类来跑才行。使用一个单例类中的main方法来作为app的入口,这个类可以称为独行者,因为没有其他类用它
- * 所以,单例类包括独行者和合作者两种
- */
- object WorldlyApp {
- defmain(args: Array[String]) {
- val wg = newWorldlyGreeter("Hello")
- wg.greet()
- }
- }
scala提供两种编译工具:scalac和fsc。相对于前者,fsc会在第一次连接jvm后建立一个守护线程,以后可以更快速地事先编译。他俩的使用方法相同:fsc WorldlyApp.scalaWorldlyGreeter.scala
执行过程是:
a. 以WorldlyApp的main方法为入口启动jvm;
b. WorldlyApp的main方法用new建立一个Greeter对象,把参数“hello”传进去:
c. Greeter的主构造方法使用“hello”初始化;
d. WorldlyApp将创建的Greeter实例赋值给本地wg;
e. 激发Greeter实例的greet方法;
f. Greeter实例的方法激发单例类Greeter的greet方法;
h. 单例类返回值,一次传递回去
11. 理解 trait和mixin
trait,官网说类似于java中的接口,我个人倒感觉更像抽象类,因为它可以有方法体,而且相互之间的继承使用extends。唯一像interface的地方是,可以多继承。
- <strong>trait</strong> Friendly {
- def greet() = "Hi" //可以有方法体
- }
- class Dog <strong>extends </strong>Friendly {
- override def greet() = "Woof"
- }
- class HungryCat <strong>extends </strong>Friendly {
- <strong><span style="color:#cc66cc;">override </span></strong>def greet() = "Meow"
- }
- class HungryDog extends Dog {
- <strong><span style="color:#cc66cc;">override </span></strong>def greet() = "I'd like to eatmy own dog food" //覆盖方法使用override,在def的前面
- }
- <strong>trait</strong> ExclamatoryGreeter <strong>extends </strong>Friendly { //多继承
- <strong><span style="color:#cc66cc;">override </span></strong>def greet() = super.greet() +"!"
- }
- var pet: Friendly =new Dog
- println(pet.greet())
- pet = new HungryCat
- println(pet.greet())
- pet = new HungryDog
- println(pet.greet())
- pet = new Dog <strong>with</strong> ExclamatoryGreeter //会先继承with后面的ExclamatoryGreeter,然后再实现Dog对ExclamatoryGreeter的继承与重写
- println(pet.greet())
- pet = new HungryCat <strong>with</strong> ExclamatoryGreeter
- println(pet.greet())
- pet = new HungryDog <strong>with</strong> ExclamatoryGreeter
- println(pet.greet())
- When you run the friendly.scala script, it will print:
- Woof
- Meow
- I'd like to eat myown dog food
- Woof!
- Meow!
- I'd like to eat myown dog food!
总结:
scala承诺的高效与简洁可见一斑,可以提高java程序员的生成效率。目前,应该可以使用scala完成一些简单的任务,运行scala脚本什么的。