[rust] Rust与C++20编码习惯对照
admin
2024-02-04 13:52:28
0

Rust

文章目录

  • Rust
    • 差异
      • 所有权
      • 字符串
      • 类型结构
      • 生命周期
      • 常量
    • 基本类型
    • 构造类型
    • String
    • Vec
    • HashMap
    • File
    • 泛型
    • Trait
      • 编译时多态
      • 运行时多态
    • 函数
    • Lambda/闭包/匿名函数
    • 模式匹配
    • 迭代器
    • 智能指针
    • 析构函数
    • 线程
    • 线程通信
      • 管道
      • 信号量
    • C交互

差异

所有权

rust可以将不变所有权转为可变所有权

let a = String::from("str");
let mut b = a;

C++只能开发者自我约束, 在所有权移动前不去修改对象

const auto a = string("str");
auto b = move(a); // 降为复制auto a = string("str");
auto b = move(a); // 有效移动

字符串

rust的字符串由长度和内容组成, 其中字符串不要求以0结尾.

let a = "str";

C++的字符串以内容和0结尾组成, 其中字符串一定以0结尾.

const char* a = "str";

类型结构

-rust大小C++大小
引用类型&T &mut Tsconst T& T&s
指针类型*const T *mut T (unsafe)sconst T* T*s
数组类型[T; N]size_of::() * NT[N]sizeof(T) * N
切片类型&[T] &mut [T] &str &mut str2sspan span
span span
2s

生命周期

函数返回的每一个引用类型和切片类型都需要从参数类型中获取生命周期, 如

fn foo(a: &str, b: &str) -> &str

一种选取是任选一个参数, 如取生命周期与a相同

fn foo<'a>(a: &'a str, b: &str) -> &'a str

另一种选取是取多个参数的最小值, 如取生命周期为a, b, c的最小值

fn foo<'a>(a: &'a str, b: &'a str, c: &'a str) -> &'a str

如不写明生命周期

  1. 当参数中只有一个引用类型/切片类型, 则取其生命周期
  2. 当参数中含&self&mut self, 则取其生命周期
  3. 报错

常量

const I: i32 = 3;			constexpr int I = 3;
const S: &str = "3";		constexpr const char* S = "3";

基本类型

查询类型大小可用

use mem;
mem::size_of::()

在说明大小时, 约定s为本机CPU位宽的字节数, 32位CPU下s=4, 64位CPU下s=8

基本类型字面量后缀字面量格式大小参考C++类型
i8i81signed char
u8u8b'c'1unsigned char
i16i162short
u16u162unsigned short
i32i32(整数默认)4int
u32u324unsigned int
i64i648long long
u64u648unsigned long long
i128i12816
u128u12816
isizeisizesssize_t
usizeusizessize_t
f32f324float
f64f64(小数默认)8double
booltrue, false1bool
&str"str"2sconst char*
char'c'4char32_t
类型不变切片类型参考C++类型不变切片参考C++类型
&str&strconst char[N]
string_view
string_view
String&strstringstring_view
[T; N]&[T]const T[N]
span
span
Vec&[T]vectorspan
类型大小注释参考C++类型
()0默认返回类型void
(i8, i8, i8)3tuple
(i8, i64)16对齐tuple
struct T {}0struct T {}
struct T { a: i8, b: i8, c: i8 }3struct T { int8_t a; int8_t b; int8_t c; }
struct T { a: i64, b: i8 }16对齐struct T { int64_t a; int8_t b; }
enum T {}0class enum T {}
enum T { E1, E2 }1class enum T { E1, E2 }
enum T { E1(f32), E2(u8) }8variant

构造类型

构造新类型

struct NewType(T);					struct NewType { T inner; };struct NewType : T { using T::T; };enum class NewType : T {};

类型别名

type TypeAlias = T;					using TypeAlias = T;typedef T TypeAlias;template
type TypeAlias = U;			using TypeAlias = U;

String

let s = "Hello";					const char* s = "Hello";
let s = String::new();				const auto s = string();
let mut s = String::new();			auto s = string();
s.push_str("bar");					s.append("bar");let s = String::from("Hello");		const auto s = string("Hello");
let slice = &s[0..5];				auto slice = span(s.cbegin(), s.cbegin() + 5);let mut s = String::from("Hello");	auto s = string("Hello");
let slice = &mut s[0..5];			auto slice = span(s.begin(), s.begin() + 5);
let slice = &s[0..5];				auto slice = span(s.cbegin(), s.cbegin() + 5);let s1 = String::from("Hello");		auto s1 = string("Hello");
let s2 = String::from(", world");	const auto s2 = string(", world");
let s3 = s1 + &s2;					const auto s3 = move(s1) + s2;
let s = format!("{}-{}", s2, s3);  	const auto s = format("{}-{}", s2, s3);

Vec

let v = vec![1, 2, 3];             	const auto v = vector{1, 2, 3};
let first = &v[0];					auto& first = v[0];
let mut v = vec![1, 2, 3];			auto v = vector{1, 2, 3};
v.push(4);							v.emplace_back(4);
let first = &v[0];					const auto& first = v[0];
let v = vec![1, 2, 3];				const auto v = vector{1, 2, 3};
for i in &v {						for (auto& i in v) {println!("{}", i);					cout << i << endl;
}									}
let mut v = vec![1, 2, 3];			auto v = vector{1, 2, 3};
for i in &mut v {					for (auto& i in v) {*i += 1;							i += 1;
}									}

HashMap

let mut scores = HashMap::new();			auto scores = unordered_map();
scores.insert(String::from("Blue"), 10);	scores["Blue"] = 10;
let team_name = String::from("Blue");		const auto team_name = string("Blue");
let score = scores.get(&team_name);			const auto score = scores.find(team_name);
if let Some(score) = score {				if (score != scores.end()) {println!("{}", score);						cout << score->second << endl;
}											}
for (key, value) in &scores {				for (const auto& [key, value] : scores) {println!("{}: {}", key, value);				cout << key << ": " << value << endl;
}											}

File

let f = File::open("hello.txt");	FILE* f = fopen("hello.txt", "rb");
let mut f = match f {				if (!f) {Ok(file) => file,					return;Err(e) => return				}
};

注: rust一般用?处理Result类型的值, 示例不是最佳实践.

泛型

									template
fn max(list: &[T]) -> T {		T max(span list) {let mut m = list[0];				T m = list[0];for &item in list {					for (auto& item : list) {if item > m {						if (item > m) {m = item;							m = item;}									}}									}m									return m;
}									}

C++的T可以是不完整类型, rust的T默认是Sized, 可确定大小的

									template
fn f() {}				void f() {}template 
fn f() {}						void f() {}

Trait

编译时多态

											template
trait Summary {								concept Summary = requires(T const& t) {summarize_author(t);summarize(t);}fn author(&self) -> String;				string author(auto const& self);fn summarize(&self) -> String {			string summarize(auto const& self) {format!("(Read more from {}...)",		return format("(Read more from {}...)",self.author())									   author(self));}										}
}
struct Tweet {								struct Tweet {pub username: String,						string username;pub content: String,						string content;pub reply: bool,							bool reply;pub retweet: bool,							bool retweet;
}											};impl Summary for Tweet {					template<>fn author(&self) -> String {			string author(Tweet const& self) {format!("@{}", self.username)			return "@" + self.username;}										}
}fn main() {									int main() {let tweet = Tweet {							auto tweet = Tweet {username: String::from("ebooks"),			.username = "ebooks",content: String::from("content"),			.content = "content",reply: false,								.reply = false,retweet: false,								.retweet = false,};											};println!("1 new tweet: {}",					cout << "1 new tweet: "tweet.summarize());					 << summarize(tweet) << endl;
}											}
											template
fn notify(item: &impl Summary) {			void notify(T const& item) {println!("Breaking news! {}",				cout << "Breaking news! "item.summarize());						 << summarize(item) << endl;
}											}
												template
fn some_function(t: &T, u: &U) -> i32		int some_function(T const& t, U const& u)where T: Display + Clone,						requires Display && Clone &&U: Clone + Debug									 Clone && Debug
{												{
												template
fn returns_summarizable() -> impl Summary {		T returns_summarizable() {Tweet {											return Tweet {username: String::from("ebooks"),				.username = "ebooks",content: String::from("content"),				.content = "content",reply: false,									.reply = false,retweet: false,									.retweet = false,}												};
}												}

运行时多态

pub trait Draw {									struct Draw {fn draw(&self);										virtual draw() const = 0;
}													};pub struct Screen {									struct Screen {pub components: Vec>					vector> components;
}													
impl Screen {										pub fn run(&self) {									void run() const {for component in self.components.iter() {			for (const auto& component : components) {component.draw();									component->draw();}													}}													}
}													};
pub struct Button {						struct Button : public Draw {pub width: u32,							uint32_t width;pub height: u32,						uint32_t height;pub label: String						string label;
}											
impl Draw for Button {						fn draw(&self) {						void darw() const override {}										}
}										};

函数

fn f() -> ! {}						[[noreturn]] void f() {}

注: C++的[[noreturn]]非强制约束

Lambda/闭包/匿名函数

let f = |a: i32, b: i32| -> i32 { a };	const auto f = [](int a, int b) -> int { return a; };
let f = |a, b| { a };					const auto f = [](auto a, auto b) { return a; };
let f = |a| a;							const auto f = [](auto a) { return a; };

注: rust的写法得到的是函数, 参数类型确定, 而C++的写法得到的是函数模板, 但亦可手动确定参数类型.

let s = String::from("Hello");			auto s = string("Hello");
let f = |a| s.len() + a;				const auto f = [&](auto a) { return s.length() + a; };
let f = move |a| s.len() + a;			const auto f = [s = move(s)](auto a) { return s.length() + a; };
let mut f = move |a| s.push_str(a);		auto f = [s = move(s)](string_view a) mutable { s.append(a); };

模式匹配

字面量

let x = 1;								auto x = 1;
match x {								switch (x) {1 => {},							case 1: { break; }2 => {},							case 1: { break; }_ => {},							default: { break; }
}										}

枚举

let x = Some(5);						auto x = optional(5);
let y = 10;								auto y = 10;
match x {								Some(50) => {},						if (x && *x == 50) {}Some(y) => {},						else if (x && *x == y) {}_ => {},							else {}
}										

多模式

let x = 1;								auto x = 1;
match x {								switch (x) {1 | 2 => {},						case 1: case 2: { break; }3 => {},							case 3: { break; }_ => {}								default: { break; }
}										}

区间匹配

let x = 'c';							auto x = 'c';
match x {								'a'..'j' => {},						if ('a' <= x && x <= 'j') {}'k'..'z' => {},						else if ('k' <= x && x <= 'z') {}_ => {}								else {}
}

解构

let (x, y) = (1, 2);					auto [x, y] = make_tuple(1, 2);
struct Point {							struct Point {x: i32,									int x;y: i32,									int y;
}										};
let Point { x, y } = Point { 2, 3 };	auto [x, y] = Point { 2, 3 };
match p {								Point { x, y: 0 } => {},			if (p.y == 0) {}Point { x: 0, y } => {},			else if (p.x == 0) {}Point { x, y } => {},				else {}
}
enum Message {							Quit,								struct Quit {};Move { x: i32, y: i32 },			struct Move { int x; int y; };Write(String),						struct Write { string val };ChangeColor(i32, i32, i32)			struct ChangeColor { tuple val; };
}										struct Message : variant {using variant::variant;};
let m = Message::ChangeColor(0, 1, 2);	Message m = ChangeColor { { 0, 1, 2 } };
match m {								visit([](auto& val) {Message::Quit => {						if constexpr (is_assignable_v) {},										}Message::Move { x, y } => {				else if constexpr (is_assignable_v) {auto [x, y] = val;},										}Message::Write(text) => {				else if constexpr (is_assignable_v) {auto text = move(val.val);},										}Message::ChangeColor(r, g, b) => {		else {static_assert(is_assignable_v);auto [r, g, b] = val.val;},										}
}										}, m);

迭代器

let mut v1 = vec![1, 2, 3];			auto v1 = vector{1, 2, 3};
for val in v1 {}					for (auto val : v1) {}
for val in &v1 {}					for (const auto& val : v1) {}
for val in &mut v1 {}				for (auto& val : v1) {}
for val in v1.iter() {}				for (auto& val : span(v1.cbegin(), v1.cend())) {}
for val in v1.iter_mut() {}			for (auto& val : span(v1.begin(), v1.end())) {}	
let v1 = vec![1, 2, 3];				const auto v1 = vector{1, 2, 3};
let mut it = v1.iter();				auto it = v1.begin(), itEnd = v1.end();
assert_eq!(it.next(), Some(&1));	assert(it != itEnd); assert(*it == 1);
assert_eq!(it.next(), Some(&2));	assert(++it != itEnd); assert(*it == 2);
assert_eq!(it.next(), Some(&3));	assert(++it != itEnd); assert(*it == 3);
assert_eq!(it.next(), None);		assert(++it == itEnd);
struct Counter {								struct Iter {count: i32,										using difference_type = ptrdiff_t;
}													using value_type = int;value_type count;
impl Counter {										bool operator==(Iter const& other) const {fn new() -> Counter {								 return count == other.count;Counter { count: 0 }						}}												Iter& operator++() {
}														++count;return *this;
impl Iterator for Counter {							}type Item = i32;								void operator++(int) {++*this;fn next(&mut self) -> Option {		}if self.count < 5 {							value_type operator*() const {self.count += 1;							return count;Some(self.count)						}} else {								};None								struct Counter {}											static Iter begin() { return Iter { 0 }; }}												static Iter end() { return Iter { 5 }; }
}												};fn main() {										int main() {let cnt = Counter::new();						auto cnt = Counter();for val in cnt {								for (auto val : cnt) {println!("{}", val);							cout << val << endl;}												}
}												}
let mut v1 = vec![1, 2, 3];			auto v1 = vector{1, 2, 3};
let total = v1.iter().sum();		const auto total = accumulate(v1.begin(), v1.end(), 0);
let m = v1.iter().map(|x|			auto m = v1 | views::transform([](auto x) {x + 1								return x + 1;
);									});
let v2: Vec<_> = v1.iter().map(|x|	auto v2_views = v1 | views::transform([](auto x) {x + 1								return x + 1;
).collect();						});auto v2 = vector(v2_views.begin(), v2_views.end());
let sum: i32 = Counter::new()		auto ints = views::zip(Counter(), Counter() | views::drop(1)).zip(Counter::new().skip(1))		| views::transform([](auto ab) {.map(|(a, b)| a * b)					return get<0>(ab) * get<1>(ab);}) | views::filter([](auto x) {.filter(|x| x % 3 == 0)					return x % 3 == 0;});.sum();							auto sum = accumulate(ints.being(), ints.end(), 0);

智能指针

  • unique
let b = Box::new(5);				auto b = make_unique(5);
  • 不变shared
let b = Rc::new(5);					auto b = make_shared(5);
let c = Rc::clone(&b);				auto c = b;
let d = b.clone();					auto d = b;
let cnt = Rc::strong_count(&d);		auto cnt = d.use_count();
  • 可变shared
let b: RefCell> = RefCell::new(vec![]);		auto b = make_shared>();
b.borrow_mut().push("Hello");							b->emplace_back("Hello");
b.borrow().len();										b->size();

析构函数

struct Data {						struct Data {data: String,						string data;
}									
impl Drop for Data {			fn drop(&mut self) {				~Data() {}									}
}									};

注: 可用mem::drop将对象提前销毁, C++中只能使用}隐式销毁.

线程

let t = thread::spawn(|| {					auto t = thread([] {thread::sleep(								this_thread::sleep_for(Duration::from_millis(1000)					chrono::millisceonds(1000););											);
});											});
t.join().unwrap();							t.join();
let v = vec![1, 2, 3];						auto v = vector{1, 2, 3};
let t = thread::spawn(move || {				auto t = thread([v = move(v)] {for i in &v {}								for (const auto& i : v) {}
});											});

线程通信

管道

send recv用法

let (tx, rx) = mpsc::channel();
let t = thread::spawn(move || {tx.send(String::from("hi")).unwrap();
});
let s = rx.recv().unwrap();

迭代用法

let (tx, rx) = mpsc::channel();
let t = thread::spawn(move || {let vals = vec![String::from("a"), String::from("b"), String::from("c"),];for val in vals {tx.send(val).unwrap();};
});
for s in rx {}

多sender

let (tx1, rx) = mpsc::channel();
let tx2 = tx1.clone();
thread::spawn(move || {tx1.send(String::from("a"));
});
thread::spawn(move || {tx2.send(String::from("b"));
});

信号量

										auto num = 5;
let m = Mutex::new(5);					auto m = mutex();
{										{let mut num = m.lock().unwrap();		auto guard = lock_guard(m);*num = 6;								num = 6;
}										}

注: Mutex = tuple

let cnt = Arc::new(Mutex::new(0));
for _ in 0..10 {let cnt = Arc::clone(&cnt);thread::spawn(move || {let mut num = cnt.lock().unwrap();*num += 1;});
}

注: Arc类同Rc, 其中计数器用atomic

-可变不变
单线程RefCellRc
多线程MutexArc

C交互

导入C (unsafe)

extern "C" {						extern "C" {fn abs(input: i32) -> i32;			int abs(int input);
}									}fn main() {							int main() {unsafe {							abs(233);						abs(233);}
}									}

导出C

#[no_mangle]
pub extern "C" fn f() {				extern "C" void f() {
}									}

联合体 (unsafe)

#[repr(C)]							
union MyUnion {						union MyUnion {f1: u32,							uint32_t f1;f2: f32,							float f2;
}									};let u = MyUnion { f1: 1 };			auto u = MyUnion { .f1 = 1 };
let f = unsafe { u.f1 };			auto f = u.f1;
unsafe {match u {						MyUnion { f1: 10 } => {}	if (u.f1 == 10) {}MyUnion { f2 } => {}		else {}}
}

相关内容

热门资讯

制作安卓系统主题软件,安卓系统... 你有没有想过,给你的安卓手机换一个全新的面貌?没错,就是那种一打开手机,就能感受到完全不同的风格和氛...
安卓系统平板怎么截屏,操作指南... 亲爱的平板用户,你是不是也和我一样,有时候想记录下平板上的精彩瞬间,却发现截屏功能有点神秘?别担心,...
安卓系统不推送更新,揭秘背后的... 最近是不是发现你的安卓手机有点儿“懒”啊?更新推送总是慢吞吞的,让人等得花儿都谢了。别急,今天就来给...
ape格式转换安卓系统,享受音... 你有没有想过,你的安卓手机里的ape格式音乐文件,竟然可以通过一个小小的转换,焕发出全新的生命力?没...
获取安卓系统加载器,核心功能与... 你有没有想过,你的安卓手机里那些神奇的软件和游戏是怎么被安装到你的设备上的呢?没错,就是通过一个叫做...
安卓系统文件夹在哪,安卓系统文... 你有没有遇到过这样的情况:手机里乱糟糟的,想找个文件却找不到?别急,今天就来给你揭秘安卓系统文件夹的...
安卓手感最好的裸机系统,安卓手... 安卓手感最好的裸机系统:探索极致体验的秘密武器在数字世界中,我们常常被各种功能和复杂操作所包围,尤其...
nas如何刷回安卓系统,轻松刷... 你有没有想过,你的NAS(网络附加存储)突然间变成了一个安卓的小天地?别急,这可不是什么天方夜谭,而...
荣耀沿用的安卓系统吗,打造个性... 你有没有注意到,最近荣耀的新机发布,大家都在热议一个问题:荣耀沿用的安卓系统吗?这可是个让人好奇不已...
快麦erp系统安卓下载,一键下... 你有没有听说最近一款叫做快麦ERP系统的软件在安卓平台上大受欢迎呢?没错,就是那个能让你企业管理如虎...
华为安卓系统下载app,一步到... 你有没有发现,最近华为手机的用户们都在忙活一件大事儿?没错,那就是下载安卓系统上的各种app啦!这可...
原生安卓系统游戏模式,畅享沉浸... 亲爱的手机游戏爱好者们,你是否曾为手机游戏运行不畅而烦恼?又或者,你是否渴望在游戏中获得更极致的体验...
安卓9改系统语言设置,轻松切换... 你有没有发现,手机里的语言设置有时候真的让人头疼?比如说,你突然想用一下安卓9的系统语言设置,结果发...
怎么升级安卓最新系统,畅享安卓... 亲爱的手机控们,你是不是也和我一样,对安卓系统的更新充满了期待?每次系统升级,都仿佛给我们的手机带来...
安卓系统电视跳舞毯,家庭娱乐新... 你有没有想过,家里的电视除了用来追剧、看电影,还能变成一个充满活力的娱乐中心?没错,我要给你介绍的就...
安卓系统维护周期,全方位守护您... 亲爱的手机控们,你是不是也和我一样,对安卓系统的维护周期充满了好奇呢?毕竟,我们的手机可是我们日常生...
安卓系统电脑怎么往下滑,一扫即... 你有没有发现,用安卓系统电脑的时候,有时候屏幕上会出现一些小图标或者应用,你想要快速浏览或者切换,却...
手机中判断安卓系统苹果系统js... 你有没有想过,你的手机里到底装的是安卓系统还是苹果系统呢?这可不是一个小问题哦,因为不同的系统,就像...
window系统和安卓系统还原... 你有没有遇到过手机或电脑突然卡顿,或者不小心删掉了重要的文件?别急,今天就来给你详细说说如何让win...
安卓系统打电话变声器,轻松实现... 安卓系统打电话变声器:探索数字时代的通信革新在数字化浪潮中,智能手机已经成为我们生活中不可或缺的一部...