用户国营 发表于 2025-4-19 07:53:31

Scala 入门指南

Scala 入门指南

目录



[*]简介
[*]环境搭建
[*]基础语法
[*]面向对象编程
[*]函数式编程
[*]聚集
[*]模式匹配
[*]特质
[*]隐式转换
[*]并发编程
[*]与 Java 互操纵
[*]最佳实践
[*]常见题目
简介

Scala 是一种多范式编程语言,联合了面向对象编程和函数式编程的特性。它运行在 JVM 上,与 Java 完全兼容,并且可以调用 Java 库。
Scala 的重要特性



[*]面向对象和函数式编程的联合
[*]静态范例体系
[*]范例推断
[*]模式匹配
[*]高阶函数
[*]不可变数据结构
[*]并发编程支持
[*]与 Java 互操纵
环境搭建

1. 安装 JDK

Scala 需要 JDK 环境,保举使用 JDK 8 或更高版本。
# 检查 Java 版本
java -version
2. 安装 Scala

方法一:使用 SDKMAN(保举)

# 安装 SDKMAN
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

# 安装 Scala
sdk install scala
方法二:直接下载安装

从 Scala 官网 下载安装包并安装。
3. 安装 IDE

保举使用 IntelliJ IDEA 或 VS Code 配合 Scala 插件。
IntelliJ IDEA


[*]下载并安装 IntelliJ IDEA
[*]安装 Scala 插件:File → Settings → Plugins → 搜索 “Scala” → 安装
[*]重启 IDE
VS Code


[*]安装 VS Code
[*]安装 “Scala (Metals)” 插件
[*]安装 “Scala Syntax (official)” 插件
4. 验证安装

# 检查 Scala 版本
scala -version

# 启动 Scala REPL
scala
基础语法

1. 变量和常量

// 变量(可变)
var x = 10
x = 20// 可以修改

// 常量(不可变)
val y = 30
// y = 40// 编译错误,不能修改

// 类型声明(可选)
val name: String = "Scala"
var age: Int = 25
2. 基本数据范例

// 数值类型
val byte: Byte = 127
val short: Short = 32767
val int: Int = 2147483647
val long: Long = 9223372036854775807L
val float: Float = 3.14f
val double: Double = 3.141592653589793

// 字符
val char: Char = 'A'

// 布尔值
val boolean: Boolean = true

// 字符串
val string: String = "Hello, Scala!"
3. 字符串操纵

val name = "Scala"
val version = 3.0

// 字符串插值
val message = s"$name version $version"
val message2 = s"${name.toUpperCase} version ${version + 0.1}"

// 多行字符串
val multiline = """
|This is a
|multiline
|string
|""".stripMargin
4. 运算符

// 算术运算符
val a = 10
val b = 3
val sum = a + b
val diff = a - b
val product = a * b
val quotient = a / b
val remainder = a % b

// 比较运算符
val isEqual = a == b
val isNotEqual = a != b
val isGreater = a > b
val isLess = a < b
val isGreaterOrEqual = a >= b
val isLessOrEqual = a <= b

// 逻辑运算符
val p = true
val q = false
val and = p && q
val or = p || q
val not = !p
5. 条件语句

// if-else 语句
val age = 20
val status = if (age >= 18) "成年" else "未成年"

// 多分支 if-else
val grade = 85
val level = if (grade >= 90) "A"
         else if (grade >= 80) "B"
         else if (grade >= 70) "C"
         else if (grade >= 60) "D"
         else "F"
6. 循环

// for 循环
for (i <- 1 to 5) {
println(i)
}

// 带过滤器的 for 循环
for (i <- 1 to 10 if i % 2 == 0) {
println(i)
}

// for 推导式
val squares = for (i <- 1 to 5) yield i * i

// while 循环
var i = 1
while (i <= 5) {
println(i)
i += 1
}

// do-while 循环
var j = 1
do {
println(j)
j += 1
} while (j <= 5)
面向对象编程

1. 类定义

// 简单类
class Person {
var name: String = ""
var age: Int = 0

def sayHello(): Unit = {
    println(s"Hello, my name is $name and I am $age years old.")
}
}

// 主构造函数
class Person(val name: String, var age: Int) {
def sayHello(): Unit = {
    println(s"Hello, my name is $name and I am $age years old.")
}
}

// 辅助构造函数
class Person {
var name: String = ""
var age: Int = 0

def this(name: String) {
    this()
    this.name = name
}

def this(name: String, age: Int) {
    this(name)
    this.age = age
}
}
2. 对象(单例)

// 单例对象
object Singleton {
def sayHello(): Unit = {
    println("Hello from singleton!")
}
}

// 伴生对象
class Person(val name: String) {
def sayHello(): Unit = {
    println(s"Hello, my name is $name")
}
}

object Person {
def apply(name: String): Person = new Person(name)

def unapply(person: Person): Option = Some(person.name)
}
3. 继承

// 基类
class Animal(val name: String) {
def makeSound(): Unit = {
    println("Some sound")
}
}

// 子类
class Dog(name: String) extends Animal(name) {
override def makeSound(): Unit = {
    println("Woof!")
}
}

// 抽象类
abstract class Shape {
def area(): Double
def perimeter(): Double
}

class Circle(radius: Double) extends Shape {
def area(): Double = Math.PI * radius * radius
def perimeter(): Double = 2 * Math.PI * radius
}
4. 封装

class BankAccount {
private var balance = 0.0

def deposit(amount: Double): Unit = {
    if (amount > 0) {
      balance += amount
    }
}

def withdraw(amount: Double): Boolean = {
    if (amount > 0 && amount <= balance) {
      balance -= amount
      true
    } else {
      false
    }
}

def getBalance: Double = balance
}
函数式编程

1. 函数定义

// 基本函数
def add(x: Int, y: Int): Int = x + y

// 无参数函数
def getCurrentTime(): Long = System.currentTimeMillis()

// 默认参数
def greet(name: String, greeting: String = "Hello"): String = {
s"$greeting, $name!"
}

// 命名参数
def createPerson(name: String, age: Int, city: String): String = {
s"$name is $age years old and lives in $city"
}

val person = createPerson(name = "Alice", age = 30, city = "New York")
2. 高阶函数

// 函数作为参数
def applyOperation(x: Int, f: Int => Int): Int = f(x)

val double = (x: Int) => x * 2
val square = (x: Int) => x * x

val result1 = applyOperation(5, double)// 10
val result2 = applyOperation(5, square)// 25

// 函数作为返回值
def multiplier(factor: Int): Int => Int = {
(x: Int) => x * factor
}

val multiplyByTwo = multiplier(2)
val result3 = multiplyByTwo(5)// 10
3. 匿名函数

// 基本匿名函数
val add = (x: Int, y: Int) => x + y

// 简写形式
val numbers = List(1, 2, 3, 4, 5)
val doubled = numbers.map(x => x * 2)
val evenNumbers = numbers.filter(_ % 2 == 0)

// 部分应用函数
val sum = (a: Int, b: Int, c: Int) => a + b + c
val addOneAndTwo = sum(1, 2, _)
val result = addOneAndTwo(3)// 6
4. 柯里化

// 柯里化函数
def add(x: Int)(y: Int): Int = x + y

val addOne = add(1)_
val result = addOne(5)// 6

// 非柯里化转柯里化
def nonCurriedAdd(x: Int, y: Int): Int = x + y
def curriedAdd = (nonCurriedAdd _).curried
聚集

1. 不可变聚集

// List
val list = List(1, 2, 3, 4, 5)
val first = list.head
val rest = list.tail
val newList = 0 :: list// 在头部添加元素
val concatenated = list ++ List(6, 7)// 连接列表

// Set
val set = Set(1, 2, 3, 3, 4, 4, 5)// 结果为 Set(1, 2, 3, 4, 5)
val contains = set.contains(3)// true
val newSet = set + 6// 添加元素

// Map
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)
val value = map("a")// 1
val valueOrDefault = map.getOrElse("d", 0)// 0
val newMap = map + ("d" -> 4)// 添加键值对
2. 可变聚集

import scala.collection.mutable

// 可变 ListBuffer
val buffer = mutable.ListBuffer(1, 2, 3)
buffer += 4// 添加元素
buffer -= 2// 移除元素

// 可变 Set
val mutableSet = mutable.Set(1, 2, 3)
mutableSet += 4// 添加元素
mutableSet -= 2// 移除元素

// 可变 Map
val mutableMap = mutable.Map("a" -> 1, "b" -> 2)
mutableMap("c") = 3// 添加或更新键值对
mutableMap -= "a"// 移除键值对
3. 聚集操纵

val numbers = List(1, 2, 3, 4, 5)

// 映射
val doubled = numbers.map(_ * 2)// List(2, 4, 6, 8, 10)

// 过滤
val evenNumbers = numbers.filter(_ % 2 == 0)// List(2, 4)

// 扁平化
val nestedList = List(List(1, 2), List(3, 4), List(5))
val flattened = nestedList.flatten// List(1, 2, 3, 4, 5)

// 扁平映射
val flatMapped = nestedList.flatMap(identity)// List(1, 2, 3, 4, 5)

// 折叠
val sum = numbers.foldLeft(0)(_ + _)// 15
val product = numbers.foldRight(1)(_ * _)// 120

// 归约
val max = numbers.reduce((a, b) => if (a > b) a else b)// 5
模式匹配

1. 基本模式匹配

def matchNumber(x: Int): String = x match {
case 0 => "zero"
case 1 => "one"
case 2 => "two"
case _ => "many"
}

// 匹配多个值
def matchMultiple(x: Int): String = x match {
case 0 | 1 | 2 => "small"
case 3 | 4 | 5 => "medium"
case _ => "large"
}
2. 范例模式匹配

def matchType(x: Any): String = x match {
case s: String => s"String: $s"
case i: Int => s"Integer: $i"
case d: Double => s"Double: $d"
case _ => "Unknown type"
}
3. 序列模式匹配

def matchList(list: List): String = list match {
case Nil => "Empty list"
case List(x) => s"Single element: $x"
case List(x, y) => s"Two elements: $x and $y"
case x :: rest => s"First element: $x, rest: $rest"
}
4. 样例类模式匹配

// 定义样例类
case class Person(name: String, age: Int)
case class Dog(name: String, breed: String)

// 模式匹配
def matchPerson(person: Any): String = person match {
case Person(name, age) => s"Person: $name, $age years old"
case Dog(name, breed) => s"Dog: $name, breed: $breed"
case _ => "Unknown"
}
特质

1. 基本特质

// 定义特质
trait Speaker {
def speak(): String
}

// 实现特质
class Dog extends Speaker {
def speak(): String = "Woof!"
}

class Cat extends Speaker {
def speak(): String = "Meow!"
}
2. 带实现的特质

trait Animal {
def name: String
def makeSound(): String

def description(): String = s"$name says ${makeSound()}"
}

class Dog(val name: String) extends Animal {
def makeSound(): String = "Woof!"
}

class Cat(val name: String) extends Animal {
def makeSound(): String = "Meow!"
}
3. 特质叠加

trait Logging {
def log(msg: String): Unit = println(s"Log: $msg")
}

trait TimestampLogging extends Logging {
override def log(msg: String): Unit = {
    val timestamp = java.time.Instant.now()
    super.log(s"[$timestamp] $msg")
}
}

trait ShortLogging extends Logging {
override def log(msg: String): Unit = {
    if (msg.length > 20) {
      super.log(msg.substring(0, 20) + "...")
    } else {
      super.log(msg)
    }
}
}

// 特质叠加顺序从右到左
class MyClass extends ShortLogging with TimestampLogging {
def doSomething(): Unit = {
    log("This is a very long message that should be shortened")
}
}
隐式转换

1. 基本隐式转换

// 定义隐式转换
implicit def intToString(x: Int): String = x.toString

// 使用隐式转换
val str: String = 42// 自动转换为 "42"
2. 隐式参数

// 定义带有隐式参数的函数
def greet(name: String)(implicit greeting: String): String = {
s"$greeting, $name!"
}

// 定义隐式值
implicit val defaultGreeting: String = "Hello"

// 使用隐式参数
val message = greet("Alice")// "Hello, Alice!"

// 显式提供参数
val customMessage = greet("Bob")("Hi")// "Hi, Bob!"
3. 范例类

// 定义类型类
trait Show {
def show(a: A): String
}

// 为 Int 实现类型类
implicit val intShow: Show = new Show {
def show(a: Int): String = a.toString
}

// 为 String 实现类型类
implicit val stringShow: Show = new Show {
def show(a: String): String = a
}

// 使用类型类
def printValue(a: A)(implicit show: Show): Unit = {
println(show.show(a))
}

printValue(42)// 打印 "42"
printValue("Hello")// 打印 "Hello"
并发编程

1. Future

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

// 创建 Future
val future = Future {
Thread.sleep(1000)
42
}

// 处理 Future 结果
future.onComplete {
case scala.util.Success(value) => println(s"Result: $value")
case scala.util.Failure(exception) => println(s"Error: ${exception.getMessage}")
}

// 使用 map 和 flatMap
val futureResult = future.map(_ * 2).map(_.toString)

// 使用 for 推导式
val combinedFuture = for {
a <- Future { 10 }
b <- Future { 20 }
} yield a + b
2. Actor 模型(Akka)

import akka.actor.{Actor, ActorSystem, Props}

// 定义 Actor
class Greeter extends Actor {
def receive = {
    case "hello" => println("Hello, world!")
    case msg: String => println(s"Received: $msg")
    case _ => println("Unknown message")
}
}

// 创建 Actor 系统
val system = ActorSystem("MySystem")
val greeter = system.actorOf(Props, "greeter")

// 发送消息
greeter ! "hello"
greeter ! "How are you?"

// 关闭系统
system.terminate()
与 Java 互操纵

1. 调用 Java 代码

// 导入 Java 类
import java.util.Date

// 创建 Java 对象
val date = new Date()
println(date)

// 调用 Java 方法
val list = new java.util.ArrayList()
list.add("Scala")
list.add("Java")
println(list)
2. Java 调用 Scala 代码

// Scala 类
class ScalaClass(val name: String) {
def greet(): String = s"Hello from $name"
}

// 伴生对象
object ScalaClass {
def create(name: String): ScalaClass = new ScalaClass(name)
}
// Java 代码
ScalaClass scala = ScalaClass.create("Scala");
String greeting = scala.greet();
System.out.println(greeting);
最佳实践

1. 代码风格



[*]使用驼峰定名法
[*]类名首字母大写
[*]方法名首字母小写
[*]使用有意义的变量名
[*]得当添加注释
2. 函数式编程原则



[*]优先使用不可变数据
[*]使用纯函数
[*]克制副作用
[*]使用高阶函数和组合
3. 错误处理

// 使用 Option
def divide(a: Int, b: Int): Option = {
if (b != 0) Some(a / b) else None
}

// 使用 Try
import scala.util.Try

def safeDivide(a: Int, b: Int): Try = Try(a / b)

// 使用 Either
def parseNumber(s: String): Either = {
try {
    Right(s.toInt)
} catch {
    case _: NumberFormatException => Left(s"Invalid number: $s")
}
}
常见题目

1. 编译错误



[*]范例不匹配
[*]缺少分号
[*]括号不匹配
[*]导入错误
2. 运行时错误



[*]空指针异常
[*]范例转换错误
[*]并发题目
3. 性能题目



[*]内存泄漏
[*]过分使用递归
[*]聚集操纵效率
4. 调试技巧



[*]使用 println 调试
[*]使用 IDE 调试器
[*]使用日志框架
[*]单元测试
学习资源



[*]Scala 官方文档
[*]Scala School
[*]Scala 编程(册本)
[*]Scala 函数式编程(册本)
[*]Coursera Scala 课程

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Scala 入门指南