Scala语言是一种面向对象语言,结合了命令式(imperative)和函数式(functional)编程风格,其设计理念是创造一种更好地支持组件的语言。

特性

  • 多范式(Multi-Paradigm)编程语言,类似Java、C#;

  • 继承面向对象编程和函数式编程的特性;

    • 面向对象:[1]. 子类继承,[2]. 混入(Mixin)机制;

    • 函数式:支持高阶函数、嵌套函数,模式匹配,支持柯里化(Currying);

    • 类型推断(Type Inference):根据函数体中的具体内容推断方法的返回值类型

  • 更高层的并发模型,可伸缩;

  • 静态类型,编译时检查;

  • 允许与Java互操作(将来会支持与.Net互操作);

与Java对比

  • 如果用作服务器端开发,Scala的简洁、灵活性是Java无法比拟的;

  • 如果是企业级应用开发、Web开发,Java的强大是Scala无法匹敌的;

基础语法

表达式(Expressions)

表达式是可计算的语句。您可以使用println输出表达式的结果。

println(1) // 1
println(1 + 1) // 2
println("Hello!") // Hello!
println("Hello," + " world!") // Hello, world!

值(Values)

您可以使用val关键字命名表达式的结果。

val x = 1 + 1
println(x) // 2

命名结果(例如x)称为值。引用值不会重新计算它。值无法被重新分配。

val x = 1 + 1
x = 3 // This does not compile.

可以推断出值的类型,但您也可以显式声明类型,如下所示:

val x: Int = 1 + 1

注意类型声明Int如何在标识符x之后出现,你还需要一个“:”

变量(Variables)

变量就像值,除了你可以重新赋值。您可以使用var关键字定义变量。

var x = 1 + 1
x = 3 // This compiles because "x" is declared with the "var" keyword.
println(x * x) // 9

与值一样,您可以根据需要明确说明类型:

var x: Int = 1 + 1

块(Blocks)

您可以通过用{}包围表达式来组合表达式。我们称之为块。块中最后一个表达式的结果也是整个块的结果。

println({
  val x = 1 + 1
  x + 1
}) // 3

函数(Functions)

函数是带参数的表达式。

您可以定义一个返回给定整数加一的匿名函数(即无名称):

(x: Int) => x + 1

在=>的左边是参数列表。右边是涉及参数的表达式。

您也可以命名函数。

val addOne = (x: Int) => x + 1
println(addOne(1)) // 2

函数可能需要多个参数。

val add = (x: Int, y: Int) => x + y
println(add(1, 2)) // 3

或者它不需要参数。

val getTheAnswer = () => 42
println(getTheAnswer()) // 42

方法(Methods)

方法的外观和行为与函数非常相似,但它们之间存在一些关键差异。

方法使用def关键字定义。 def后跟名称,参数列表,返回类型和正文。

def add(x: Int, y: Int): Int = x + y
println(add(1, 2)) // 3

注意如何在参数列表和冒号之后声明返回类型:Int。

方法可以采用多个参数列表。

def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier
println(addThenMultiply(1, 2)(3)) // 9

或者根本没有参数列表。

def name: String = System.getProperty("user.name")
println("Hello, " + name + "!")

还有一些其他差异,但就目前而言,您可以将它们视为与函数类似的东西。

方法也可以有多行表达式。

def getSquareString(input: Double): String = {
  val square = input * input
  square.toString
}

正文中的最后一个表达式是方法的返回值。 (Scala确实有一个return关键字,但它很少使用。)

关于方法(Method)和函数(Function)

  • 函数是一等公民,使用val语句可以定义函数,def语句定义方法;

  • 函数是一个对象,继承自FuctionN,函数对象有curried,equals,isInstanceOf,toString等方法,而方法不具有;

  • 函数是一个值,可以给val变量赋值,方法不是值、也不可以给val变量赋值;

  • 通过将方法转化为函数的方式 method _ 或 method(_) 实现给val变量赋值;

  • 若 method 有重载的情况,方法转化为函数时必须指定参数和返回值的类型;

  • 某些情况下,编译器可以根据上下文自动将方法转换为函数;

  • 无参数的方法 method 没有参数列表(调用:method),无参数的函数 function 有空列表(调用:function());

  • 方法可以使用参数序列,转换为函数后,必须用 Seq 包装参数序列;

  • 方法支持默认参数,函数不支持、会忽略之;

类(Classes)

您可以使用class关键字定义类,后跟其名称和构造函数参数。

class Greeter(prefix: String, suffix: String) {
  def greet(name: String): Unit =
    println(prefix + name + suffix)
}

方法greet的返回类型是Unit,它表示返回没有任何意义。它与Java和C中的void类似地使用。(不同之处在于,因为每个Scala表达式必须具有某个值,实际上存在Unit类型的单例值,write()。它不携带任何信息。)

您可以使用new关键字创建类的实例。

val greeter = new Greeter("Hello, ", "!")
greeter.greet("Scala developer") // Hello, Scala developer!

样本类(Case Classes)

Scala有一种特殊类型的类,称为样本类。默认情况下,样本类是不可变的,并按值进行比较。您可以使用“case class”关键字定义案例类。

case class Point(x: Int, y: Int)

您可以在没有new关键字的情况下实例化样本类。

val point = Point(1, 2)
val anotherPoint = Point(1, 2)
val yetAnotherPoint = Point(2, 2)

并且它们按值进行比较。

if (point == anotherPoint) {
  println(point + " and " + anotherPoint + " are the same.")
} else {
  println(point + " and " + anotherPoint + " are different.")
}
// Point(1,2) and Point(1,2) are the same.
if (point == yetAnotherPoint) {
  println(point + " and " + yetAnotherPoint + " are the same.")
} else {
  println(point + " and " + yetAnotherPoint + " are different.")
}
// Point(1,2) and Point(2,2) are different.

对象(Objects)

对象是它们自己定义的单个实例。你可以把它们想象成自己班级的单身人士。

您可以使用object关键字定义对象。

object IdFactory {
  private var counter = 0
  def create(): Int = {
    counter += 1
    counter
  }
}

您可以通过引用其名称来访问该对象。

val newId: Int = IdFactory.create()
println(newId) // 1
val newerId: Int = IdFactory.create()
println(newerId) // 2

抽象类

你可以定义一个抽象类,它定义了一些方法但没有实现它们。取而代之是由扩展抽象类的子类定义这些方法。你不能创建抽象类的实例。

abstract class Shape {      
  def getArea():Int    // subclass should define this      
} 
class Circle(r: Int) extends Shape {      
  def getArea():Int = { r * r * 3 }      
} 
val s = new Shape //error: class Shape is abstract; cannot be instantiated                     
val c = new Circle(2)

特质(Traits)

特质是包含某些字段和方法的类型。可以组合多种特质。
您可以使用trait关键字定义特质。

trait Greeter {
  def greet(name: String): Unit
}

特质也可以有默认实现。

trait Greeter {
  def greet(name: String): Unit =
    println("Hello, " + name + "!")
}

您可以使用extends关键字扩展traits并使用override关键字覆盖实现。

class DefaultGreeter extends Greeter
class CustomizableGreeter(prefix: String, postfix: String) extends Greeter {
  override def greet(name: String): Unit = {
    println(prefix + name + postfix)
  }
}
val greeter = new DefaultGreeter()
greeter.greet("Scala developer") // Hello, Scala developer!
val customGreeter = new CustomizableGreeter("How are you, ", "?")
customGreeter.greet("Scala developer") // How are you, Scala developer?

在这里,DefaultGreeter只扩展了一个特质,但它可以扩展多个特质。

什么时候应该使用特质而不是抽象类?

如果你想定义一个类似接口的类型,你可能会在特质和抽象类之间难以取舍。这两种形式都可以让你定义一个类型的一些行为,并要求继承者定义一些其他行为。一些经验法则:

  • 优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。

  • 如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,而特质不行。例如,你不能说trait t(i: Int) {},参数i是非法的。

Main方法

Main方法是程序的切入点。 Java虚拟机需要将main方法命名为main,并使用一个参数,即一个字符串数组。
使用对象,您可以按如下方式定义main方法:

object Main {
  def main(args: Array[String]): Unit =
    println("Hello, Scala developer!")
}

本文主要翻译自Basics|Scala Documentation

Scala学习(一)——基础语法的更多相关文章

  1. JavaScript学习02 基础语法

    JavaScript学习02 基础语法 JavaScript中很多基础内容和Java中大体上基本一样,所以不需要再单独重复讲了,包括: 各种算术运算符.比较运算符.逻辑运算符: if else语句.s ...

  2. Scala快速入门 - 基础语法篇

    本篇文章首发于头条号Scala快速入门 - 基础语法篇,欢迎关注我的头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_tech)获取更多干货,也欢迎关注我的 ...

  3. Scala简介及基础语法

    一.scala简介 官网:https://www.scala-lang.org/ Scala语言很强大,集成了面向对象和函数式编程的特点. 运行在JVM(jdk). 大数据中为什么学习scala? s ...

  4. JavaScript学习笔记-基础语法、类型、变量

    基础语法.类型.变量   非数字值的判断方法:(因为Infinity和NaN他们不等于任何值,包括自身) 1.用x != x ,当x为NaN时才返回true; 2.用isNaN(x) ,当x为NaN或 ...

  5. less学习:基础语法总结

    一. less是什么 Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合(mixin).函数等功能,让 CSS 更易维护.方便制作主题.扩充. 注意1):less使用. ...

  6. Python学习①. 基础语法

    Python 简介 Python 是一种解释型,面向对象的语言.特点是语法简单,可跨平台 Python 基础语法 交互式编程 交互式编程不需要创建脚本文件,是通过 Python 解释器的交互模式进来编 ...

  7. 真香,理解记忆法学习Python基础语法

    这篇文章很难写!我最开始学 Python,和大多数人一样,是看的菜鸟教程: 在写完这篇文章的第一遍后,我发现并没有写出新意,很可能读者看到后,会和我当初一样,很快就忘了.我现在已经不是读者而是作者了, ...

  8. Scala - 快速学习03 - 基础语法

    1- 变量 变量 mutable variable 在程序运行过程中其值可能发生改变的量 关键词var定义变量,定义时直接进行求值 常量 immutable variable 在程序运行过程中其值不会 ...

  9. 学习fortran77基础语法

    Program ParamaterDefine Implicit None C FORTRAN变量名和关键字不区分大小写.但调用外部函数的话,需要在编译选项里指定 c 大小写等选项 因为链接器是区分大 ...

  10. Python学习--Python基础语法

    第一个Python程序 交互式编程 交互式编程不需要创建脚本文件,是通过 Python 解释器的交互模式进来编写代码. linux上你只需要在命令行中输入 Python 命令即可启动交互式编程,提示窗 ...

随机推荐

  1. AWS In Action

    Core Services of AWS Elastic Cloud Compute(EC2) Simple Storage Service(S3) Relational Database Servi ...

  2. 无障碍开发(三)之ARIA aria-***属性值

    aria-***属性值

  3. leetcode 1282. Group the People Given the Group Size They Belong To

    There are n people whose IDs go from 0 to n - 1 and each person belongs exactly to one group. Given ...

  4. linux入门到高级

    目  录 1. Linux入门篇.................................................................................... ...

  5. sql limit i,n

    limit i,n; i:为查询结果的索引值(默认从0开始),当i=0时可省略i n:为查询结果返回的数量(也就是条数) 表示从第i+1条开始,取n条数据 limit n 等同于 limit 0,n ...

  6. jq选择CheckBox进行排序

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta name=& ...

  7. Python enumerate 使用技巧

    enumerate() 是Python内建的函数,能让打印的结果更清晰,不管是列表,元组,字典,enumerate()都可以帮你完成,在某些需求下还是非常好用的. >>> a = [ ...

  8. lightinthebox头部分类菜单下拉导航,使鼠标移到See All Categories就显示下拉菜单

    lightinthebox头部分类菜单下拉导航,使鼠标移到See All Categories就显示下拉菜单 打开includes\templates\lightinthebox\common\tpl ...

  9. 从给定的N个正数中选取若干个数之和最接近M

    https://blog.csdn.net/lsjseu/article/details/11660731

  10. HDU - 6589 Sequence (生成函数+NTT)

    题目链接 设序列a的生成函数$\large f(x)=\sum\limits_{i=0}^{n-1}a_ix^i$,则操作1,2,3分别对应将$f(x)$乘上$\Large\frac{1}{1-x}, ...