获取当前的时间戳
示例代码如下:
| use std::time::{SystemTime}; fn get_timestamp() -> u64 { match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { Ok(now) => { now.as_secs() }, _ => { std::u64::MAX }, } }
fn main() { println!("Hello, world! now={}", get_timestamp()); }
|
实现函数重载
函数重载
rust本身不支持函数重载,但是可以用泛型trait实现类似于重载的效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| pub trait With<T> { fn with(value: T) -> Self; }
struct Foo { bar: String, baz: i32, quux: bool, }
impl Default for Foo { fn default() -> Self { Foo { bar: "".to_string(), baz: 0, quux: false, } } }
impl Foo { fn new() -> Self { Foo { ..Default::default() } } }
impl With<String> for Foo { fn with(x: String) -> Self { Foo { bar: x, ..Default::default() } } }
impl With<i32> for Foo { fn with(x: i32) -> Self { Foo { baz: x, ..Default::default() } } }
impl With<bool> for Foo { fn with(x: bool) -> Self { Foo { quux: x, ..Default::default() } } }
#[test] fn name() { let a = Foo::with(1); }
|
vec合并数据时防止出现拷贝的方法
当结构体中使用Vec在头部插入一个新的Vec数据时可以通过mem::replace方法来减少数据的拷贝。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| use std::mem; struct Myvec { data: Vec<u8>, count: usize, }
impl Myvec { fn new() -> Myvec { Myvec { data : Vec::new(), count : 0, } }
fn append(&mut self, d:&mut Vec<u8>) { self.data.append(d); }
fn pre_insert(&mut self, d:Vec<u8>) { let mut old = mem::replace(&mut self.data, d); self.data.append(&mut old); }
fn push(&mut self, u:u8) { self.data.push(u); }
fn print(&self) { println!("data{:#?}", self.data); } }
fn main() { let mut v1 = Myvec::new(); let mut v2:Vec<u8> = Vec::new(); v2.push(3); v2.push(4); v1.push(1); v1.push(2); v1.pre_insert(v2); v1.print(); }
|
打印变量地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| fn main(){ let a:i32 = 5; let addr = &a as *const i32 as usize; println!("addr:0x{:X}",addr);
let pa = addr as *mut i32; unsafe{*pa = 100};
println!("value:{}",a); }
|
打印变量T的类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| fn print_type_of<T>(_: &T) { println!("{}", std::any::type_name::<T>()) } fn main() { let s = String::from("hello"); let bytes = s.into_bytes(); assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]); print_type_of(&bytes); let mut mb = bytes; print_type_of(&mb); print_type_of(&mut mb); let mut x = &mut mb; print_type_of(&x); let y = &mut x; print_type_of(&y); }
|
同一个crate内 不同lib或程序间的引用
在同一个大型项目中,可能会建立多个lib,有时候想要以外部调用库的方式测试其中的某个lib的某项功能,这时怎么修改Cargo.toml文件引用工程内的某个lib?
答案是修改Cargo.toml 文件中的[dependencies]
参考arnl/test_simple/test_redis/Cargo.toml
1 2 3 4 5 6 7 8 9 10 11
| [package] name = "test_redis" version = "0.1.0" authors = ["wanghaibin <wanghaibin@qiyi.com>"] edition = "2018"
[dependencies] redis = { path = "../../src/libredis/" }
|
在非tests目录下的测试程序arnl/test_simple/test_redis/src内容如下
1 2 3 4 5 6 7 8 9
| use redis::{redis_string, redis_client};
fn main() { println!("Hello, world!"); let mut stream = redis_client::RedisClient::new("127.0.0.1:6379", &0, &3).unwrap(); let mut rstr = redis_string::RedisString::new(&mut stream); let key = "incrbyfloat_test"; println!("xxxx={:#?}",rstr.incrbyfloat(key, 2.1)); }
|
有趣的所有权问题问题
代码1
1 2 3 4 5 6
| fn main() { let mut v = vec![1,2,3]; let first = &v[0]; v.push(5); println!("Hello, world!, first={}", first); }
|
代码2
1 2 3 4 5 6 7
| fn main() { let mut v = vec![1,2,3]; let first = &v[0]; println!("Hello, world!, first={}", first); v.push(5); }
|
上述代码1
会编译报错,提示error[E0502]: cannot borrow
v as mutable because it is also borrowed as immutable
而代码2
却可以正常编译通过,为什么那?
个人认为这正是rust在在编译期发现问题的优点之一,代码1报借用和可变借用同时存在错误,是因为在print的时候使用first,这时进行所有权规则检查,发现了E0502错误。而代码2
为什么没有报错,是因为在编译时,运行到print进行所有权检测,此时还没有发生所有权问题,而在检测后续的push时first已经没有任何引用或使用,所以相关所有权规则没有问题