Scala 基础语法

Scala 基础语法学习文档

一、Scala 简介

Scala 是一门多范式编程语言,集成了面向对象编程和函数式编程的各种特性。如果你之前是一名 Java 程序员,并了解 Java 语言的基础知识,那么你能很快学会 Scala 的基础语法。

Scala 与 Java 的主要区别

  • Scala 语句末尾的分号 ; 是可选的
  • Scala 支持函数式编程范式
  • Scala 具有更强大的类型推断能力
  • Scala 代码更加简洁

核心概念

Scala 程序可以认为是对象的集合,通过调用彼此的方法来实现消息传递。以下是核心概念:

概念 说明
对象 (Object) 对象有属性和行为。例如:一只狗的属性有:颜色、名字;行为有:叫、跑、吃等。对象是一个类的实例。
类 (Class) 类是对象的抽象,而对象是类的具体实例。
方法 (Method) 方法描述基本的行为,一个类可以包含多个方法。
字段 (Field) 每个对象都有它唯一的实例变量集合,即字段。对象的属性通过给字段赋值来创建。

二、第一个 Scala 程序

交互式编程

交互式编程不需要创建脚本文件,可以通过以下命令调用:

bash 复制代码
$ scala
Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_31).
Type in expressions to have them evaluated.
Type :help for more information.

scala> 1 + 1
res0: Int = 2

scala> println("Hello World!")
Hello World!

脚本形式

创建 HelloWorld.scala 文件:

scala 复制代码
object HelloWorld {
   def main(args: Array[String]) = {
      println("Hello, world!")
   }
}

编译和运行:

bash 复制代码
$ scalac HelloWorld.scala 

Hello, world!

Scala 3 新语法

Scala 3 引入了更简洁的程序入口语法:

scala 复制代码
@main def hello() = println("Hello, Scala developer!")

三、基本语法规则

1. 大小写敏感

Scala 是大小写敏感的,标识符 Hellohello 在 Scala 中会有不同的含义。

2. 类名命名规则

  • 所有类名的第一个字母要大写
  • 如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写(大驼峰命名)
scala 复制代码
class MyFirstScalaClass
class Person
class OrderProcessor

3. 方法名称命名规则

  • 所有方法名称的第一个字母用小写
  • 如果若干单词被用于构成方法的名称,则每个单词的第一个字母应大写(小驼峰命名)
scala 复制代码
def myMethodName()
def calculateTotal()
def processOrder()

4. 程序文件名

程序文件的名称应该与对象名称完全匹配(新版本不需要了,但建议保留这种习惯)。保存文件时,应该保存它使用的对象名称,并追加 .scala 为文件扩展名。

5. 程序入口

Scala 程序从 main() 方法开始处理,这是每一个 Scala 程序的强制程序入口部分。

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

四、标识符

Scala 可以使用两种形式的标识符:字符数字和符号。

字符数字标识符

  • 使用字母或是下划线开头,后面可以接字母或是数字
  • 符号 $ 在 Scala 中也看作为字母
  • $ 开头的标识符为保留的 Scala 编译器产生的标识符使用,应用程序应该避免使用
scala 复制代码
val myValue = "hello"
var myVariable = 123
val _temp = 10

符号标识符

符号标识符包含一个或多个符号,如 +:? 等:

scala 复制代码
+  ++  :::  <  ?>  :->

Scala 内部实现时会使用转义的标识符,比如 -> 使用 $colon$minus$greater 来表示。

混合标识符

混合标识符由字符数字标识符后面跟着一个或多个符号组成:

scala 复制代码
unary_+  // Scala 对 + 方法的内部实现时的名称

字面量标识符

字面量标识符为使用反引号 ````` 定义的字符串:

scala 复制代码
Thread.`yield`()  // yield 为 Scala 中的关键字,必须使用反引号

五、命名约定

常量命名

常量使用大驼峰命名法:

scala 复制代码
object Container {
  val MyConstant = 10
}

值和变量命名

值和变量使用小驼峰命名法:

scala 复制代码
val myValue = "hello"
var myVariable = 123

六、Scala 关键字

以下是 Scala 保留关键字,不能使用这些关键字作为变量名:

abstract case catch class
def do else extends
false final finally for
forSome if implicit import
lazy match new null
object override package private
protected return sealed super
this throw trait try
true type val var
while with yield
- : = =>
<- <: <% >:
# @

七、注释

Scala 类似 Java 支持单行和多行注释。多行注释可以嵌套,但必须正确嵌套。

单行注释

scala 复制代码
// 这是单行注释

多行注释

scala 复制代码
/* 
 * 这是多行注释
 * 可以跨越多行
 */

嵌套注释(Scala 特有)

scala 复制代码
/*
 * 外层注释开始
 * /* 
  * 内层注释
  */
 * 外层注释结束
 */

八、变量声明

Scala 有两种类型的变量:valvar

val - 不可变变量

val 声明的变量是不可变的,类似于 Java 中的 final 变量,一旦初始化就不能重新赋值:

scala 复制代码
val a = 0
val x: Int = 1        // 显式类型声明
val s = "Hello"       // 类型推断
val nums = List(1,2,3)
val p = Person("Martin", "Odersky")  // 对象实例化

var - 可变变量

var 声明的变量是可变的,可以重新赋值:

scala 复制代码
var b = 1
var x = 5
var x: Double = 5     // 显式类型声明

x = 10                // 可以重新赋值

显式类型 vs 隐式类型

scala 复制代码
val x: Int = 1        // 显式类型声明
val x = 1             // 隐式类型声明,编译器推断类型

最佳实践

推荐优先使用 val,只有在确实需要修改变量值时才使用 var。这有助于编写更加函数式和安全的代码。


九、数据类型

Scala 是强类型语言,但具有强大的类型推断能力。

基本数据类型

数据类型 描述
Byte 8位有符号整数
Short 16位有符号整数
Int 32位有符号整数
Long 64位有符号整数
Float 32位单精度浮点数
Double 64位双精度浮点数
Char 16位无符号 Unicode 字符
Boolean true 或 false
String 字符串
Unit 表示无值,类似 void
Null 空引用
Nothing 所有类型的子类型
Any 所有类型的超类

类型声明示例

scala 复制代码
val numInt: Int = 10
val numLong: Long = 100000L
val numFloat: Float = 10.5f
val numDouble: Double = 10.5
val bool: Boolean = true
val char: Char = 'A'
val str: String = "Hello Scala"

十、方法定义

基本语法

scala 复制代码
def methodName(param1: Type1, param2: Type2): ReturnType =
  // 方法体

方法定义示例

scala 复制代码
def sum(a: Int, b: Int): Int = a + b

def concatenate(s1: String, s2: String): String = s1 + s2

// 省略返回类型(编译器自动推断)
def sum(a: Int, b: Int) = a + b

def concatenate(s1: String, s2: String) = s1 + s2

方法调用

scala 复制代码
val x = sum(1, 2)
val y = concatenate("foo", "bar")

十一、类和对象

类定义

scala 复制代码
class Person(name: String, age: Int) {
  def greet(): Unit = {
    println(s"Hello, my name is $name")
  }
}

对象(单例对象)

scala 复制代码
object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, World!")
  }
}

对象实例化

scala 复制代码
val p = Person("Al", "Pacino")
val nums = List(1, 2, 3)

十二、函数式编程特性

for 推导式

Scala 2 语法:

scala 复制代码
val y = for (i <- nums) yield i * 2

Scala 3 语法:

scala 复制代码
val y = for i <- nums yield i * 2

集合操作

scala 复制代码
val nums = List(1, 2, 3, 4, 5)

val sum = nums.reduceLeft(_ + _)

val z = nums
  .filter(_ > 100)
  .filter(_ < 10_000)
  .map(_ * 2)

十三、Scala 2 vs Scala 3 主要差异

特性 Scala 2 Scala 3
程序入口 def main(args: Array[String]) @main def hello()
for 推导式 for (i <- nums) yield i * 2 for i <- nums yield i * 2
数字分隔符 不支持 10_000
语法简洁性 相对繁琐 更加简洁

十四、代码示例汇总

完整示例

scala 复制代码
object Main {
  def main(args: Array[String]): Unit = {
    println("=== Scala 基础语法示例 ===")
    
    val immutableValue = 10
    var mutableValue = 20
    
    println(s"不可变值: $immutableValue")
    println(s"可变值: $mutableValue")
    
    mutableValue = 30
    println(s"修改后的可变值: $mutableValue")
    
    val result = sum(5, 3)
    println(s"sum(5, 3) = $result")
    
    val greeting = concatenate("Hello, ", "Scala!")
    println(s"拼接结果: $greeting")
    
    val nums = List(1, 2, 3, 4, 5)
    val doubled = nums.map(_ * 2)
    println(s"列表翻倍: $doubled")
  }
  
  def sum(a: Int, b: Int): Int = a + b
  
  def concatenate(s1: String, s2: String): String = s1 + s2
}

十五、建议

  1. 优先使用 val:尽量使用不可变变量,这有助于编写更加安全和易于推理的代码
  2. 遵循命名规范:保持代码风格一致,提高可读性
  3. 利用类型推断:在类型明显的情况下,可以省略类型声明,让代码更简洁
  4. 学习函数式编程:Scala 的强大之处在于函数式编程特性,建议深入学习
相关推荐
AMoon丶1 小时前
C++模版-函数模版,类模版基础
java·linux·c语言·开发语言·jvm·c++·算法
SugarFreeOixi2 小时前
Matlab多个图窗重叠问题解决,平铺函数TileFigs
开发语言·matlab
码不停蹄Zzz2 小时前
C语言【结构体值传递问题】
c语言·开发语言
AMoon丶2 小时前
Golang--多种数据结构详解
linux·c语言·开发语言·数据结构·c++·后端·golang
wearegogog1232 小时前
C# Modbus 协议实现
开发语言·c#
紫郢剑侠3 小时前
【C语言编程gcc@Kylin | 麒麟 】5:获取系统启动时间
c语言·开发语言·kylin·gcc·麒麟操作系统
晓晓hh3 小时前
JavaSe学习——基础
java·开发语言·学习
清水白石0083 小时前
Python 内存陷阱深度解析——浅拷贝、深拷贝与对象复制的正确姿势
开发语言·python
phltxy3 小时前
算法刷题|模拟思想高频题全解(Java版)
java·开发语言·算法