0%

Scala 模式匹配:超越 switch 的强大匹配机制

模式匹配是 Scala 中最具特色的功能之一,它不仅能替代 Java 中的 switch...case,还支持类型匹配、集合匹配、对象匹配等复杂场景,甚至可以结合条件判断实现灵活的逻辑分支。本文将全面解析 Scala 模式匹配的语法、特性及应用场景。

基本语法:match 与 case

Scala 模式匹配通过 match 关键字定义匹配主体,case 关键字定义分支,语法简洁且功能强大。

基本用法(类似 switch)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
val operator: Char = '*'
val num1: Int = 10
val num2: Int = 2

// 匹配运算符,执行对应计算
val result = operator match {
case '+' => num1 + num2
case '-' => num1 - num2
case '*' => num1 * num2
case '/' => num1 / num2
case _ => throw new Exception("不支持的运算符") // 默认分支,类似 default
}

println(result) // 输出:20

核心特点

  • 每个 case 分支通过 => 连接匹配条件和执行逻辑。
  • 匹配成功后自动退出(无需 break),效率高于 Java 的 switch
  • case _ 表示默认分支,匹配所有未被其他分支覆盖的情况。

与 Java switch 的区别

特性 Scala 模式匹配 Java switch
匹配类型 支持值、类型、集合、对象等 仅支持基本类型、枚举、字符串(Java 7+)
分支执行 自动退出(无需 break) 需要显式 break,否则穿透
返回值 整个 match 表达式有返回值 无返回值(需手动赋值)
默认分支 case _ default

类型匹配:根据数据类型分支

Scala 模式匹配可直接根据变量的运行时类型进行分支,无需显式调用 isInstanceOf

示例:匹配不同类型

阅读全文 »

Scala 集合操作:高阶函数与函数式编程精髓

Scala 集合的强大之处不仅在于丰富的数据结构,更在于其提供的一系列高阶函数操作。这些操作允许将函数作为参数传递,实现简洁、高效的函数式编程风格,极大提升了数据处理的灵活性和可读性。本文将深入解析 Scala 集合的核心操作(映射、过滤、化简等),并展示如何利用高阶函数简化代码。

高阶函数基础

高阶函数是指可以接收函数作为参数或返回函数的函数,是 Scala 函数式编程的基础。集合操作大量依赖高阶函数,实现对元素的批量处理。

定义与示例

1
2
3
4
5
6
7
8
9
10
11
// 高阶函数:接收一个函数参数 (Int => Int) 和一个 Int,返回 Int
def process(f: Int => Int, num: Int): Int = f(num)

// 普通函数:将输入翻倍
def double(x: Int): Int = x * 2

// 调用高阶函数(传递函数作为参数)
println(process(double, 5)) // 输出:10(等价于 double(5))

// 调用时使用匿名函数(更简洁)
println(process(x => x + 3, 5)) // 输出:8

核心特点

  • 函数作为参数时,需指定其类型(如 f: Int => Int 表示接收 Int 并返回 Int 的函数)。
  • 可直接传递命名函数(如 double)或匿名函数(如 x => x + 3)。

映射操作(map 与 flatMap)

映射操作通过传入的函数转换集合中的每个元素,生成新集合。

1. map:一对一转换

map 对集合中的每个元素应用函数,返回一个新集合(元素数量与原集合相同)。

阅读全文 »

MySQL 大小写敏感问题详解:从字符集到实际应用

MySQL 中字符串查询的大小写敏感行为,主要由字符集的校对规则(Collation) 决定,而非字符集本身。查询返回 aA 两条记录的问题,正是由于默认校对规则 utf8_general_ci 不区分大小写导致的。本文详细解析这一机制及解决方案。

核心概念:字符集与校对规则

字符集(Character Set)

定义字符的编码方式(如 utf8utf8mb4),决定如何存储字符(如 a 存储为 0x61A 存储为 0x41)。

校对规则(Collation)

定义字符的比较规则,决定如何判断两个字符是否相等。大小写敏感行为由校对规则控制,而非字符集。

常见的 utf8 系列校对规则:

  • utf8_general_cici 即 Case-Insensitive(不区分大小写),aA 被视为相等。
  • utf8_binbin 即 Binary(二进制比较),严格区分大小写,a0x61)与 A0x41)被视为不同。
  • utf8_unicode_ci:不区分大小写,但比 utf8_general_ci 更符合 Unicode 标准(如支持德语、法语特殊字符的正确排序)。

默认规则

  • 当指定字符集为 utf8 而未指定校对规则时,MySQL 会自动使用默认校对规则 utf8_general_ci(不区分大小写),这就是你遇到问题的原因。

查询当前字符集与校对规则

查看数据库的字符集和校对规则

阅读全文 »

MySQL 日志系统全解析:类型、作用与实战配置

MySQL 的日志系统是数据库运维、故障排查和数据恢复的核心支撑,包含六种关键日志:事务日志(redo log、undo log)、二进制日志(binlog)、错误日志、慢查询日志、一般查询日志、中继日志(relay log)。每种日志各司其职,共同保障数据库的稳定性、可追溯性和一致性。

事务日志:保障事务的 ACID 特性

事务日志是 InnoDB 引擎特有的日志,专门用于保证事务的原子性、一致性和持久性,分为重做日志(redo log)和回滚日志(undo log)。

1. 重做日志(redo log):保证持久性与原子性

核心作用:

当 MySQL 宕机时,通过 redo log 恢复未刷盘的脏页数据,确保事务提交后的数据不丢失(持久性)。

工作原理:

InnoDB 采用 WAL(Write-Ahead Logging,预写式日志) 机制:

  • 数据修改时,先写入内存中的 redo log buffer,再异步 / 同步刷入磁盘的 redo log file
  • 同时修改内存缓冲池(Buffer Pool)中的数据页(脏页),脏页会定期异步刷入磁盘;
  • 若宕机,重启时通过 redo log 回放未刷盘的脏页操作,恢复数据。

redo log 记录的是物理日志(如 “数据页 X 的偏移量 Y 处修改为 Z”),与具体 SQL 无关。

存储与配置:
  • 存储位置:默认在数据目录下,以 ib_logfile0ib_logfile1 命名(循环写入,满后覆盖旧日志)。

  • 关键配置

阅读全文 »

Scala 集合:不可变与可变的完美融合

Scala 集合框架是处理数据集合的核心工具,其设计兼顾了不可变性(线程安全、函数式编程友好)和可变性(性能优化、状态修改),提供了丰富的数据结构(序列、集合、映射等)和操作方法。本文将系统解析 Scala 集合的层级结构、核心类型及常用操作,帮助你高效处理各类数据集合。

集合框架概览

Scala 集合分为两大体系:不可变集合(默认)和可变集合,分别位于不同的包中:

  • 不可变集合scala.collection.immutable,集合创建后无法修改,所有操作返回新集合。

    不可变集合

  • 可变集合scala.collection.mutable,集合可直接修改,操作效率更高。

    可变集合层级关系

核心特质与继承关系

所有集合都扩展自 Iterable 特质,主要分为三大类:

  1. Seq(序列):有序集合(如数组、列表、队列),元素按顺序访问,可通过索引访问。
  2. Set(集合):无序集合,元素唯一,无重复值。
  3. Map(映射):键值对集合,键唯一,值可重复。

序列(Seq)

序列是有序集合,支持索引访问,核心类型包括数组(Array)、变长数组(ArrayBuffer)、列表(List)、队列(Queue)等。

定长数组(Array)

与 Java 数组类似,长度固定,初始化后不可修改,支持泛型。

定义方式
1
2
3
4
5
6
7
// 方式1:指定长度和类型(默认值为0、null等)
val arr1 = new Array[Int](5) // 长度为5的Int数组,默认值0
val arr2 = new Array[String](3) // 长度为3的String数组,默认值null

// 方式2:直接初始化元素(调用apply方法)
val arr3 = Array(1, 2, 3, 4) // Int数组:Array(1, 2, 3, 4)
val arr4 = Array("a", "b", "c") // String数组:Array(a, b, c)
常用操作
阅读全文 »