当前位置: 首页 > news >正文

CppCon 2015 学习:Simple, Extensible Pattern Matching in C++14

什么是 Pattern Matching(模式匹配)

模式匹配就是一种“描述式”的写法,不需要你手动判断、提取数据,而是直接描述你希望的数据结构是什么样子,系统自动判断并提取。❞

你给的定义拆解:

✴ Instead of explicitly extracting and testing…

传统写法是这样的:

if (shape.type == "circle") {double r = shape.radius;// do something
} else if (shape.type == "rectangle") {double w = shape.width;double h = shape.height;// do something
}

这种方式需要你先判断类型,再显式地提取数据成员。这就是“explicitly extracting and testing”。

Pattern Matching 改写为:

match shape {Circle(r) => { /* use r directly */ },Rectangle(w, h) => { /* use w and h directly */ },
}

直接描述想要的结构,比如一个 Circle(r),系统就会帮你提取 r,而不需要你去“访问属性”。
你也可以把它想象成这样:

正则表达式模式匹配
匹配文本结构匹配数据结构
提取子串提取子字段
(\d+)-(\w+)Rectangle(w, h)
if (x matches pattern)match x { pattern => ... }

总结一句话

模式匹配 = 数据结构的“正则表达式”

它让你声明你想要的数据形状,并在匹配时自动提取内容并处理

这是一个 经典的 C++ switch-case 语句例子,它展示了 在运行时对整型变量 i 进行分支匹配的能力。下面是对这段代码的逐行解释:

原始代码:

switch (i) {case 1:std::cout << "one";break;case 2:std::cout << "two";break;case 3:std::cout << "three";break;default:std::cout << "unknown";
}

代码含义:

  • switch (i):根据变量 i 的值,进入匹配的分支。
  • case 1::如果 i == 1,输出 “one”。
  • case 2::如果 i == 2,输出 “two”。
  • case 3::如果 i == 3,输出 “three”。
  • default::如果不匹配任何 case,输出 “unknown”。

特点:

特性说明
运行时匹配编译时无法确定分支走向,必须等 i 的值在运行时才知道。
整型值支持传统 switch 只支持 intenum 类型。
手动 break每个分支后需要加 break 防止“贯穿执行”到下一个 case。
default 备选default 分支相当于“else”逻辑。

类比模式匹配(Pattern Matching)

switch 是一种最基础的“模式匹配”形式,但功能非常有限:

特性switch模式匹配(如 Rust)
支持数据结构仅支持整数值匹配支持结构体/枚举/元组等
自动提取字段不能自动解构(如 Point(x, y)
表达式形式语句形式,不能直接赋值可作为表达式返回值

这段 Haskell 代码是关于 模式匹配(Pattern Matching)元组 / 列表的分解式函数定义,下面是对每一部分的详细解释和理解:

一、函数定义:提取三元组中的元素

first :: (a, b, c) -> a
first (x, _, _) = x
  • 类型签名 :: (a, b, c) -> a 表示:函数 first 接收一个三元组 (a, b, c),返回其中的第一个元素 a
  • (x, _, _) = x 使用模式匹配提取第一个值,忽略其他两个(用 _ 表示不关心)。
    类似的:
second :: (a, b, c) -> b
second (_, y, _) = y
third :: (a, b, c) -> c
third (_, _, z) = z

这些函数从三元组中提取第二、第三个元素。

二、列表分析函数 describeList

describeList :: [a] -> String
describeList xs = "The list is " ++ case xs of[]   -> "empty."[x]  -> "a singleton list."xs   -> "a longer list."
类型说明:
  • :: [a] -> String 表示该函数接收一个任意类型元素的列表,返回一个 String 描述。
逻辑说明:
  • case xs of 使用 模式匹配 来分析 xs 的结构:
    模式匹配条件返回文本
    []空列表"empty."
    [x]只包含一个元素的列表"a singleton list."
    xs(默认)多于一个元素的列表"a longer list."
示例:
describeList []         -- "The list is empty."
describeList [42]       -- "The list is a singleton list."
describeList [1,2,3]    -- "The list is a longer list."

三、总结

概念说明
模式匹配(Pattern Matching)Haskell 的核心特性,可在函数参数、case 表达式中直接分解数据结构。
元组分解(x, _, _) 形式表示从三元组中提取出想要的元素。
列表匹配[], [x], xs 等用于分别匹配空列表、单元素列表、多元素列表。
表达式匹配 + 拼接使用 ++ 拼接字符串,用 case 对输入做结构匹配判断并产生不同返回值。

你给出的这段代码是 Rust 中 模式匹配(match 的典型用法。下面是对它的完整解释:

代码回顾

let x = 1;
match x {1 | 2 => println!("one or two"), 3 => println!("three"),_ => println!("anything"), 
}

逐行解释

let x = 1;

  • 这行代码定义了一个变量 x,它的值为 1

match x { ... }

这是 Rust 中的 模式匹配结构,类似于其他语言中的 switch,但更强大。
Rust 的 match 表达式根据变量的值与不同的 模式(patterns) 进行匹配,一旦匹配成功,就执行对应的代码块。

分支解释:

1 | 2 => println!("one or two"),
  • 1 | 2 表示:如果 x 是 1 或 2,就执行这一分支。
  • | 是逻辑“或”的模式匹配用法(不是布尔操作)。
3 => println!("three"),
  • x == 3 时匹配这个分支。
_ => println!("anything"),
  • _ 是通配符,表示“其他任何情况”。
  • 如果 x 不是 1、2 或 3,就会匹配这个分支。

本例中运行结果

由于 x = 1,因此匹配第一个分支:

one or two

总结

结构说明
match用于模式匹配变量的值
``匹配多个值中的任一个
_匹配所有未被显式列出的情况
=>分支体开始

小技巧

  • match 在 Rust 中是表达式(expression),所以它可以返回值。
  • 分支是穷尽性匹配,编译器会强制你覆盖所有可能性,或使用 _ 兜底。
  • match 也可以解构结构体、枚举、元组、引用等,功能非常强大。

这段 Rust 代码展示了 模式匹配(pattern matching) 在元组(tuple)上的用法。我们来逐步理解它:

原始代码

let tup = (1, 0);
match tup {(0, 0) => println!("both zero"),(x, 0) => println!("{} and zero", x),(0, y) => println!("zero and {}", y),_      => println!("did not match"),
}

变量定义

let tup = (1, 0);
  • 创建了一个元组变量 tup,其值是 (1, 0)

match 分支解析

Rust 的 match 会从上到下尝试匹配每个模式:

(0, 0) => println!("both zero")

  • 匹配元组两个元素都是 0 的情况。
  • 当前是 (1, 0)不匹配

(x, 0) => println!("{} and zero", x)

  • 匹配元组第二个元素为 0,第一个元素任意(绑定为 x)。
  • 当前是 (1, 0)匹配成功
  • 执行:println!("{} and zero", x),输出:
1 and zero

匹配成功后,match 结构结束,不会继续匹配下面的分支。

(0, y) => println!("zero and {}", y)

  • 匹配第一个是 0,第二个任意的元组。
  • 当前不匹配,因此不会执行。

_ => println!("did not match")

  • _ 是通配符:匹配所有未匹配到的情况。
  • 本例中没走到这一分支。

运行结果

1 and zero

小结

模式含义匹配 (1, 0) 吗?
(0, 0)两个都是 0
(x, 0)第二个是 0,第一个绑定为 x
(0, y)第一个是 0,第二个绑定为 y
_其他任何情况(兜底)不会执行
如果你想学习更多 Rust 中的模式匹配技巧,例如:
  • 匹配结构体和枚举
  • 使用 match guard(例如 if x > 0
  • 模式绑定的细节(如 @ 绑定)

这段 Rust 代码展示了如何使用 枚举(enum)和模式匹配(match 来处理不同类型的消息(Message)。我们来逐步分析和理解它:

枚举定义

enum Message {Quit,ChangeColor(i32, i32, i32),Move { x: i32, y: i32 },Write(String),
}

这定义了一个 Message 类型,它有 4 种变体(variants):

变体名类型描述
Quit无数据退出指令
ChangeColor包含三个 i32 参数改变颜色(RGB)
Move是一个具名结构体样式的变体移动到 (x, y) 坐标位置
Write包含一个 String输出字符串

process_message 函数

fn process_message(msg: Message) {match msg {Message::Quit => quit(),Message::ChangeColor(r, g, b) => change_color(r, g, b),Message::Move { x: x, y: y } => move_cursor(x, y),Message::Write(s) => println!("{}", s),};
}

该函数接收一个 Message 类型的参数,然后使用 match 匹配它是哪种变体,并执行相应的操作。

逐个分支解释

1. Message::Quit => quit()
  • 如果是 Quit 变体,调用 quit() 函数。
  • 不包含任何数据。
2. Message::ChangeColor(r, g, b) => change_color(r, g, b)
  • 如果是 ChangeColor,提取出三个整数,绑定为 r, g, b,然后传给 change_color 函数。
  • 这是 位置匹配(positional matching)
3. Message::Move { x: x, y: y } => move_cursor(x, y)
  • 如果是 Move 变体,它是具名字段结构体形式。
  • 提取 xy 字段,传入 move_cursor(x, y)
  • 可以简写为 { x, y } 而不是 { x: x, y: y }
4. Message::Write(s) => println!("{}", s)
  • 如果是 Write(String),提取出字符串 s,并打印。

简写优化(推荐写法)

你可以把 x: x, y: y 简写为 x, y

Message::Move { x, y } => move_cursor(x, y)

示例调用

process_message(Message::Quit);
process_message(Message::Write("Hello!".to_string()));
process_message(Message::Move { x: 10, y: 20 });
process_message(Message::ChangeColor(255, 0, 0));

小结

这个例子体现了 Rust 的模式匹配能力:

  • 适用于结构体、枚举、元组等
  • 自动解构并绑定变量
  • 简洁且类型安全
    如果你来自其他语言(如 C++、Java),可以把这理解为:
  • enum 是 tagged union + 类型安全
  • match 类似 switch,但更强大,可解构结构体和元组

后面应该是介绍这个c++怎么实现的看不懂 知道模式匹配这个东西就行

https://github.com/jbandela/simple_match

相关文章:

  • 中文分词双向匹配
  • .Net 优秀框架 ABP全面详解
  • 【JMeter】接口断言
  • “一张网,万般用”——聊聊网络虚拟化到底怎么实现的
  • 数据库管理与高可用-MySQL故障排查与生产环境优化
  • 当文化遇见科技:探秘国际数字影像创新生态高地
  • 华硕a豆14 Air香氛版,美学与科技的馨香融合
  • 北京智乐活科技有限公司 适趣ai 二面 全栈
  • FAISS:高性能向量库
  • 佰力博科技与您探讨热释电测量的几种方法
  • RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
  • 博睿数据×华为, 共筑智慧金融新未来
  • React Native 是什么?为什么学它?
  • 井云科技|智能体变现新路径:从开发到盈利的关键跨越
  • day51 python CBAM注意力
  • 前端面试题 微信小程序兼容性问题与组件适配策略
  • Mysql8 忘记密码重置,以及问题解决
  • OpenGL-什么是软OpenGL/软渲染/软光栅?
  • MFC 抛体运动模拟:常见问题解决与界面美化
  • 关于MQ之kafka的深入研究
  • 淘宝网站c#设计怎么做/百度惠生活怎么优化排名
  • 那个网站的公众后推广做的好/重庆seo教程
  • 用html做简单网站/竞价推广账户竞价托管费用
  • 网站建设技术部奖惩制度/免费发布产品信息的网站
  • wap移动建站系统/百度竞价投放
  • 江苏建设集团招聘信息网站/网络营销有本科吗