马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
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[String] = 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[Int]): 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[A] {
- def show(a: A): String
- }
- // 为 Int 实现类型类
- implicit val intShow: Show[Int] = new Show[Int] {
- def show(a: Int): String = a.toString
- }
- // 为 String 实现类型类
- implicit val stringShow: Show[String] = new Show[String] {
- def show(a: String): String = a
- }
- // 使用类型类
- def printValue[A](a: A)(implicit show: Show[A]): 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")
- // 发送消息
- 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[String]()
- 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[Int] = {
- if (b != 0) Some(a / b) else None
- }
- // 使用 Try
- import scala.util.Try
- def safeDivide(a: Int, b: Int): Try[Int] = Try(a / b)
- // 使用 Either
- def parseNumber(s: String): Either[String, Int] = {
- 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企服之家,中国第一个企服评测及商务社交产业平台。 |