Scala入门笔记

Scala入门

Scala简介

ps:在最新的薪资调查中,Scala程序员的工资是平均最高的Scala工资。 Scala是一门多范式的编程语言,一种类似java的编程语言,设计初衷是实现可伸缩的语言 、并集成面向对象编程和函数式编程的各种特性。Scala的官网地址为:http://www.Scala-lang.org/ Scala有几项关键特性表明了它的面向对象的本质。例如,Scala中的每个值都是一个对象,包括基本数据类型(即布尔值、数字等)在内,连函数也是对象。另外,类可以被子类化,而且Scala还提供了基于mixin的组合(mixin-based composition)。与只支持单继承的语言相比,Scala具有更广泛意义上的类重用。Scala还包含了若干函数式语言的关键概念,包括高阶函数(Higher-Order Function)、局部套用(Currying)、嵌套函数(Nested Function)、序列解读(Sequence Comprehensions)等等。

Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。它也能运行于Java ME, CLDC(Java Platform, Micro Edition Connected Limited Device Configuration)上。还有另一.NET平台的实现,不过该版本更新有些滞后。Scala的编译模型(独立编译,动态类加载)与Java和C#一样,所以Scala代码可以调用Java类库(对于.NET实现则可调用.NET类库)。Scala包中包含了编译器和类库,以BSD许可证发布。

Scala发展历史

  1. 联邦理工学院洛桑(EPFL)的Martin Odersky于2001年基于Funnel的工作开始设计Scala。Funnel是把函数式编程思想和Petri网相结合的一种编程语言。Odersky先前的工作是Generic Java和javac(Sun Java编译器)。Java平台的Scala于2003年底/2004年初发布。.NET平台的Scala发布于2004年6月。该语言第二个版本,v2.0,发布于2006年3月。
  2. 截至2009年9月,最新版本是版本2.7.6。Scala 2.8预计的特性包括重写的Scala类库(Scala collections library)、方法的命名参数和默认参数、包对象(package object),以及Continuation.
  3. 2009年4月,Twitter宣布他们已经把大部分后端程序从Ruby迁移到Scala,其余部分也打算要迁移。此外,Wattzon已经公开宣称,其整个平台都已经是基于Scala基础设施编写的。

Scale语言特点

快速实验: Scala有交互式命令行(REPL),可以在上面快速的试各种语法和代码。这对学习新特性,或者实验新想法非常有用。

一致性: 尽管Scala融合了静态类型系统、面向对象、函数式编程等语言特性,但却很少能看出融合的痕迹。Scala是我见到融合最多语言特性而又不显得杂乱的编程语言之一。

类型安全: Scala创始人是教授,他先带领创建了java 5编译器,而后觉得Java有太多羁绊而发明了Scala。Scala编译器和类型系统非常强大,它的目标是尽量把软件错误消灭在编写过程中。Scala类型系统是图灵完备的,甚至可以在编译期间解决问题。

面向对象: Scala是面向对象的编程语言,所有的变量和方法都封装在对象中,可以把信息封装起来供外部使用。

函数式编程: Scala同时又是函数式编程语言,函数可以独立存在,可以定义一个函数作为另一个函数的返回值,也可以接受函数作为函数的参数。这给组合函数带来了很大的便利。如何把面向对象编程形容成搭积木的话,函数式编程就像拼线条,更灵活和更有创意。

异步编程: 由于函数式编程提倡变量不可变,使异步编程变得非常容易。同时Scala提供的Future,和akka类库,使得异步编程变得非常容易。

基于JVM: Scala会被编译成为jvm bytecode,所以Scala能无缝集成已有的Java类库。你可以非常自然的使用已经存在的非常庞大且稳定的Java类库,比如小巧好用的apache.common.*,或者Java上的各种工具类库。

静态类型: Scala是具备类型系统,通过编译时的检查,保证代码的安全性和一致性。类型系统具体支持以下特性:泛型类,型变注释(Variance Annotation),类型继承结构的上限和下限,把类别和抽象类型作为对象成员,复合类型,引用自己时显式指定类型,视图,多态方法。

扩展性: Scala的设计承认一个事实,即在实践中,某个领域特定的应用程序开发往往需要特定于该领域的语言扩展。Scala提供了许多独特的语言机制,可以以库的形式轻易无缝添加新的语言结构:任何方法可用作前缀或后缀操作符,可以根据预期类型自动构造闭包。联合使用以上两个特性,使你可以定义新的语句而无须扩展语法也无须使用宏之类的元编程特性。

其他特定:更高层的并发模型Actor、轻量级的函数语法、高阶、嵌套、局部套用(Currying)、与Java无缝地互操作

因为如此众多特性,用Scala可以优雅地编写简洁的代码,同时又能减少很多低级错误;能快速进行开发,又能保证系统性能、团队协作和长期维护。Scala的风格和特性已经吸引了大量的开发者。总而言之,Scala是一种函数式面向对象语言,它融汇了许多前所未有的特性,而同时又运行于JVM之上。随着开发者对Scala的兴趣日增,以及越来越多的工具支持,无疑Scala语言将成为你手上一件必不可少的工具。

Scala语法

构造函数

构造函数不是特殊的方法,他们是除了类的方法定义之外的代码。

class MyClass(x: Int, y: Int) {           // Defines a new type MyClass with a constructor  
  require(y > 0, "y must be positive")    // precondition, triggering an IllegalArgumentException if not met  
  def this (x: Int) = { ... }             // auxiliary constructor   
  def nb1 = x                             // public method computed every time it is called  
  def nb2 = y  
  private def test(a: Int): Int = { ... } // private method  
  val nb3 = x + y                         // computed only once  
  override def toString =                 // overridden method  
      member1 + ", " + member2 
  }

new MyClass(1, 2) // creates a new object of type

继承

继承和Java的语法类似。

abstract class TopLevel {     // abstract class  
  def method1(x: Int): Int   // abstract method  
  def method2(x: Int): Int = { ... }  
}

class Level1 extends TopLevel {  
  def method1(x: Int): Int = { ... }  
  override def method2(x: Int): Int = { ...} // TopLevel's method2 needs to be explicitly overridden  
}

object MyObject extends TopLevel { ... } // defines a singleton object. No other instance can be created

变量

Scala 定义了两种类型的变量val和var,val类似于Java中的final变量,一旦初始化之后,不可以重新赋值。而var类似于一般的非final变量,可以任意重新赋值。 例如,定义一个字符串常变量:

scala> val msg="Hello,World"
msg:String= Hello,World

可以看到我们在定义这个变量时并不需要像Java一样定义其类型,Scala 可以根据赋值的内容推算出变量的类型。此外Scala语句也不需要以分号结尾。 如果在命令行中需要分多行输入,Scala解释器在新行前面显示|,表示该行接着上一行。例如,上面的代码可以改为:

scala> val msg3=    

           |"Hello world 3rd time"

msg3:String= Hello world 3rd time

类型

scala类型系统以Any为根,分为AnyRef和AnyVal 两个分支体系,在AnyRef分支的最底层,有个Null类型的特殊类型,它被当作是所有AnyRef类型的子类型。更进一步在两个分支共同的最底层类型是Nothing类型,它被当作所有AnyRef和AnyVal类型的子类型。

数值类型

Scala的数值类型包含:

  • Byte 1字节
  • Short 2
  • Int 4
  • Long 8
  • Foat
  • Double 高精度类型 a = 低精度类型 b (同c自动转换) 低精度类型 b = 高精度类型 a (error :type mismatch)

Boolen 类型

  • false
  • true

Null类型

Null类型只有一个唯一的值:null,可以被赋给所有的AnyRef类型变量List(Null,Null,1)

Block代码块

Block 也是一个表达式,其最终的求得的值是最后一个表达式的结果。

{exp1;exp2}

{
exp1
exp2
}

循环

第五步使用while来实现循环,和使用Java实现无太大差异,而Scala是面向函数的语言,更好的方法是采用“函数式”风格来编写代码。比如使用foreach方法来实现循环,如下:

args.foreach(arg => println(arg))

该表达式,调用args的foreach方法,传入一个参数,这个参数类型也是一个函数(lambda表达式,和C#中概念类似)。这段代码可以再写的精简些,你可以利用Scala支持的缩写形式,如果一个函数只有一个参数并且只包含一个表达式,那么你无需明确指明参数。因此,上面的表达式还可以简写为:

args.foreach( println)

而Scala的for循环比Java更加强大,例如:

for( a <- 1 to 10){ 
         println( "Value of a: " + a );

//或者
// for loop execution with a range
for( a <- 1 until 10){ 
       println( "Value of a: " + a );      }

while 和 do while

var a = 10;
     // while loop execution
      while( a < 20 ){
         println( "Value of a: " + a ); 
         a = a + 1;}
 // do loop execution
do {        
        println( "Value of a: " + a );
         a = a + 1;
      }
      while( a < 20 )   }

match表达式

val alice = new Person("Alice", 25)
val bob = new Person("Bob", 32)
val charlie = new Person("Charlie", 32)
for (person <- List(alice, bob, charlie)) {

         person match { 
            case Person("Alice", 25) => println("Hi Alice!")
            case Person("Bob", 32) => println("Hi Bob!") 
            case Person(name, age) => println(
               "Age: " + age + " year, name: " + name + "?")
         }
      } 
   }
#这个类是特殊的用以比较的类
case class Person(name: String, age: Int)
>>>
Hi Alice!
Hi Bob! 
Age: 32 year, name: Charlie?

Traits

是一些字段和行为的集合,可以扩展或混入(mixin)你的类中。

trait Car {
  val brand: String
}

trait Shiny {
  val shineRefraction: Int
}
class BMW extends Car {
  val brand = "BMW"
}

通过with关键字,一个类可以扩展多个特质:

class BMW extends Car with Shiny {
  val brand = "BMW"
  val shineRefraction = 12
}

单例

object IdFactory {
  private var counter = 0
  def create(): Int = {
    counter += 1
    counter
  }
}
//获取单例实例
val newId: Int = IdFactory.create()
println(newId) // 1

小结

Scala语言的一个特点是支持面向函数编程,因此学习Scala的一个重要方面是改变之前的指令式编程思想(尤其是来自Java或C#背景的程序员),观念要向函数式编程转变。首先在看代码上要认识哪种是指令编程,哪种是函数式编程。一个简单的原则,如果代码中含有var类型的变量,这段代码就是传统的指令式编程,如果代码只有val变量,这段代码就很有可能是函数式代码,因此学会函数式编程关键是不使用vars来编写代码。更多Scala的知识请访问官网

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏斑斓

当函数成为一等公民时,设计模式的变化

GOF提出的设计模式,其本质思想是封装变化。故而,创建型模式封装的是对象创建的变化,结构型模式封装的是对象之间的协作与组合结构,行为型模式则封装了对象行为的变化...

3115
来自专栏IMWeb前端团队

神奇运算符

每一门编程语言的设计都离不开运算符,我们写的每一行代码基本也少不了它们,这篇文章就让我们一起来了解一下这个无处不在的小伙伴的应用和小技巧吧~~ ~ 按位取反 字...

2099
来自专栏怀英的自我修炼

Java漫谈8

今天我们来聊聊字符串。 字符串,在Java中一个最接近与8大数据类型的存在。甚至于由于它太好用了,以至于在编写代码的时候都快忘了有个叫char的基本数据类型了。...

36210
来自专栏一个会写诗的程序员的博客

《Kotin 极简教程》第7章 面向对象编程(OOP)(1)第7章 面向对象编程(OOP)《Kotlin极简教程》正式上架:

在前面的章节中,我们学习了Kotlin的语言基础知识、类型系统、集合类以及泛型相关的知识。在本章节以及下一章中,我们将一起来学习Kotlin对面向对象编程以及函...

952
来自专栏AzMark

Python列表与元组

1403
来自专栏书山有路勤为径

寻找中位数

LeetCode 295. Find Median from Data Stream 设计一个数据结构,该数据结构动态维护一组数据,且支持如下操作: 1.添...

1043
来自专栏Java帮帮-微信公众号-技术文章全总结

第八天 自定义类型方法集合混合使用【悟空教程】

2028
来自专栏有趣的Python和你

函数讲解

963
来自专栏向治洪

Scala入门

Scala入门 Scala简介 ps:在最新的薪资调查中,Scala程序员的工资是平均最高的Scala工资。 Scala是一门多范式的编程语言,一种类似java...

1997
来自专栏AlgorithmDog的专栏

靠默契保证的私有制:Python 中的私有

人类文明开化以来,私有制似乎是人类历史的主流在西方国家,“私有财产神圣不可侵犯” 是很多资本主义国家的立国原则之一。在我国,“私有财产不可侵犯” 也...

2038

扫码关注云+社区

领取腾讯云代金券