sui_rust/ch01/ctfe.rs
1#![allow(unused_variables)]
2//! 第一章:Rust语言基础
3//! 1.4 语法面面观(二):面向表达式(中)
4//!
5//!
6//!
7
8/**
9 ### 必须是常量表达式才能在常量上下文使用
10
11 ```
12 fn main(){
13 let an = (42,).0;
14 const AN: i32 = an; // Error: attempt to use a non-constant value in a constant
15 }
16 ```
17*/
18pub fn must_const_expr() {
19 println!(" 1.4 : Must Const erpr in Const Context ");
20}
21
22/**
23
24 ### const fn
25
26
27 ```
28 const fn len() -> usize { 3 }
29
30 fn main(){
31 // 数组长度是常量上下文
32 let array: [i32; len()] = [1, 2, 3];
33 }
34 ```
35
36*/
37pub fn const_array_len() {
38 println!("1.4 : Expression-Oriented programming: const array len");
39}
40
41/**
42 ### const fn : fib
43
44 ```
45 const fn gcd(a: u32, b: u32) -> u32 {
46 match (a, b) {
47 (x, 0) | (0, x) => x,
48
49 (x, y) if x % 2 == 0 && y % 2 == 0 => 2*gcd(x/2, y/2),
50 (x, y) | (y, x) if x % 2 == 0 => gcd(x/2, y),
51
52 (x, y) if x < y => gcd((y-x)/2, x),
53 (x, y) => gcd((x-y)/2, y),
54 }
55 }
56
57
58 const fn fib(n: u128) -> u128 {
59 const fn helper(n: u128, a: u128, b: u128, i: u128) -> u128 {
60 if i <= n {
61 helper(n, b, a + b, i + 1)
62 } else {
63 b
64 }
65 }
66 helper(n, 1, 1, 2)
67 }
68
69 const X: u128 = fib(10);
70 const GCD: u32 = gcd(21, 7);
71
72 fn main(){
73 println!("{}", X);
74 println!("{}", GCD);
75 }
76
77 ```
78
79*/
80pub fn const_fib() {
81 println!("1.4 : Expression-Oriented programming: const fib");
82}
83
84/**
85
86 ### const fn
87
88 ```
89 const UNIT_TUPLE: [(u64, &str); 6] = {
90 let mut i = 0;
91 [
92 (1 << (10 * { i += 1; i }), "KiB"),
93 (1 << (10 * { i += 1; i }), "MiB"),
94 (1 << (10 * { i += 1; i }), "GiB"),
95 (1 << (10 * { i += 1; i }), "TiB"),
96 (1 << (10 * { i += 1; i }), "PiB"),
97 (1 << (10 * { i += 1; i }), "EiB")
98 ]
99 };
100
101 const fn square_area(a: i32) -> i32 {
102 let area = a * a;
103 area
104 }
105
106 const AREA: i32 = square_area(5);
107
108 fn main (){
109 dbg!(UNIT_TUPLE);
110 dbg!(AREA);
111 }
112
113 ```
114*/
115pub fn const_fn_() {
116 println!(" 1.4 : Const fn ");
117}
118
119/**
120
121 ### 展示错误的 const 求值用法
122
123 ```
124 #![feature(const_fn)]
125
126 // Error
127 const fn hello() -> String{
128 "Hello".to_string()
129 }
130
131 // Error
132 const S : String = hello();
133
134 fn main(){
135 println!(" {:?} ", S);
136 }
137
138 ```
139*/
140pub fn const_fn_error() {
141 println!(" 1.4 : Const fn Error ");
142}
143
144/**
145 ### 修正错误的 const 求值用法
146
147 ```
148
149 const fn hello() -> &'static str{
150 "Hello"
151 }
152
153 const Y: &str = hello();
154
155 fn main(){
156 println!("{}", Y);
157 }
158
159 ```
160*/
161pub fn fixed_const_fn_error() {
162 println!(" 1.4 : Fixed Const fn Error ");
163}
164
165/**
166
167 ### 其他的Const fn 用法
168
169 ```
170 #[derive(Debug)]
171 struct Answer(u32);
172 const A: Answer = Answer(42);
173
174 fn main(){
175 println!("{}", A);
176 }
177
178 ```
179*/
180pub fn others_const_fn() {
181 println!(" 1.4 : Others Const fn ");
182}
183
184/**
185
186 ### 编译期计算原理:MIR 展示
187 ```
188 const fn anwser() -> u32 { 42 }
189
190 const A: u32 = anwser();
191
192 fn main(){
193 A;
194 }
195 ```
196
197*/
198pub fn mir_show() {
199 println!(" 1.4 : MIR show ");
200}
201
202/**
203
204 ### If True && While True
205
206 ```
207 fn if_true(x: i32) -> i32 {
208 if true { // error[E0308]: mismatched types,expected type `i32` found type `()`
209 return x+1;
210 }
211 }
212
213 fn while_true(x: i32) -> i32 {
214 while true { // error[E0308]: mismatched types,expected type `i32` found type `()`
215 return x+1;
216 }
217 }
218
219 fn main() {
220 let y = while_true(5);
221 assert_eq!(y, 6);
222
223 let y = if_true(5);
224 assert_eq!(y, 6);
225
226 let x;
227 // while true { x = 1; break; }
228 loop { x = 1; break; }
229 println!("{}", x);
230
231 }
232 ```
233
234*/
235pub fn if_while_true() {
236 println!(" 1.4 : If True && While True")
237}
238
239/**
240 ### const generic
241
242 ```
243 #![feature(min_const_generics)]
244 #![feature(const_in_array_repeat_expressions)]
245
246 use core::mem::MaybeUninit;
247
248 #[derive(Debug)]
249 pub struct ArrayVec<T, const N: usize> {
250 items: [MaybeUninit<T>; N],
251 length: usize,
252 }
253
254 impl<T, const N: usize> ArrayVec<T, {N} > {
255 pub const fn new() -> ArrayVec<T, {N} > {
256 ArrayVec {
257 items: [MaybeUninit::uninit(); N],
258 length: 0,
259 }
260 }
261
262 #[inline]
263 pub const fn len(&self) -> usize { self.length }
264
265 #[inline]
266 pub const fn is_empty(&self) -> bool { self.len() == 0 }
267
268 #[inline]
269 pub const fn capacity(&self) -> usize { N }
270
271 #[inline]
272 pub const fn is_full(&self) -> bool { self.len() >= self.capacity() }
273
274 }
275
276 impl<T, const N: usize> Drop for ArrayVec<T, { N }> {
277 #[inline]
278 fn drop(&mut self) {
279 // Makes sure the destructors for all items are run.
280 // self.clear();
281 }
282 }
283
284
285 fn main(){
286 // let mut vector = ArrayVec::new();
287 // println!("{}, {}", vector.len(), vector.capacity());
288 // println!("{:?}", vector);
289 }
290 ```
291*/
292pub fn const_generic_show() {
293 println!(" 1.4 : Const Generic Show")
294}
295
296/**
297
298 ### array chunk 演示
299
300 ```
301 #![feature(array_chunks)]
302 fn main() {
303 let data = [1, 2, 3, 4, 5, 6];
304 let sum1 = data.array_chunks().map(|&[x, y]| x * y).sum::<i32>();
305 assert_eq!(sum1, (1 * 2) + (3 * 4) + (5 * 6));
306
307 let sum2 = data.array_chunks().map(|&[x, y, z]| x * y * z).sum::<i32>();
308 assert_eq!(sum2, (1 * 2 * 3) + (4 * 5 * 6));
309 }
310
311 ```
312*/
313pub fn array_chunk_show() {
314 println!(" 1.4 : Array Chunks Show")
315}