Rust之枚举和模式匹配(二):控制流程结构match

Rust模式匹配 模式匹配是从函数式编程语言(例如:Haskell,Lisp)吸收而来的,用于为复杂的类型系统提供一个轻松的解构能力。rust使用match来提供模式匹配的功能。mathc类似于其它编程语言中的switch-case,但是远比switch-case强大。match的通用模式如下所示。该形式清晰的说明了何为模式,何为模式匹配:将模式与 target 进行匹配,即为模式匹配,而模式匹配不仅仅局限于 match,还有if let。 阅读详情

开发环境

  • Windows 10
  • Rust 1.59.0

 

  •  VS Code 1.65.2 

 项目工程

这里继续沿用上次工程rust-demo

 控制流程结构 - match

Rust有一个非常强大的控制流构造,称为match,它允许您将一个值与一系列模式进行比较,然后根据匹配的模式执行代码。模式可以由文字值、变量名、通配符和许多其他东西组成;后面涵盖了所有不同种类的模式以及它们的作用。match的强大之处在于模式的表现力,以及编译器确认所有可能的情况都被处理的事实。 

把一个match表达式想象成一个硬币分拣机:硬币沿着一条轨道滑下,轨道上有不同大小的洞,每个硬币通过它遇到的第一个洞落入。以同样的方式,值通过match中的每个模式,在第一个模式中,值“适合”,该值落入在执行期间使用的相关代码块中。说到硬币,我们就以使用match为例吧!我们可以编写一个函数,用一种类似于计数机的方法,获取一枚未知的美国硬币,确定它是哪一枚硬币,并返回它的美分值,如下所示:

// 枚举
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

// 函数
fn value_in_cents(coin: Coin) -> u8 {
    // match使用
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

让我们在value_in_cents函数中分解match。首先,我们列出match关键字,后跟一个表达式,在本例中是值coin。这似乎与if使用的表达式非常相似,但有一个很大的区别:使用if,表达式需要返回一个布尔值,但在这里,它可以返回任何类型。这个例子中的coin类型是我们在第一行定义的硬Coin枚举。

接下来是match体。有两个部分:一个模式和一些代码。这里的第一个分支有一个模式,它是值Coin::Penny,然后是=>操作符,它将模式和要运行的代码分开。这种情况下的代码只是值1。每条分支都用逗号隔开。

当match表达式执行时,它将结果值与每个分支的模式依次进行比较。如果模式与该值匹配,则执行与该模式关联的代码。如果模式与值不匹配,执行将继续到下一个分支,就像硬币分拣机一样。我们可以有任意多的分支,在上述实例中,我们的match有四个分支。

与每个分支相关联的代码是一个表达式,匹配分支中的表达式的结果值是整个match表达式返回的值。

如果匹配分支代码很短,我们通常不使用花括号,如上例所示,其中每个分支只返回一个值。如果你想在一个匹配臂中运行多行代码,你必须使用花括号。例如,下面的代码打印“幸运便士!”每次用Coin::Penny调用方法,但还是返回块的最后一个值,1:

fn value_in_cents(coin: Coin) -> u8 {
    match coin {   // match表达式
        Coin::Penny => {  // 这里返回块
            println!("Lucky penny!");
            1
        }
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

绑定到值的模式

match表达式的另一个有用特性是,它们可以绑定到值中与模式匹配的部分。这就是我们如何从枚举变量中提取值。

作为一个例子,让我们改变我们的一个枚举变量来保存数据。从1999年到2008年,美国铸造了50个州不同设计的硬币。没有其他硬币有州图案,所以只有25美分硬币有这种额外的价值。我们可以通过改变Quarter变量来将这个信息添加到我们的enum中,在它里面存储一个UsState值,如下所示:

#[derive(Debug)] // 调试模式
enum UsState {  // 枚举变量
    Alabama,
    Alaska,
    // --snip--
}

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),     // Quarter
}

让我们想象一个朋友正试图收集所有50个州的硬币。当我们按硬币类型对零钱进行分类时,我们还会喊出与每个硬币相关的州名,这样如果我们的朋友没有硬币,他们就可以将其添加到收藏中。

在这段代码的match表达式中,我们将一个名为state的变量添加到匹配变量Coin::Quarter的模式中。当Coin::Quarter匹配时,state变量将绑定到该Quarter的状态值。然后我们可以在分支的代码中使用状态,就像下面这样: 

fn value_in_cents(coin: Coin) -> u8 {
    match coin {    // match表达式
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {     // Quarter
            println!("State quarter from {:?}!", state);
            25
        }
    }
}

如果我们调用value _ in _ cents(Coin::Quarter(UsState::Alaska)),coin将是Coin::Quarter(UsState::Alaska)。当我们将该值与每个匹配分支进行比较时,在到达Coin::Quarter(state)之前,没有一个匹配。此时,state的绑定将是值UsState::Alaska。然后我们可以在println!表达式使用该绑定,从而从coin枚举变量中获得Quarter的内部状态值。

使用Option< T >匹配

在上一节中,我们想在使用Option<T >时从some中获取内部T值;我们也可以像处理Coin枚举一样使用match来处理Option<T >!我们将比较Option< T >的变体,而不是比较硬币,但是match表达式的工作方式保持不变。

假设我们想写一个函数,它接受一个Option< i32 >,如果里面有一个值,就给这个值加1。如果里面没有值,函数应该返回None值,并且不尝试执行任何操作。

多亏了match,这个函数非常容易编写,如下所示:

fn main() {
    fn plus_one(x: Option<i32>) -> Option<i32> {
        match x {                // match表达式
            None => None,
            Some(i) => Some(i + 1),
        }
    }

    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);

    println!("value five = {:#?}", five);    // 输出类型
    println!("value six = {:#?}", six);
    println!("value none = {:#?}", none);
}

编译运行

cargo run

让我们更详细地检查一下plus_one的第一次执行。当我们调用plus_one(five)时,plus_one主体中的变量x将具有值Some(5)。然后我们将它与每个匹配分支进行比较,

None => None,

Some(5)值与模式None不匹配,所以我们继续下一个分支,

Some(i) => Some(i + 1),

Some(5)和Some(i)匹配吗?为什么是这样呢?我们有相同的变体。i绑定到Some中包含的值,所以i取值5。然后执行match分支中的代码,因此我们将i的值加1,并创建一个新的Some值,其中包含我们的总计6。

现在让我们考虑上例种对plus_one的第二次调用,其中x是None。我们进入match,并与第一条进行比较,

None => None,

完全吻合,没有要添加的值,所以程序停止并返回=>右侧的None值。因为第一条匹配,所以不比较其他分支。

在许多情况下,将match和枚举结合起来是很有用的。你会在Rust代码中经常看到这种模式:match一个枚举,将一个变量绑定到里面的数据,然后基于它执行代码。一开始有点棘手,但是一旦你习惯了,你会希望在所有语言中都有它。这一直是用户的最爱。

匹配是详尽的

我们还需要讨论match的另一个方面。考虑一下这个版本的plus_one函数,它有一个错误,不能编译:

fn main() {
    fn plus_one(x: Option<i32>) -> Option<i32> {
        match x {          // match表达式
            Some(i) => Some(i + 1),
        }
    }

    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);
}

我们没有处理None的情况,所以这段代码会导致一个bug。幸运的是,这是一只锈菌知道如何捕捉的虫子。如果我们试图编译这段代码,我们会得到这个错误:

编译

cargo run

Rust知道我们没有涵盖所有可能的情况,甚至知道我们忘记了哪个模式!Rust中的匹配是穷尽的:为了使代码有效,我们必须穷尽所有的可能性。特别是在Option<T >的情况下,当Rust防止我们忘记显式处理None的情况时,它防止我们在可能有null时假设我们有一个值,从而使前面讨论的十亿美元的错误不可能发生。 

包罗万象的模式和 _占位符

使用枚举,我们还可以对一些特定的值采取特殊的操作,但是对所有其他的值采取一个默认的操作。想象一下,我们正在实现一个游戏,如果你掷骰子掷出一个3,你的玩家不动,而是得到一顶新的漂亮的帽子。如果你掷出7,你的玩家将失去一顶漂亮的帽子。对于所有其他值,你的玩家在棋盘上移动该数量的空格。这里有一个实现该逻辑的match,骰子滚动的结果是硬编码的,而不是随机值,所有其他逻辑都由没有主体的函数表示,因为实际实现它们超出了本例的范围:

let dice_roll = 9;
    match dice_roll {    // match表达式
        3 => add_fancy_hat(),
        7 => remove_fancy_hat(),
        other => move_player(other),
    }

fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn move_player(num_spaces: u8) {}

对于前两个分支,模式是文字值3和7。对于覆盖所有other可能值的最后一个分支,模式是我们选择命名为other的变量。为另一只分支运行的代码通过将变量传递给move_player函数来使用该变量。

尽管我们没有列出u8可能具有的所有值,但是这段代码可以编译,因为最后一个模式将匹配所有没有特别列出的值。这种包罗万象的模式满足了match必须详尽的要求。请注意,我们必须将捕获分支放在最后,因为模式是按顺序计算的。Rust会警告我们,如果我们在一个总括之后添加武器,因为那些后来的武器永远不会匹配!

Rust还有一个模式,当我们不想使用catch-all模式中的值时,我们可以使用这个模式:_,这是一个特殊的模式,它匹配任何值,并且不绑定到那个值。这告诉Rust我们不会使用这个值,所以Rust不会警告我们一个未使用的变量。

所以上述示例可以更改为:

  let dice_roll = 9;
    match dice_roll {
        3 => add_fancy_hat(),
        7 => remove_fancy_hat(),
        _ => reroll(),        // _占位符
    }

fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn reroll() {}

这个例子也满足了穷举要求,因为我们显式地忽略了最后一个分支中的所有其他值;我们什么都没忘记。

如果我们再改变一次游戏规则,如果你掷出的不是3或7,那么在你的回合中不会发生任何事情,我们可以通过使用单位值(元组类型”一节中提到的空元组类型)作为_ 分支的代码来表达这一点:

let dice_roll = 9;
    match dice_roll {
        3 => add_fancy_hat(),
        7 => remove_fancy_hat(),
        _ => (),           // _占位符
    }

fn add_fancy_hat() {}
fn remove_fancy_hat() {}

在这里,我们明确地告诉Rust,我们不会使用与早期分支中的模式不匹配的任何其他值,并且我们不想在这种情况下运行任何代码。

现在,我们将继续讨论if let语法,这在match表达式有点冗长的情况下很有用。

本章重点

  • match表达式
  • 绑定到值的模式
  • _占位符
常见信号逻辑电平标准介绍:TTL、CMOS、ECL、LVDS、CML 逻辑电平是指数字信号电压的高、低电平,相关参数定义如下:(1)输入高电平门限Vih:保证逻辑门的输入为高电平时所允许的最小输入高电平,当输入电平高于Vih时,则认为输入电平为高电平;(2)输入低电平门限Vil:保证逻辑门的输入为低电平时所允许的最大输入低电平,当输入电平低于Vil时,则认为输入电平为低电平;(3)输出高电平门限Voh:保证逻辑门的输出为高电平时的输出电平的最小值,逻辑门的输出为高电平时的电平值都必须大于此Voh; 阅读详情

相关推荐

Fluent 中多相流模型全面解析

3.颗粒或液滴在连续相中的运动:若关注颗粒或液滴在连续相中的运动轨迹、分布规律以及与连续相的相互作用,如喷雾干燥、气力输送等过程,Eulerian-Lagrangian 模型则是最佳选择。Eulerian-Eulerian 模型可以准确模拟气体在固体颗粒中的流动情况,包括颗粒的流化状态、气体与颗粒之间的传热传质过程,为气固流化床的优化设计和操作提供依据。通过该模型,可以了解混合器内不同位置的混合程度、颗粒的运动轨迹以及液固相间的相互作用,从而改进混合器的结构和操作条件,提高混合效率。

khhdp的博客 3087

Rust:Match语句详解

Rust book里一个简单的例子: 当你在 => 后执行的语句不止一条时,需要加 {}: Match语句的exhaustive(穷尽)特性: match语句存在一个exhaustive特性,我觉得可以翻译为“穷尽”。也就是说match语句要求穷尽value的所有pattern。 当你不想穷尽所有可能的pattern的时候,Rust也提供了相应的解决办法:_ placeholder 比如 u8 的范围为0~255,我们可能只关心其中几个“pattern” :1,3,5,7。这时候可以用_

weixin_52617269的博客 5221

图信号处理中的多尺度分析:图小波变换与图傅里叶变换的对比与应用

本文深入探讨了图信号处理中的多尺度分析方法,重点对比了图小波变换(GWT)与图傅里叶变换(GFT)的技术特点与应用场景。通过分析图的拓扑结构,GWT展现出强大的局部洞察力,适用于异常检测和社区发现;而GFT则擅长全局频率分析,适合趋势分析和信号去噪。文章结合实战案例,为读者提供了方法选型指南和前沿进展,帮助开发者在生物信息学、社交网络分析等领域高效应用这些技术。

weixin_30369041的博客 406

RUST中match语法的一个疑难点解析

RUST在针对引用类型做match时,match对类型的处理上会有一些使人困惑的地方,本文做了解释

weixin_45429253的博客 2051

基于互相关(NCC)模板匹配——find_ncc_model_defocused.hdev

相关性原理:仅在NCC(r,c) = ±1时,模板与图像完全匹配; NCC绝对值越大,表示模板与正在检测部分图像越接近; NCC绝对值越接近于零,表示模板与图像越不一致。 线性光照变化不会影响NCC计算结果。 重要函数一: 创建模板:create_ncc_model( Template : : NumLevels, AngleStart, AngleExtent, AngleStep, Metric : ModelID) 参数列表: Template(in):单通道灰度图像,它的区域可被创建为模板。 Num

m0_51271525的博客 3413

Linux系统下Materials Studio 2020安装避坑指南:从依赖包到许可证配置全流程

本文提供了一份在Linux系统上安装Materials Studio 2020的深度避坑指南。详细解析了从系统依赖包检查、安装流程、许可证配置到Gateway服务部署的全过程,并分享了与Slurm作业调度系统集成的实战经验,旨在帮助用户高效、稳定地完成部署。

weixin_29313547的博客 387

Rust语言中match详解

表达式是Rust中一种强大而灵活的工具,它可以帮助我们处理各种条件和变量取值的情况。通过合理使用模式匹配,我们可以编写更清晰、更健壮的代码。根据不同的硬币类型,我们执行相应的代码逻辑,并返回对应的价值。的模式,并根据变量的取值与模式匹配情况来选择执行相应的代码块。类型一起使用,用于根据变量的不同取值执行不同的代码逻辑。是一个用于模式匹配的关键字。下面是一个简单的例子,展示了如何使用。是一个枚举类型,表示不同的硬币。由一个模式和相应的代码块组成。表达式执行时,它会逐个检查每个。时,我们返回5,以此类推。

金夔窳镞 1153

让 ABAP 程序天生可翻译:Text Symbols 与 Text Pool 从入门到工程化落地

ABAP 国际化实践:Text Symbols 的工程价值与落地方法 摘要: 本文系统阐述了 ABAP 开发中 Text Symbols 的核心价值与实践方法。通过解耦程序逻辑与语言文本,Text Symbols 实现了代码国际化,避免了硬编码带来的维护难题。文章详细介绍了 Text Pool 结构、两种引用方式(独立引用 TEXT-001 和附着式 '(001)'),以及 SE38 和 SE63 的翻译流程。特别强调最大长度预留、术语统一等工程实践,并提供了 READ TEXTPOOL 自动化检查方案。最

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 239

Rust中的match控制流:枚举的强大搭档

在Rust中,`match`是一种强大的控制流结构,特别适合与枚举(`enum`)一起使用。`match`允许你根据枚举的不同变体执行不同的代码逻辑,并且编译器会强制检查是否覆盖了所有可能的情况,从而避免运行时错误。本文将详细介绍`match`的用法,并通过具体示例展示如何用它处理枚举。

美味小鱼的杂货铺 885

利用dddd_trainer训练通用验证码识别模型

博文介绍了使用dddd_trainer工具训练自定义验证码识别模型的过程,详细展示了从环境搭建、数据集准备到模型训练的全流程。

九月镇灵将的博客 1033

【车载以太网】【架构】整体架构与协议标准

车载以太网架构图 应用层:DHCP /SOMEIP/DoIP/XCP/UDPNM 传输层:TCP/IP 网络层:IPv4/IPv6/ARP/ICMP 链路层:IEEE Ethernet MAC+VLAN 物理层:Ethernet PHY: 100BASE-T1/1000BASE-T1/100BASE-Tx

专注汽车软件开发、AutoSAR、车载以太网、SOA、EE架构。 8357

Rust 模式匹配语法详解

Rust的模式匹配是一种强大的特性,主要通过match表达式实现,支持多种模式类型和语法形式。核心要点包括: 基本match语法:匹配值并执行对应代码块,必须覆盖所有可能情况,可使用_通配符。 常见模式类型: 字面值、变量、通配符模式 范围模式(1..=5) 结构体和枚举模式(解构数据) 元组模式 高级特性: 守卫(guard):用if添加额外匹配条件 if let/while let简化单模式匹配 所有权注意事项:使用ref/&避免移动 特点: 编译时穷尽性检查 无运行时

本博客分享软硬件一体化开发实战。硬件涵盖 PCB 设计、STM32 等 MCU 底层开发;软件包含 C++、Rust,Qt/QML、PyQt、Slint、TouchGFX、LVGL 各类 GUI 框架。方便软硬件开发者查阅学习。欢迎关注! 1672

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Rust权威指南之枚举和模式匹配

本文来源于阅读《Rust权威指南》第六章:枚举和模式匹配的读书笔记。快速了解Rust中关于枚举和模式匹配的相关知识。

学习和工作总结,共勉! 963

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Rust编程从入门到精通 枚举和模式匹配

让我们看看一个需要诉诸于代码的场景,来考虑为何此时使用枚举更为合适且实用。假设我们要处理 IP 地址。目前被广泛使用的两个主要 IP 标准:IPv4(version four)和 IPv6(version six)。这是我们的程序可能会遇到的所有可能的 IP 地址类型:所以可以 枚举 出所有可能的值,这也正是此枚举名字的由来。任何一个 IP 地址要么是 IPv4 的要么是 IPv6 的,而且不能两者都是。IP 地址的这个特性使得枚举数据结构非常适合这个场景,因为枚举值只可能是其中一个成员。

wanmeijuhao的博客 831

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

【跟小嘉学 Rust 编程】十八、模式匹配(Patterns and Matching)

模式是Rust的一种特殊语法,用于匹配复杂的和简单类型的结构,模式与匹配表达式和其他构造结合使用,可以更好的控制流。模式由下列元素或组合组成字面值解构的数组、enum、struct、tuple变量通配符占位符想要使用模式,需要将其与某个值进行比较,如果模式匹配,就可以在代码中使用这个值的想应部分。主要教材参考 《The Rust Programming Language》以上就是今天要讲的内容。

小嘉丶学长的博客 2089

Rust编程-模式匹配

条件中的y就是来自表达式外部的y, 匹配守卫if n == y不是一个模式,所以它不会引入新的变量.能够比较n和y的值是否相同。组成:字面量、解体的数组、元组、枚举、结构体 、变量、通配符、占位符等组件组成。可以混用if let 、else if、else if let 、else。会匹配到第二个分支,这里的y在match创建的作用域内,是一个新的变量,不是x后面的y变量。可以使用使用_或..语法忽略元组中的元素,_只能匹配一个,.. 可以匹配多个。@运算符允许在测试一个值是否匹配模式的同时。

Mercuryyjs的博客 1076

Rust中模式匹配

介绍了rust中的模式匹配(match) 如何用于解构数据结构、匹配值和控制程序分支;介绍了值、管道、忽略、值绑定等匹配模式;以及在if let, while let和for中如何使用模式匹配

飞鹰技术 431

Rust模式匹配进阶指南(从入门到精通的9大经典案例)

掌握Rust模式匹配核心技巧,解决复杂数据处理难题。通过9大经典案例详解匹配表达式、枚举解析与引用匹配等关键用法,覆盖常用场景与性能优化策略。深入理解match与if let的高效实践,提升代码安全与可读性。Rust模式匹配案例精讲,值得收藏。

PoliSeed的博客 660

深入解析 Rust 穷尽性检查:match 不只是 switch,它是类型安全的契约

穷尽性检查是 Rust 编译器的一个特性,它强制要求match表达式必须处理被匹配类型的所有可能情况(variants)。这个机制的核心依赖于 Rust 强大的**代数数据类型(Algebraic Data Types, ADT)**系统,尤其是enum(枚举)。1.enum:穷尽性的基石enum允许我们定义一个“和类型”(Sum Type),即um Type),即一个类型可以是“这个、那个或另一个”。Red,Yellow,Green,编译器确切地知道,类型的值有且仅有RedYellowGreen。

2501_94019712的博客 1067

rust(72)-match匹配

fn main() { for n in 2..101{ let num1=n % 2; let num2=n % 7; match num1 { 0=>println!("{:?} 偶数",n), 1=>println!("{:?} 奇数",n), _ =>println!("{:?} other",n), } match num2 { 1...3 =>println!("{:?} 1-3",n), 5|6 =>print

The research on computer technolog 385

Rust语言模式匹配实战技巧(90%开发者忽略的细节优化)

掌握rust语言模式匹配的实用技巧,提升代码安全性与执行效率。涵盖枚举解析、结构体解构等常见场景,深入讲解匹配守卫与绑定策略优化。避免常见陷阱,写出更优雅的Rust代码,值得收藏。

ByteChat的博客 393

2024 Rust现代实用教程 流程控制与函数

函数的代码本身通常是存储在可执行文件的代码段,而在调用时函数会在栈,开辟一个新的stack frame(栈空间),用于存储函数的局部变量、参数和返回地址等信息,而当函数结束后会释放该空间。而当传入non-Copy value(Vec、String等)传入函数时,实参会转移value的所有权给形参,实参会失去value的所有权而在函数结束时,value的所有权会释放。1.函数的定义:在Rust中,你可以使用fn关键字声明和定义函数,而main是程序的入口点是一种特殊的函数。

喜欢打篮球的普通人 1012

《通过例子学Rust》第8章 流程控制

任何编程语言都包含的一个必要部分就是改变控制流程:if/else,for 等。让我们谈谈 Rust 语言中的这部分内容。

chenyijun的专栏 819

Rust的匹配中的模式守卫

在Rust中,`match`表达式是处理复杂条件分支的强大工具,而模式守卫(Pattern Guard)则为其增添了额外的灵活性。模式守卫允许开发者在匹配模式的通过额外的布尔条件进一步筛选数据,从而更精准地控制程序流程。例如,某些复杂条件可能导致匹配分支的可读性下降,此时可能需要拆分为单独的函数或使用`if-let`结构。Rust的模式守卫为`match`表达式提供了更强大的逻辑控制能力,能够结合解构、避免重复计算,并提升代码的简洁性。

xtwbko_979的博客 359

Rust中的关键字

强制类型转换,消除特定包含项的 trait 的歧义,或者对 use 和 extern crate 语句中的项重命名。- 链接(link)一个外部 crate 或一个代表宏定义的 crate 的宏变量。- 遍历一个迭代器或实现一个 trait 或者指定一个更高级的生命周期。- 定义一个 union 并且是 union 声明中唯一用到的关键字。- 表示不安全的代码、函数、trait 或实现。- 定义或实现 trait 的类型的类型别名。- 表示引用、裸指针或模式绑定的可变性。

techdashen的博客 369

Rust-01-关键字

• as - 强制类型转换,消除特定包含项的 trait 的歧义,或者对 use 语句中的项重命名。因此,这些关键字不能被用作标。识符(除了 “原始标识符” 部分介绍的原始标识符),这包括函数、变量、参数、结构体字段、• for - 遍历一个迭代器或实现一个 trait 或者指定一个更高级的生命周期。模块、crate、常量、宏、静态值、属性、类型、trait 或生命周期 的名字。• unsafe - 表示不安全的代码、函数、trait 或实现。• Self - 定义或实现 trait 的类型的类型别名。

weixin_43714208的博客 754
上一篇: Rust之枚举和模式匹配(一):枚举定义
下一篇: Rust之枚举和模式匹配(三):简明控制流if let
枫★曦
博客等级 码龄19年 251粉丝 153原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值