2311rust到27版本更新

1.23

Rust1.0开始,有叫AsciiExt特征来提供u8,char,[u8]str上的ASCII相关功能.要使用它,需要如下编写代码:

use std::ascii::AsciiExt;
let ascii = 'a';
let non_ascii = ' ';
let int_ascii = 97;
assert!(ascii.is_ascii());
assert!(!non_ascii.is_ascii());
assert!(int_ascii.is_ascii());

Rust1.23中,现在直接在这些类上定义这些方法,因此不再需要导入trait.

#[allow(unused_imports)]
use std::ascii::AsciiExt;
//也可继续以前导入.

抑制相关警告.

此外,新API:
现在从非原子类型实现各种std::sync::atomic类型.如,

let x = AtomicBool::from(true);

()现在实现了FromIterator<()>;
RwLock<T>取消发送限制

货物特点
1,Cargo Check现在可检查你的单元测试.
2,cargo uninstall现在可在一个命令卸载多个包.

1.24

rustup component add rustfmt-preview
//格式组件.

有两点:首先,在此使用的是

rustup component add
//而不是
cargo install

如果以前通过cargo install使用过rustfmt,应该先卸载它.
其次,这是一个预览.

增量编译

Rust1.24开始,默认增量编译.
要在Cargo.toml中设置codegen-units1(或16),以提升每一滴性能.

未定义行为.Rust一般努力减少未定义行为,在安全代码中没有未定义行为,在不安全代码中尽量少.
跨越FFI边界,恐慌(panic)!时,可调用UB.即:

extern "C" fn panic_in_ffi() {panic!("Test");
}

Rust1.24中,代码现在中止,而不是ub.
str::find,在&str中查找给定的符:它现在快了10倍!这要归功于memchr.[u8]::contains也用它.
此外,还稳定了一些新API:

RefCell::replace
RefCell::swap
std::sync::atomic::spin_loop_hint

最后,现在可在常量式中使用这些函数,如,初化静:
1,Cell,RefCellUnsafeCell的新功能
2,各种原子整数类型的新函数
3,{integer}::min_valuemax_value
4,MEMsize_ofalign_of
5,ptr::nullnull_mut

1.24.1稳定版

更改细节:
1,通过FFI展开时不会中止(恢复1.24.0中添加的行为)
2,在窗口上为链接器参数发出UTF-16文件
3,使错误索引生成器再次工作
4,如果要更新,Cargo窗口7上发出警告.

rlua的异常.
深入挖掘后,发现了原因:setjmp/longjmp.由C标准库提供这些函数来处理错误.先调用setjmp,然后稍后再调用longjmp.

这样,控制流返回到之前调用setjmp的位置.它一般用来实现异常,甚至协程.Lua的实现使用setjmp/longjmp来实现异常:
C++Java不同,C语言不提供异常处理机制.为了改善,Lua使用了C语言中的setjmp工具,这导致了类似异常处理的机制.
如果用C++编译Lua,则更改代码来使用真正的异常并不困难.

所以,问题变成了:为什么会在窗口上破裂
窗口有个叫"结构化异常处理"(SEH)的概念.窗口使用SEH来实现setjmp/longjmp,因为SEH的整个思想是有统一的错误处理.
类似,C++异常使用SEH,Rust恐慌也是.
看看rlua的工作原理.rlua有个protect_lua_call内部函数,来调用Lua.它像这样使用:

protect_lua_call(self.state, 0, 1, |state| {ffi::lua_newtable(state);
}) ;

即,protect_lua_call需要一些包含闭包的参数.把此闭包传递给lua_pcall,它再抓传递给它的代码(该闭包)可能抛的longjmp.

即,代码现在像如下伪码:

protect_lua_call(self.state, 0, 1, |state| {let result = panic::catch_unwind(|| {ffi::lua_newtable(state);});if result.is_err() {process::abort();}
}) ;

之前,在讨论setjmp/longjmp时,说过在Rust代码中的问题是,它不处理Rust析构器.因此,在除窗口之外的所有平台上,上述catch_unwind恶作剧都被有效地忽略了,因此一切正常.

但是,在窗口上,因为setjmp/longjmpRustpanic都使用SEH,因此抓住了longjmp,并运行新的中止代码!

1.25.0稳定版

已从LLVM4升级到了LLVM6.
嵌套导入组.

use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};

现在可这样写:

//在一行上
use std::{fs::File, io::Read, path::{Path, PathBuf}};
//更多空间
use std::{fs::File,io::Read,path::{Path,PathBuf}
};

接受允许设置结构对齐方式属性的如下对齐:

#[repr(align(x))]

示例:

struct Number(i32);
assert_eq!(std::mem::align_of::<Number>(), 4);
assert_eq!(std::mem::size_of::<Number>(), 4);
#[repr(align(16))]
struct Align16(i32);
assert_eq!(std::mem::align_of::<Align16>(), 16);
assert_eq!(std::mem::size_of::<Align16>(), 16);

1,std::ptr::NonNull<T>.此类型类似*mut T,但为非null且协变.NonNull<T>保证它不会为null,即Option<NonNull<T>>的大小与*mut T相同.

如果要用不安全代码构建数据结构,NonNull<T>适合你!

2,libcore获得了,包含以前仅在libstd中可用的Duration类型的time模块.
此外,与Duration关联的from_secsfrom_millis函数都变成了常量函数,允许按常量式创建Duration.

3,:cargo new现在默认生成二进制文件,而不是.可用--lib/--bin来设置.

1.26.0稳定版

impl特征

impl Trait来了!提供了叫"存在类型"的功能.核心想法是:

fn foo() -> impl Trait {//...
}

此类型签名,表示"foo是一个无参但返回实现Trait特征的类型"的函数.也即,不会告诉你foo具体返回类型,只告诉你它实现了指定特征.

特征对象有何不同?

fn foo() -> Box<Trait> {//...
}

假设有个针对i32f32实现的Trait特征:

trait Trait {fn method(&self);
}
impl Trait for i32 {//实现在此
}
impl Trait for f32 {//实现在此
}

考虑以下函数:

fn foo() -> ? {5
}

如何填充返回类型.以前,只能用特征对象:

fn foo() -> Box<Trait> {Box::new(5) as Box<Trait>
}

但这引入了要分配Box.在此也没有返回动态数据,所以也会影响特征对象的动态调度.因此,从Rust1.26开始,可这样写:

fn foo() -> impl Trait {5
}

这不会创建,特征对象,与写了-> i32一样,但,只提及Traits部分.从而得到静态调度,但隐藏了真实类型.

闭包中有用.Rust闭包都有个唯一的,不可写的但实现了Fn特征的类型.即,如果函数返回闭包,可如下:

//以前
fn foo() -> Box<Fn(i32) -> i32> {Box::new(|x| x + 1)
}
//后
fn foo() -> impl Fn(i32) -> i32 {|x| x + 1
}

没有装箱(Box),没有动态调度.返回迭代器类似.迭代器不仅一般甚至包含嵌套闭包.如:

fn foo() {vec![1, 2, 3].into_iter().map(|x| x + 1).filter(|x| x % 2 == 0)
}

编译时,报错:

error[E0308]: mismatched types--> src/main.rs:5:5|
5 | /     vec![1, 2, 3]
6 | |         .into_iter()
7 | |         .map(|x| x + 1)
8 | |         .filter(|x| x % 2 == 0)| |_______________________________^ expected (), found struct `std::iter::Filter`|= note: expected type `()`found type `std::iter::Filter<std::iter::Map<std::vec::IntoIter<{integer}>, [closure@src/main.rs:7:14: 7:23]>, [closure@src/main.rs:8:17: 8:31]>`

以前,必须在此使用特征对象,但现在可简单这样:

fn foo() -> impl Iterator<Item = i32> {vec![1, 2, 3].into_iter().map(|x| x + 1).filter(|x| x % 2 == 0)
}

完成它.同未来工作类似.
注意,有时仍需要特征对象.仅当函数返回单个类型时,才能使用impl Trait;如果要返回多个,则需要动态调度.如:

fn foo(x: i32) -> Box<Iterator<Item = i32>> {let iter = vec![1, 2, 3].into_iter().map(|x| x + 1);if x % 2 == 0 {Box::new(iter.filter(|x| x % 2 == 0))} else {Box::new(iter)}
}

为了使语法更对称,也可在参数位置使用impl Traits:

//以前
fn foo<T: Trait>(x: T) {
//以后
fn foo(x: impl Trait) {

更好的匹配绑定

你是否曾经引用过Option,并试使用match?如,如下代码:

fn hello(arg: &Option<String>) {match arg {Some(name) => println!("Hello {}!", name),None => println!("你是谁?"),}
}

如果试在Rust1.25中编译它,会得到错误:

error[E0658]: non-reference pattern used to match a reference (see issue #42640)--> src/main.rs:6:9|
6 |         Some(name) => println!("Hello {}!", name),|         ^^^^^^^^^^ help: consider using a reference: `&Some(name)`
error[E0658]: non-reference pattern used to match a reference (see issue #42640)--> src/main.rs:7:9|
7 |         None => println!("I don't know who you are."),|         ^^^^ help: consider using a reference: `&None`

好的,当然.修改代码:

fn hello(arg: &Option<String>) {match arg {&Some(name) => println!("Hello {}!", name),&None => println!("你是谁?"),}
}

添加了编译器抱怨的&s.再次试编译:

 错误`[E0507]`:无法移出借用的内容--> src/main.rs:6:9|
6 |         &Some(name) => println!("Hello {}!", name),|         ^^^^^^----^|         |     ||         |     hint: to prevent move, use `ref name` or `ref mut name`|无法移出借用的内容

好的如下:

fn hello(arg: &Option<String>) {match arg {&Some(ref name) => println!("Hello {}!", name),&None => println!("你是谁?"),}
}

不得不添加两个&s和一个ref.
Rust1.26开始,没有&sref初始代码,完全按你的期望编译执行.总之,在match语句中自动引用或解引用.所以

match arg {Some(name) => println!("Hello {}!", name),

编译器会自动引用Some,且因为借用了name,因此name也自动绑定为ref name.如果修改为:

fn hello(arg: &mut Option<String>) {match arg {Some(name) => name.push_str(", world"),None => (),}
}

编译器自动按可变引用借用,且name也按ref mut绑定.

main也可返回结果

use std::fs::File;
fn main() {let f = File::open("bar.txt")?;
}

导致了如下编写代码:

fn run(config: Config) -> Result<(), Box<Error>> {//...
}
fn main() {//...if let Err(e) = run(config) {println!("Application error: {}", e);process::exit(1);}
}

Rust1.26中,现在可声明返回Resultmain:

use std::fs::File;
fn main() -> Result<(), std::io::Error> {let f = File::open("bar.txt") ;Ok(())
}

现在正常工作!如果main返回错误,则退出并显示错误码,并打印出错误的调试表示.

包含…=

可如下使用..:

for i in 1..3 {println!("i: {}", i);
}

这打印i:1,然后打印i:2.在Rust1.26中,你现在可如下创建包含区间:

for i in 1..=3 {println!("i: {}", i);
}

这打印如前i:1,然后打印i:2,但也打印i:3.

fn takes_u8(x: u8) {//...
}
fn main() {for i in 0..256 {println!("i: {}", i);takes_u8(i);}
}

编译时收到提示:
警告:U8文本出域

 --> src/main.rs:6:17|
6 |     for i in 0..256 {|                 ^^^|= note: #[warn(overflowing_literals)] on by default

但是,可用包含区间来完成:

fn takes_u8(x: u8) {//...
}
fn main() {for i in 0..=255 {println!("i: {}", i);takes_u8(i);}
}

产生你可能期望的256行输出.

基本切片模式

允许在切片上匹配.如:

let arr = [1, 2, 3];
match arr {[1, _, _] => "starts with one",[a, b, c] => "starts with something else",
}

在本例中,知道arr的长度为3,因此需要在[]中加入3个项.不知道长度时,也可匹配:

fn foo(s: &[u8]) {match s {[a, b] => (),[a, b, c] => (),_ => (),}
}

128位整数,Rust现在有128位整数!

let x: i128 = 0;
let y: u128 = 0;

大小是u64的两倍,因此可容纳更多值.即,

u128: 0 - 340,282,366,920,938,463,463,374,607,431,768,211,455
i128:  170,141,183,460,469,231,731,687,303,715,884,105,728 - 170,141,183,460,469,231,731,687,303,715,884,105,727

库稳定

稳定了比File::openio::Read::read_to_string更方便的fs::read_to_string,它可轻松地一次读取整个文件内存中:

use std::fs;
use std::net::SocketAddr;
let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?;

现在,你可用Debug格式将数字格式化为十六进制:

assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]")

标准库中的所有宏现在都支持尾随逗号.

1.26.2稳定版

漏洞:允许同时对路径有两个可变借用.

let mut foo = Some("foo".to_string());
let bar = &mut foo;
match bar {Some(baz) => {bar.take(); //不应允许,因为`baz`唯一引用`条形指针`.},None => unreachable!(),
}

1.26.2拒绝上述代码,并显示以下错误消息:

error[E0499]: cannot borrow `*bar` as mutable more than once at a time--> src/main.rs:6:9|
5 |     Some(baz) => {|          --- first mutable borrow occurs here
6 |         bar.take(); //不应被允许,因为`baz`有一个......|         ^^^ second mutable borrow occurs here
...
9 | }|第一次借用到此结束

错误:因为上一个错误而中止

1.27.0稳定版

SIMD
好了,现在是大新闻:现已发布SIMD基础!SIMD代表"单指令,多数据".考虑如下此函数:

pub fn foo(a: &[u8], b: &[u8], c: &mut [u8]) {for ((a, b), c) in a.iter().zip(b).zip(c) {*c = *a + *b;}
}

在此,取两个切片,并把数字相加,在第三个切片中放置结果.
但是,编译器可做得更好.LLVM一般会"自动向量化"代码.
Rust1.27中,添加了std::arch模块,允许直接使用这类指令,不必依赖编译器.此外,还包括一些允许根据各种标准选择指定实现的功能.如:

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"),target_feature = "avx2"))]
fn foo() {#[cfg(target_arch = "x86")]use std::arch::x86::_mm256_add_epi64;#[cfg(target_arch = "x86_64")]use std::arch::x86_64::_mm256_add_epi64;unsafe {_mm256_add_epi64(...);}
}

在此,根据目标机器,使用cfg标志选择正确的版本;在x86上,使用该版本,在x86_64上,使用其版本.也可在运行时选择:

fn foo() {#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]{if is_x86_feature_detected!("avx2") {return unsafe { foo_avx2() };}}foo_fallback();
}

在此,有两个版本函数:一个使用可让你执行256位操作的指定类型的SIMD功能的AVX2.
is_x86_feature_detected!宏生成代码,来检测CPU是否支持AVX2,如果支持,则调用foo_avx2函数.如果没有,则回退到非AVX实现,foo_fallback.

std::arch专门用来构建这类工作.并在高级上用稳定std::simd的模块.
如下,没有simd.

let lots_of_3s = (&[-123.456f32; 128][..]).iter().map(|v| {9.0 * v.abs().sqrt().sqrt().recip().ceil().sqrt() - 4.0 - 2.0}).collect::<Vec<f32>>();

要用SIMD,请更改为:

let lots_of_3s = (&[-123.456f32; 128][..]).simd_iter().simd_map(f32s(0.0), |v| {f32s(9.0) * v.abs().sqrt().rsqrt().ceil().sqrt() - f32s(4.0) - f32s(2.0)}).scalar_collect();

它几乎是一样的:simd_iter而不是iter,simd_map而不是map,f32s(2.0)而不是2.0.但是,你获得为你生成的SIMD化版本.

dyn特征

给定Foo特征,如下是一个特征对象:

Box<Foo>

Rust1.27中,稳定了一个新的dyn Trait语法.特征对象现在如下:

//旧`=>`新
Box<Foo> => Box<dyn Foo>
&Foo => &dyn Foo
&mut Foo => &mut dyn Foo

同样,对其他指针类型,Arc<Foo>现在是Arc<dyn Foo>等.

开发了可自动升级代码到更新习惯用语的rustfix的工具.

#[must_use]函数

最后,升级了#[must_use]属性:现在可用于函数.
以前,它仅适合Result<T,E>等类型.但是现在,可这样:

#[must_use]
fn double(x: i32) -> i32 {2 * x
}
fn main() {double(4); //警告:必须使用的`"double"`的未使用返回值let _ = double(4); //(无警告)
}

稳定了几个新API:

DoubleEndedIterator::rfind
DoubleEndedIterator::rfold
DoubleEndedIterator::try_rfold
Duration::from_micros
Duration::from_nanos
Duration::subsec_micros
Duration::subsec_millis
HashMap::remove_entry
Iterator::try_fold
Iterator::try_for_each
NonNull::cast
Option::filter
String::replace_range
Take::set_limit
hint::unreachable_unchecked
os::unix::process::parent_id
process::id
ptr::swap_nonoverlapping
slice::rsplit_mut
slice::rsplit
slice::swap_with_slice

Cargo更改目标目录,用--target-dir标志.
Cargo试自动发现项目中的测试,示例和二进制文件.但是,有时需要显式配置.

快速摘要:

1,RLS不再干扰命令行生成
2,有时,Rustfmt停止了错误文本格式
3,不再允许通过非终止Traitimpl Trait返回main.
4,对implTrait类型的方法参数,不再适合::<>(turbofish)
5,NaN>NaN常量环境中,不再返回true.
6,Rustup应该不会再因为缺少文档而失败
7,如果代码继续编译,则只有更改浮点比较,可能会改变行为.

fn main() -> Result<(), std::io::Error> {Ok(())
}

如下.

struct Foo;
impl Foo {fn bar(&self, _arg: impl Copy) {}
}
fn main() {Foo.bar::<u32>(0);
}

浮点比较:

use std::f64::NAN;
const FOO: bool = ::std::f64::NAN >= ::std::f64::NAN;
# On 1.26.0
assert_eq!(FOO, true);
# On 1.26.1
assert_eq!(FOO, false);//假

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

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

相关文章

C#多线程Thread、Task

在C#中&#xff0c;线程可以用于完成需要耗费较长时间的操作&#xff0c;而不会阻塞用户界面。一个程序可以有多个线程&#xff0c;每个线程可以并行执行代码。 在C#中&#xff0c;可以使用System.Threading.Thread类来创建和控制线程&#xff0c;使用System.Threading.Mutex类…

javascript二维数组(22)JavaScript 中的数据类型有哪些?如何进行类型转换?

在 JavaScript 中&#xff0c;数据类型主要分为两种&#xff1a;基本类型和对象类型。 基本类型是指原始数据类型&#xff0c;包括&#xff1a; Number&#xff1a;数值型。可以是整数或浮点数。String&#xff1a;字符串型。用于表示文本数据。Boolean&#xff1a;布尔型。包…

ZYNQ7000---FLASH读写

提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Flash是什么&#xff1f;二、Flash的分类1、内部结构&#xff08;接口&#xff09;区分&#xff1a;2、外部接口区分&#xff1a;SPIQPSI Flash: QSPI 控制…

k8s pod 处于Terminating的原因分析和解决处理——筑梦之路

之前整理了一下各种资源长时间无法回收&#xff0c;解决处理的命令行 k8s 各种资源Terminationg状态处理 —— 筑梦之路_k8s自定义资源修改状态-CSDN博客 这里具体整理下pod长时间处于Terminating状态的相关知识&#xff0c;主要是对前面的补充和完善&#xff0c;作为笔记记录…

京东数据挖掘(京东数据采集):2023年Q3电脑行业数据分析报告

近年来&#xff0c;在远程办公、远程教育等需求的刺激下&#xff0c;电脑的销售增长较为显著。不过&#xff0c;随着市场的成熟乃至饱和&#xff0c;电脑销售市场也逐渐出现增长困难、需求疲软等问题。 2023年第三季度&#xff0c;电脑市场的出货量同比下滑。根据鲸参谋电商数据…

德迅云安全为您介绍关于抗D盾的一些事

抗D盾概述&#xff1a; 抗D盾是新一代的智能分布式云接入系统&#xff0c;接入节点采用多机房集群部署模式&#xff0c;隐藏真实服务器IP&#xff0c;类似于网站CDN的节点接入&#xff0c;但是“抗D盾”是比CDN应用范围更广的接入方式&#xff0c;适合任何TCP 端类应用包括&am…

GB28181 编码规则说明

背景&#xff1a; GB/T28181-2011 《安全防范视频监控联网系统信息传输、交换、控制技术要求》中规定了联网系统应对前端设备、监控中心设备、用户终端ID进行统一编码,该编码具有全局唯一性。这就是国标编码。编码分20位和18位&#xff0c;其中18位编码已经淘汰。下文中&#…

React hooks(一):useState

1.React hooks React hooks是React16.8的新特性&#xff0c;可以让React函数组件具有状态&#xff0c;并提供类似componentDidMount和componentDidUpdate等生命周期方法。 React 早期版本&#xff0c;类组件可以在shouldComponentUpdate中&#xff0c;通过判断props和state是…

搭建yum源并定时同步

一 、安装yum源 1-准备yum目录 cd /data/www/html createrepo -v ./目录 2-安装服务 yum -y install httpd 3-配置服务 /etc/httpd/conf/httpd.conf 4.配置/etc/yum.repo.d/local.rpeo 二、定时更新yum源 #1. 同步整个源到指定目录 [rootV10SP1-1 pac]# reposync -p /root/…

到底什么是Linux?快进来学习!

相信大家对Linux并不陌生吧&#xff1f;Linux 是一种计算机系统&#xff0c;属于基础中的基础&#xff0c;就和我们熟知的Windows一样&#xff0c;都是系统。它是现今最流行和最实用的计算机操作系统&#xff0c;它区别于后台、算法、大数据、前端、测试方向&#xff0c;需要程…

python 随机数生成

生成随机整数 使用 randint() 函数可以生成指定范围内的随机整数。 import random # 生成1到10之间的随机整数 random_int random.randint(1, 10) print(random_int) 生成随机浮点数 random() 方法用于生成 0 到 1 之间的随机浮点数。 import random # 生成0到1之间…

LVGL 日历组件

LVGL 日历组件 calendar 添加到默认组中 lvgl的 calendar 组件会默认添加到旋钮按键组中&#xff0c;需要手动将其删除&#xff0c;否则会聚焦到不可见的控件上。 lv_obj_set_style_pad_all(calendar, 8, LV_STATE_DEFAULT); lv_group_remove_obj(calendar);修改时间范围 年…

[msg_msg] corCTF2021 -- fire_of_salvation

前言 msg_msg 是 kernel pwn 中经常用作堆喷的结构体. 其包含一个 0x30 大小的 header. 但 msg_msg 的威力远不如此, 利用 msg_msg 配合其他堆漏洞可以实现任意地址读写的功能. 程序分析 本题给了源码, 可以直接对着源码看. 并且题目给了编译配置文件, 所以可以直接编译一个…

C++ const与符号表

fun_cpp.cpp //const修饰的全局变量 默认是内部链接&#xff08;只在当前源文件有效 不能直接用于其他源文件&#xff09; const int num_pp 100;//如果必须用在其他源文件 使用只读的全局变量 必须加extern将num转换成外部链接 //extern const int num_pp 100;main_cpp.cpp…

Linux/麒麟系统上部署Vue+SpringBoot前后端分离项目

目录 1. 前端准备工作 1.1 在项目根目录创建两份环境配置文件 1.2 环境配置 2. 后端准备工作 2.1 在项目resources目录创建两份环境配置文件 2.2 环境配置 3. 前后端打包 3.1 前端打包 3.2 后端打包 4、服务器前后端配置及部署 4.1 下载、安装、启动Nginx 4.2 前端项目部署…

Elasticsearch搜索分析引擎本地部署与远程访问

文章目录 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 Elasticsearch是一个基于Lucene库的分布式搜索和分析引擎&#xff0c;它提供了一个分布式、多…

【小白的Spring源码手册】 BeanFactoryPostProcessor的注册和用法(BFPP)

目录 前言应用1. 手动注册2. 自动注册3. 优先级 前言 沿用上一篇文章的流程图&#xff0c;我们的注解类应用上下文中的AnnotationConfigApplicationContext#scan(String...)方法已经将所有BeanDefinition注册到了IoC容器中。完成注册后&#xff0c;开始执行AbstractApplicatio…

信息的浏览

万维网(WWW)是目前Internet上最流行的一种服务&#xff0c;它是建立在Internet上的多媒体集合信息系统。它利用超媒体的信息获取技术&#xff0c;通过一种超文本的表达方式&#xff0c;将所有WWW上的信息连接在一起。我们使用浏览器浏览网上的信息。 ▶浏览器 浏览器是指可以…

PHP低版本安全问题

目录 1、PHP弱类型问题 1.1 MD5、 SHA1 弱比较问题 1.2 数组 0 1&#xff09;函数无法处理数组&#xff0c;返回0 2&#xff09;strcmp 2、特殊字符串导致的问题 2.1 "ffifdyop" 与 md5(string,raw) 2.2 ereg函数漏洞&#xff1a;00 截断 3、正则匹配问…

物联网AI MicroPython学习之语法UART通用异步通信

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; UART 介绍 模块功能: UART通过串行异步收发通信 接口说明 UART - 构建UART对象 函数原型&#xff1a;UART(id, baudrate&#xff0c;bits, parity&#xff0c;stop, tx, rx)参数说明&#xff1a; 参数类…