Rust学习日记(二)变量的使用--结合--温度换算/斐波那契数列--实例

前言:
这是一个系列的学习笔记,会将笔者学习Rust语言的心得记录。
当然,这并非是流水账似的记录,而是结合实际程序项目的记录,如果你也对Rust感兴趣,那么我们可以一起交流探讨,使用Rust来构建程序。

注:本文中使用Rust都是在windows环境下,如果是macOS或者linux,其指令或有不同,请注意。

系列第一篇:Rust学习日记(一)Cargo的使用

概述:

这是Rust学习笔记的第二篇,主要说一下Rust中的变量,本文将结合两个实例来说明,这两个实例分别是:
1、在华氏度和摄氏度之间转换温度
2、生成指定个数(n)的斐波那契数列
如果你看过rust的官方手册,那你会熟悉,这两个例子事实上就是官方留的“课后习题”

在进入实例之前,还是要先来简单看看变量的使用。

变量的申明

1、关键词let
在rust中,申明变量的关键词就是let。如果你使用过其他语言,那么你可能对rust的变量申明有疑问,为什么用let?
我觉得不用纠结,这就是一个定义,使用什么单词来作为关键词并不重要,重要的是,这个关键词的作用。

fn main() {let x=5;println!("x is {x}");
}

上面的示例程序段,是在主函数中创建了变量x,并打印,在终端输入cargo run,输出如下:

PS D:\008 rustpro\var> cargo runFinished dev [unoptimized + debuginfo] target(s) in 0.02sRunning `target\debug\var.exe`
x is 5

2、变量的可变与不可变
变量,顾名思义,就是可变化的量,不可变的是变量吗?不可变的应该是常量吧?
在rust中,默认情况下,变量是不可变的。
这是rust的设计,它的目的,当然是为了安全。“安全”是贯穿rust整个体系的,后面会有更多更复杂更高级的功能,都会和它有关。

fn main() {let x=5;println!("x is {x}");x=x+1;println!("x is {x}");
}

对前面的函数稍作修改,给变量x再次赋值,再看输出:

PS D:\008 rustpro\var> cargo runCompiling var v0.1.0 (D:\008 rustpro\var)
error[E0384]: cannot assign twice to immutable variable `x`--> src\main.rs:4:5|
2 |     let x=5;|         -|         ||         first assignment to `x`|         help: consider making this binding mutable: `mut x`
3 |     println!("x is {x}");
4 |     x=x+1;|     ^^^^^ cannot assign twice to immutable variableFor more information about this error, try `rustc --explain E0384`.
error: could not compile `var` (bin "var") due to previous error

错误提示,cannot assign twice to immutable variable,不能给“immutable variable”分配两次,什么叫immutable variable?就是不可变变量。
所以,现在你就知道,rust是比较奇葩的了。
但是,这就是rust的设计,如果你定义变量的时候,只是简单的let x=5;那么这个x是不可变的。那如果要可变呢:

let mut x=5

再加一个关键词mut,mut其实就是mutable的简写,可变的。

fn main() {let mut x=5;println!("x is {x}");x=x+1;println!("x is {x}");
}

cargo run:

PS D:\008 rustpro\var> cargo runCompiling var v0.1.0 (D:\008 rustpro\var)Finished dev [unoptimized + debuginfo] target(s) in 0.43sRunning `target\debug\var.exe`
x is 5
x is 6

可以发现,“变量x”的值可以多次分配,也就是真正的可变了。
看到这里你发现什么?
你会发现,在rust里,你对一个对象,比如变量的定义,必须要十分清楚,可变就可变,不可变就不可变,
这样一来,rust编译器就能非常清楚地知道,你定义这个变量的目的,它会编译过程对你的意图全程跟踪,
不可变变量如果不小心让它变化,编译器就会报错,提示你,对你来说,这就是安全。
你不用等程序都运行了,然后偶尔崩溃了一次,然后去找bug,找来找去无论怎么编译就是没问题,但一运行就报错,这是令人崩溃的。

你已经了解到rust中变量的奇葩性了,我们接着再看几个,然后再进入实例。

3、常量
rust中常量用const来申明,这个const应该是比较熟悉的单词了,很多编程语言申明常量都是用它吧。
const也就是Constants的简写。
看一下申明的格式吧:

const C_1=5

如果你真的这么写,cargo check一下,会报错:

PS D:\008 rustpro\var> cargo checkChecking var v0.1.0 (D:\008 rustpro\var)
error: missing type for `const` item--> src\main.rs:6:14|
6 |     const C_1=5;|              ^ help: provide a type for the constant: `: i32`error: could not compile `var` (bin "var") due to previous error

rust编译器提示你,需要给常量提供一个数据类型,并且给了你一个选项:i32
rust中的数据类型----整数型:
在这里插入图片描述
关于数据类型,其实我认为不用多说,照着手册看看了解一下即可,因为一般来说,对编程有所了解的,对数据类型一般都不陌生,可以说,几乎所有语言中的数据类型,都大同小异。
常见的比如说整数、浮点数、布尔量、字符串等,还有一些复杂的,比如结构体(复合体)、数组、列表、元组等。

我们接着说常量,上面说这样写const C_1=5;会报错,原因是未给常量提供数据类型,所以我们应该这么来申明常量

const C_1:i32=5

rust就是这样,它要求你明确,哪怕是常量,它不会为你隐式转换,它要求你定义常量时,明确常量的数据类型。
到此,你会发现,rust似乎很“麻烦”,这也要明确,那也要明确,为什么不能像其他语言一样,直接a=5;或者const a=5;
我只能说,rust它就是这样一门语言,如果你对此实在不能接受,那么放弃是好的,如果无所谓,那么就按照rust的规则,暂时先走下去。

4、变量的覆盖
我们在本文前面说过,rust中的变量有可变和不可变的区别,直接申明变量,默认不可变,如果要可变,需加关键词mut。
但现在我们来看另一种使用:

fn main() {let x=5;println!("x is {x}");let x:char='a';println!("x is {x}");
}

我们在第一行定义x变量,且赋值为5,但没有用mut使其可变,所以x是不可变的,但是我们在第三行再次使用x变量,而且给它赋值为字符‘a’。
我们先cargo run一下:

PS D:\008 rustpro\var> cargo runCompiling var v0.1.0 (D:\008 rustpro\var)Finished dev [unoptimized + debuginfo] target(s) in 0.63sRunning `target\debug\var.exe`
x is 5
x is a

可以看到,rust正常编译,且结果x的值被改变了。你应该看到区别,就是第三行再次使用x时,重新定义了一次。
rust中,用let来定义变量,是可以重名的,并且后一个可以覆盖前面的,所谓“shadow”,即旧的变量活在新的变量的阴影里
你可能会觉得,这样是不是会造成困扰,如果不小心使用了一样的变量名,覆盖之前的变量数据,岂不是会影响程序。但这个问题容易解决,只需要你在命名变量时有自己的规律即可,但是rust中这样的机制会带来好处。
我们看到,同样的变量x,在第一次和第二次的定义中,不仅值可以不同,连数据类型也可以不同。
什么场景会这样使用,比如你要输入一个值,是字符类型,但程序接收字符后,要以整数型来运算,但是这两个其实一个东西,如果是其他语言,你可能会这样定义变量,x_str和x_int,但是rust中你可以只定义一个x,

let x:char='a';
let x:i32=5;

好了,关于变量就先说到这,基本上差不多了,当然这并非是说把变量的所有方面都涉及到了,只是说基本的概念都已经了解了。
下面将开始实例:

一、温度转换

1、新建一个temp项目

PS D:\008 rustpro> cargo new tempCreated binary (application) `temp` package
PS D:\008 rustpro> cd temp
PS D:\008 rustpro\temp> cargo buildCompiling temp v0.1.0 (D:\008 rustpro\temp)Finished dev [unoptimized + debuginfo] target(s) in 0.49s
PS D:\008 rustpro\temp> 

在这里插入图片描述
新建项目后,rust会自动生成一个main.rs主函数。
这个主函数里默认的是打印“hello world”,我们要修改它,以达到温度转换的功能。
华氏度和摄氏度的转换关系如下:

1 摄氏度=33.8 华氏度

所以,如果我们输入一个摄氏度值为x,那么转换为华氏度应该是:f(x)=33.8*x
数学关系很清楚,是很简单的一元一次函数。
先看一下main.rs的结构:

fn main() {println!("Hello, world!");
}

fnlet一样,是关键词,定义函数,所以fn后面的main就是函数,只不过它是主函数,所以地位特殊,但是,main这个名字,想必大家也不陌生,无论是C还是python,都有主函数,地位也差不多,谁让它是main呢!
但我们先不修改main,我们先新建一个函数,就叫temp_convert:

fn temp_convert(){}

添加逻辑代码:

fn temp_convert(t:f32)->f32{let t2=t*33.8;return t2;
}

可以看到,我们在新建的函数基础上,添加了一个形式参数t,把它的数据类型定义为f32,即浮点数。
定义了一个函数返回值类型:->f32,即函数返回值也是f32类型。
然后在函数体内,定义了变量t2,其赋值为t*33.8,
最后将计算后的t2的值返回。
这个函数中形式参数t即输入的摄氏度,返回的t2即转换的华氏度。
接下来,就是在主程序里调用了:
修改一下main函数:

fn main() {let t1=temp_convert(3.0);println!("t_f is {t1}");
}

因为函数temp_convert有返回值,所以我们定义一个变量t1来储存它。
到此,简单的温度转换就实现了,只要给函数的参数赋予不同的值(摄氏度),函数就可以返回华氏度:

PS D:\008 rustpro\temp> cargo runCompiling temp v0.1.0 (D:\008 rustpro\temp)Finished dev [unoptimized + debuginfo] target(s) in 0.42sRunning `target\debug\temp.exe`
t_f is 101.399994

但这样肯定不算是一个完整的程序,我们设想应该是这样,程序启动,会输出一个文字提示,让我们输入一个摄氏度,我们输入后,程序输出一个华氏度。然后能循环,这样才算是完整的转换程序。
我们分两部分来说,一是如何接受用户输入,二是如何循环。

1 用户输入

用户输入,需要用到IO接口,在rust中即std::io
std::io,这是一个程序包crate,类似于其他程序的模块。在使用它之前,需要先导入它。

use std::io;

然后使用它:

use std::io;
fn main() {let mut t_in=String::new();println!("请输入摄氏度值:");io::stdin().read_line(&mut t_in).expect("error");let t_in:f32=t_in.trim().parse().expect("error");let t1=temp_convert(t_in);println!("华氏度是 {t1}");
}

上面的主函数main变化较大,我们一一来说一下。我们使用use关键词导入了std::io,这是用来接受用户输入的模块。
然后在主函数体内添加程序:

let mut t_in=String::new();

这行是定义了一个可变变量t_in且类型为string

  io::stdin().read_line(&mut t_in).expect("error");

这行就是io接口的调用,用于读取用户的输入,read_line即是std::io模块的函数。&mut t_in是将我们定义的变量t_in来接受read_line的输入值。
其实上面这行直接写如下:

io::stdin().read_line(&mut t_in).expect("error");

之所以写成多行样式,是为了便于阅读。
这里的expect是对潜在错误的处理,关于错误的处理不在本文的范围,后续会有专门叙述。此处只要知道这样用就可以了。
我们现在已经从用户处接受到输入值,即t_in,接下来要对输入值进行处理:

let t_in:f32=t_in.trim().parse().expect("error");

此处我们使用前面介绍的变量覆盖,先定义了t_in为用户输入,且数据类型为string类型,接着此行用同名变量t_in定义为f32类型,覆盖之前的字符串类型。
其中的trim是消除一个字符串的开头和结尾的多余空格,parse是将字符串转为另一种数据类型,在此处就是转为f32类型。expect我们已经说过,是对返回值的判断时可能发生的错误处理。

`let t1=temp_convert(t_in);

在顺利获得用户输入的值且转为浮点类型后,我们调用写好的temp_convert转换函数,其形式参数t在调用时传入实际参数t_in。将temp_convert函数的返回值,传给变量t1。
完整程序:

use std::io;
fn main() {let mut t_in=String::new();println!("请输入摄氏度值:");io::stdin().read_line(&mut t_in).expect("error");let t_in:f32=t_in.trim().parse().expect("error");let t1=temp_convert(t_in);println!("华氏度是 {t1}");
}
fn temp_convert(t:f32)->f32{let t2=t*33.8;return t2;
}

在终端运行cargo run:

PS D:\008 rustpro\temp> cargo runCompiling temp v0.1.0 (D:\008 rustpro\temp)Finished dev [unoptimized + debuginfo] target(s) in 0.74sRunning `target\debug\temp.exe`
请输入摄氏度值:
2
华氏度是 67.6

好了,第一部分完成了,现在我们能成功根据输入的摄氏度转为华氏度且输出,但缺点是每次运行只能进行一次,所以需要循环。

循环

想让程序循环起来,也很简单,使用loop指令,它会循环执行主程序的逻辑,直到触发停止。本文中未添加明确的停止程序,因为这不在我们的学习范围,后续会有说明,此文不赘述。

fn main() {loop{let mut t_in=String::new();println!("请输入摄氏度值:");io::stdin().read_line(&mut t_in).expect("error");let t_in:f32=t_in.trim().parse().expect("error");let t1=temp_convert(t_in);println!("华氏度是 {t1}");}}

我们可以看到,只需要将main中的原程序添加进loop的{}中即可。
让我们运行一下:

PS D:\008 rustpro\temp> cargo runCompiling temp v0.1.0 (D:\008 rustpro\temp)Finished dev [unoptimized + debuginfo] target(s) in 0.46sRunning `target\debug\temp.exe`
请输入摄氏度值:
2
华氏度是 67.6
请输入摄氏度值:
3
华氏度是 101.399994
请输入摄氏度值:
4
华氏度是 135.2
请输入摄氏度值:
1
华氏度是 33.8
请输入摄氏度值:
2
华氏度是 67.6
请输入摄氏度值:
r
thread 'main' panicked at src\main.rs:10:42:
error: ParseFloatError { kind: Invalid }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\temp.exe` (exit code: 101)

可以看到,程序在不停地执行,如果用户一直输入正确的值得话,但你会发现在终端的记录中,最后输入r时,rust报错且退出了,这是因为程序中没有对非法输入的应对措施,当输入非法值时,只能报错退出。
但我不准备在本文中完善它,我相信随着我们学习rust的深入,这个问题会迎刃而解。
如果你看到这里,我相信你对rust中变量、函数的使用,有了初步的印象了。
下面我们说一下第二个实例,即实现斐波那契数列。

斐波那契数列

斐波那契数列应该是比较经典的练手题目了,你在学习其他语言如C、python、java中都可以通过编写斐波那契数列来加深对语言的理解。
rust也不例外,我在文章一开头就说过,此文所列举的两个实例,都是rust官方手册中给读者留的课后习题。
其实官方在手册的第二章给了一个很好的实例即猜谜游戏,说的非常详细,但我们作为学习者,在学习了官方手册后,自己要学会应用,所以我选择用课后习题来作为示例。

斐波那契数列是这样的数列:

1,1,2,3,5,8,13,21,34,55,89…

这个数列的规律是,从第三项开始,每一项的值都是它前面两项的和。用公式表示为:

f(n)=f(n-1)+f(n-2);n>2

所以,如果要用函数来实现斐波那契数列,函数肯定是递归的。

rust实现,首先是创建新项目,这个不用多说了。
在这里插入图片描述
接着创建新的函数,命名为fibonacci

fn fibonacci(num:i32)->i32{if num<3{return 1;}else{return fibonacci(num-1)+fibonacci(num-2);}
}

这个fibonacci函数有个形式参数num,数据类型为i32,函数的返回值类型由’->'符号指出,也是i32
函数体内的逻辑,是对num进行判断,如果num小于3,也就是fibonacci数列的前2项,那么函数返回值固定为1,如果num大于等于3,那么返回值就等于前2项之和。
此处的判断,使用了if。。else语句。if else应该不用多说了吧,这应该是学习编程的人,都会了解的。
几乎你学习任何编程语言,都会遇到if语句。
所以,本文也不会赘述if。。else语句。
接下来看main函数:

use std::io;
fn main() {loop{println!("please enter fibonacci number:");let mut number=String::new();io::stdin().read_line(&mut number).expect("err");let number:i32=number.trim().parse().expect("err");println!("number is {number}");for y in 1..number{let x=fibonacci(y);println!("fibo({y}) is {x}");}}  }

可以看到,几乎和前面的实例一样,一点区别在于子函数fibonacci的调用处,这里用了for语句:
之所以使用for语句,因为斐波那契数列是一个数列,当我们给定一个斐波那契数列的项索引(n)时,我们实际上希望程序能够列出至n项的斐波那契数列所有的项。

 for y in 1..number{let x=fibonacci(y);println!("fibo({y}) is {x}");}

同理,for循环也是常见的,和if语句一样,我们会在后续的文章里统一说明,此文不赘述。
我们还是看一下实际运行效果吧:

PS D:\008 rustpro\fibonacci> cargo runCompiling fibonacci v0.1.0 (D:\008 rustpro\fibonacci)Finished dev [unoptimized + debuginfo] target(s) in 0.71sRunning `target\debug\fibonacci.exe`
please enter fibonacci number:
2
number is 2
fibo(1) is 1
please enter fibonacci number:
5
number is 5
fibo(1) is 1
fibo(2) is 1
fibo(3) is 2
fibo(4) is 3
please enter fibonacci number:
10
number is 10
fibo(1) is 1
fibo(2) is 1
fibo(3) is 2
fibo(4) is 3
fibo(5) is 5
fibo(6) is 8
fibo(7) is 13
fibo(8) is 21
fibo(9) is 34
please enter fibonacci number:
r
thread 'main' panicked at src\main.rs:10:46:
err: ParseIntError { kind: InvalidDigit }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\fibonacci.exe` (exit code: 101)

总结一下,rust变量:

let x=5;//x不可变
let mut x=5;//x可变
let x=5;
let x='a';//x依旧不可变,但可以被重名者覆盖,且可不同数据类型
const x:i32=5;//常量需指定数据类型

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/184812.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Camera Raw 16 v16.0.0

Camera Raw 16是一款允许摄影师处理原始图像文件的软件PS增效工具。原始图像文件是未经相机内部软件处理的数码照片&#xff0c;因此包含相机传感器捕获的所有信息。Camera Raw 为摄影师提供了一种在将原始文件转换为更广泛兼容的格式&#xff08;如 JPEG 或 TIFF&#xff09;之…

基于React使用swiperjs实现竖向滚动自动轮播

很多文章&#xff0c;都只提供了js部分&#xff0c;包括官方的文档也只有js部分&#xff0c;如果css设置不正确&#xff0c;会导致轮播图不自动播放。 使用的swiper版本&#xff1a;v11.0.3 文档 https://swiperjs.com/get-startedhttps://swiperjs.com/react 实现效果 使…

AD教程 (十)Value值的核对

AD教程 &#xff08;十&#xff09;Value值的核对 填写器件位号 直接根据原理图的原始编号进行更改 通过位号编辑器快速更改 点击工具&#xff0c;选择标注&#xff0c;选择原理图标注&#xff0c;进入位号编辑器 可以在位号编辑器中 设置处理顺序&#xff0c;从上往下还是从…

layui form 中input输入框长度的统一设置

Layui.form中使用class"layui-input-inline"就可轻松将元素都放到一行&#xff0c;但如果元素过多&#xff0c;就会自动换行。那就需要手动设置input框的长度。 像这种情况&#xff1a; 其实只需要添加css样式就可修改了 .layui-form-item .layui-input-inline {wid…

奔驰E Coupe 升级鼠标按键 操作简单 完美结合

人机交互系统正是汽车智能化发展的产物&#xff0c;它实现了人与车之间的互联。不知道大家有没有发现&#xff0c;在很多奔驰车的中央扶手箱前&#xff0c;有一块类似于“鼠标”的操作区&#xff0c;它并不是我们常见的换挡杆&#xff0c;而是奔驰研发的独立影音控制系统COMAND…

【Dockerfile镜像实战】构建LNMP环境并运行Wordpress网站平台

【Dockerfile镜像实战】构建LNMP环境并运行Wordpress网站平台 Nginx部署MySQL部署PHP部署 Nginx部署 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0[rootlocalhost ~]# docker pull centos:7[rootlocalhost ~]# docker imagescd /opt mkdir n…

从行车记录仪恢复已删除/丢失视频的方法

“我的车里有行车记录仪。几天前&#xff0c;当我下班回家时&#xff0c;一辆卡车不知从哪里冒出来撞向了我。我们的两辆车都损坏了&#xff0c;但幸运的是&#xff0c;没有人受伤。我曾与卡车司机就修理我的汽车进行过会面&#xff0c;但他说我有错。我需要查看我的行车记录仪…

怎么学编程效率高,编程练习网站编程软件下载,中文编程开发语言工具下载

怎么学编程效率高&#xff0c;编程练习网站编程软件下载&#xff0c;中文编程开发语言工具下载 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的…

Harbor私有仓库

Harbor私有仓库 文章目录 Harbor私有仓库Harbor简介&#xff1a;Harbor 提供了以下主要功能和特性&#xff1a;优缺点&#xff1a;环境说明&#xff1a;部署harbor1.永久关闭防火墙和seliux&#xff0c;配置阿里云源&#xff0c;添加映射关系2.安装docker&#xff0c;开启docke…

【论文阅读】Generating Radiology Reports via Memory-driven Transformer (EMNLP 2020)

资料链接 论文原文&#xff1a;https://arxiv.org/pdf/2010.16056v2.pdf 代码链接&#xff08;含数据集&#xff09;&#xff1a;https://github.com/cuhksz-nlp/R2Gen/ 背景与动机 这篇文章的标题是“Generating Radiology Reports via Memory-driven Transformer”&#xf…

基于单片机GP2D12测距-proteus仿真-源程序

基于51单片机红外测距-proteus仿真-源程序 一、系统方案 本设计采用51单片机作为主控器&#xff0c;液晶1602显示&#xff0c;GP2D12采集距离值&#xff0c;按键设置报警阀值&#xff0c;测量值超过阀值&#xff0c;蜂鸣器报警。 二、硬件设计 原理图如下&#xff1a; 三、单…

Python进阶教程:pandas数据分析实践示例总结

文章目录 前言一、分析数据文件二、数据预处理关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 前言 在近日的py…

相机滤镜软件Nevercenter CameraBag Photo mac中文版特点介绍

Nevercenter CameraBag Photo mac是一款相机和滤镜应用程序&#xff0c;它提供了一系列先进的滤镜、调整工具和预设&#xff0c;可以帮助用户快速地优化和编辑照片。 Nevercenter CameraBag Photo mac软件特点介绍 1. 滤镜&#xff1a;Nevercenter CameraBag Photo提供了超过2…

微信小程序:怎么在一个js中修改另一个js的数据(这里通过缓存进行实现)

实例&#xff1a;现有两个页面index.js和category.js,我现在想在index.js中修改category.js的数据 初始数据 category [{name: 物流配送,list: [{id: 1,job: 外卖骑手,checked: true}, {id: 2,job: 快递员,checked: false}, {id: 3,job: 司机,checked: false}, {id: 4,job: …

蓝桥杯每日一题203.11.7

题目描述 题目分析 使用dp思维&#xff0c;当前位置是否可行是有上一位置推来&#xff0c;计算出最大的可行位置即可 #include <stdio.h> #include <string.h>#define N 256 int f(const char* s1, const char* s2) {int a[N][N];int len1 strlen(s1);int len2 …

react组件通信

目录 前言&#xff1a; 父子组件通信 子父组件通信 兄弟组件通信 总结 前言&#xff1a; React是一种流行的JavaScript库&#xff0c;用于构建现代化的、高性能的Web应用程序。在React中&#xff0c;组件是代码的构建块。组件通信是React中一个非常重要的概念&#xff0c;…

[动态规划] (十四) 简单多状态 LeetCode LCR 091.粉刷房子

[动态规划] (十四) 简单多状态 LeetCode LCR 091.粉刷房子 文章目录 [动态规划] (十四) 简单多状态 LeetCode LCR 091.粉刷房子题目解析解题思路状态表示状态转移方程初始化和填表顺序返回值 代码实现总结 LCR 091. 粉刷房子 题目解析 (1) 一排房子&#xff0c;共有n个 (2) 染…

世微 DC-DC降压恒注驱动芯片 LED汽车大灯 过EMC认证 AP2400

产品特点 宽输入电压范围&#xff1a;5V&#xff5e;100V 可设定电流范围&#xff1a;10mA&#xff5e;6000mA 固定工作频率&#xff1a;150KHZ 内置抖频电路&#xff0c;降低对其他设备的 EMI 干扰 平均电流模式采样&#xff0c;恒流精度更高 0-100%占空比控制&#…

python+robotframework接口自动化测试

目前我们需要考虑的是如何实现关键字驱动实现接口自动化输出&#xff0c;通过关键字的封装实现一定意义上的脚本与用例的脱离&#xff01; robot framework 的安装不过多说明&#xff0c;网上资料比较太多~ 实例&#xff1a;&#xff01;&#xff01;&#xff01;&#xff01…

网络原理---拿捏网络层:IP协议

文章目录 IP协议4位版本4位首部长度、选项8位服务类型&#xff08;TOS&#xff09;16位总长度16位标识、3位标志、13位片偏移8位生存时间&#xff08;TTL&#xff09;8位协议16位首部校验和32位源IP地址、32位目的IP地址解决IP地址不够用的问题动态分配IP地址NAT机制&#xff0…