应用篋:宏dbg!
与可变实例
学习内容
- 了解和学习使用宏方法
dbg!
的借用实例
篇目
宏dbg!
与借用机制
宏方法dbg!
实现打印并返回给定表达式的值,目的进行快速而简陋的调试。该宏类似于程序输出宏println!
,但是宏方法dbg!
使用简单方便,并且它不是以与程序输出在一起,而是单独输出。所以,当使用在线图书执行它时,我们将看不到其输出结果。
先看一个宏方法dbg!
的简单应用实例:
# #![allow(unused_variables)] #fn main() { // File: ./examples/dbg/mut_macro.rs // #[cfg(feature = "cp")] let string :String = format!("{}", "Hello"); dbg!(std::mem::size_of_val(&string)); dbg!(&string); dbg!(string); #}
其输出结果如下:
官方文档解释宏方法dbg!
如下:
Invoking the macro on an expression moves and takes ownership of it before returning the evaluated expression unchanged. If the type of the expression does not implement Copy and you don't want to give up ownership, you can instead borrow with dbg!(&expr) for some expression expr.
中文翻译:
调用基于表达式
expr
的宏,会转移对象并获取其所有权,然后再返回已求值的表达式不变。如果表达式的类型未实现特质Copy
且不想放弃所有权,则对于一些表达式expr
可以改用这种调用方法dbg!(&expr)
。
下面程序的目的就是来验证上面阐述的第一句话。一旦使用了没有实现特质Copy
的类型String
对象,是否宏方法dbg!
转移该对象,并且调用该宏结束以后,就拿走了该对象的所有权。只要运行一下该程序,就得到了验证。在实际中,都会使用这种dbg!(&expr)
调用方法。
# #![allow(unused_variables)] #fn main() { // File: ./examples/dbg/mut_macro.rs // ANCHOR = "error_01" // error[E0382]: borrow of moved value: `string` let string = format!("{}", "Hello"); dbg!(string); dbg!(&string); #}
可变对象及其固定引用对象
对于可变类型对象,在使用宏方法dbg!
时,可以绑定其固定引用对象,具体实例如下:
# #![allow(unused_variables)] #fn main() { // File: ./examples/dbg/mut_macro.rs // #[cfg(feature = "ok")] let mut string :String = format!("{}", "Hello"); string.push('!'); let ref_string = &string; dbg!(ref_string); dbg!(ref_string); #}
上面程序运行正常,说明固定引用对象ref_string
的借用是正常的。那么我们可否绑定其可变引用对象呢?
可变对象及其可变引用对象
下面程序将回答上面的问题。对于可变类型对象,在使用宏方法dbg!
时,可以绑定其可变引用对象,将会发生什么?具体实例如下:
# #![allow(unused_variables)] #fn main() { // File: ./examples/dbg/mut_macro.rs // ANCHOR = "error_03" // error[E0382]: use of moved value: `ref_mut_string` dbg!(""); let mut string = format!("{}", "Hello"); string.push('!'); let ref_mut_string = &mut string; dbg!(ref_mut_string); dbg!(ref_mut_string); #}
对于可变引用对象,宏方法dbg!
将收回其所有权。但是前面我们看到,对于固定引用对象,宏方法dbg!
则不会收回其所有权。
题外话
创建类型String
对象方法
# #![allow(unused_variables)] #fn main() { let new_string :String = String::new(); let from_string :String = String::from("Hello"); let format_string :String = format!("{}", "Hello"); let to_string :String = "Hello".to_string(); #}
类型String
:方法push
和push_str
在创建类型String
的可变对象时,经常会使用到方法push()
和push_str()
,前者方法参数类型是char
,而后者方法参数类型&str
。