你如何在 Rust 的比赛中借用一个值?
how do you borrow a value during match in Rust?
我是 Rust 新手。
我创建了一个结构来保存系统信息。
pub struct systemConfig {
pub admin_address: String,
pub engine_name: Option<String>,
pub group_name: Option<String>
}
我想将此结构传递给 make_msg 函数以创建一个 json 正文并将其作为请求发送到另一台服务器。
fn make_msg(config: systemConfig) -> String{
let (host_name, cpus) = get_system_info();
let engine_name = match config.engine_name {
Some(name) => name,
None => host_name.clone(),
};
let group_name = match config.group_name {
Some(name) => name,
None => String::from("")
};
let msg = json!({
"engineName": engine_name,
"groupName": group_name,
"hostName": host_name,
});
msg.to_string()
}
fn get_system_info() -> (String, usize){
use sysinfo::{ System, SystemExt };
// monitoring info
let mut my_system = System::new_all();
my_system.refresh_all();
// hostname
let hostname = get_hostname(&my_system);
// logical cpu count
let cpus = get_logical_cpus(&my_system);
(hostname, cpus)
}
我有两个问题。
- engine_name和group_name是从process参数中得到的值。 type 被定义为 Option 的原因是它的值不是必需的。如果未输入引擎名称,则填写主机名。如果未输入组名,则将其作为“”(空字符串)发送。
我使用了 match 语法,但是有没有更合适的语法呢? (如果让 Some/None,
更简洁直观)
None => host_name.clone()
,
如果此处不执行clone(),则会出现借用问题。我正在寻找有关使用 clone() 是否正确的方法,或者是否有更好的方法的建议。
我添加测试代码
//cargo.toml
[dependencies]
sysinfo = "0.23.12"
serde_json = { version = "1.0", features = ["arbitrary_precision"] }
use sysinfo::{System, SystemExt};
use serde_json::json;
struct systemConfig {
pub admin_address: String,
pub engine_name: Option<String>,
pub group_name: Option<String>
}
fn main() {
let config = systemConfig {
admin_address: String::from("127.0.0.1:8080"),
engine_name: Some(String::from("hello")),
group_name: Some(String::from("world"))
};
let msg = make_msg(config);
println!("msg: {}", msg);
}
fn make_msg(config: systemConfig) -> String{
let host_name = get_system_info();
let engine_name = match config.engine_name {
Some(name) => name,
None => host_name.clone(),
};
let group_name = match config.group_name {
Some(name) => name,
None => String::from("")
};
let msg = json!({
"engineName": engine_name,
"groupName": group_name,
"hostName": host_name,
});
msg.to_string()
}
fn get_system_info() -> String {
use sysinfo::{ System, SystemExt };
// monitoring info
let mut my_system = System::new_all();
my_system.refresh_all();
// hostname
let hostname = get_hostname(&my_system);
hostname
}
pub fn get_hostname(s: &System) -> String {
s.host_name().unwrap()
}
两个问题,两个答案:
- 展开或替换
Option
的情况很常见,它有自己的功能:Option::unwrap_or
:
let engine_name = config.engine_name.unwrap_or(host_name.clone());
let group_name = config.group_name.unwrap_or(String::from(""));
- 克隆才是正道。在某些情况下,
engineName
和 hostName
将包含相同的字符串,因此在任何时候都需要 .clone()
。
I used the match syntax, but is there a more appropriate syntax? (if let Some/None,, more concise and intuitive)
Option
有一些您可以使用的实用程序。在 engine_name
的情况下,unwrap_or_else()
比你的 match
:
更简洁
let engine_name = config.engine_name
.unwrap_or_else(|| host_name.clone());
对于 group_name
你可以使用 unwrap_or_default()
因为 Default
在 String
returns 上实现了一个空字符串:
let group_name = config.group_name.unwrap_or_default();
请注意,在这种情况下,这两个选项都优于 unwrap_or()
,因为除非需要,否则它们不需要构建替代值。例如,在 engine_name
的情况下,这不会克隆 host_name
除非 config.engine_name
是 None
.
I'm looking for advice on whether using clone() is the right way, or if there is a better way.
您可以只使用像这样的引用使其工作:
let engine_name = match &config.engine_name {
Some(ref name) => name,
None => &host_name,
};
或者,像上面一样,您可以使用 unwrap_or()
(结合 as_ref()
):
let engine_name = config.engine_name.as_ref().unwrap_or(&host_name);
然而,JSON Value::String
变体需要一个拥有的字符串,所以不在这里克隆并不是真正的优化——json!
宏无论如何都会克隆它。
我是 Rust 新手。
我创建了一个结构来保存系统信息。
pub struct systemConfig {
pub admin_address: String,
pub engine_name: Option<String>,
pub group_name: Option<String>
}
我想将此结构传递给 make_msg 函数以创建一个 json 正文并将其作为请求发送到另一台服务器。
fn make_msg(config: systemConfig) -> String{
let (host_name, cpus) = get_system_info();
let engine_name = match config.engine_name {
Some(name) => name,
None => host_name.clone(),
};
let group_name = match config.group_name {
Some(name) => name,
None => String::from("")
};
let msg = json!({
"engineName": engine_name,
"groupName": group_name,
"hostName": host_name,
});
msg.to_string()
}
fn get_system_info() -> (String, usize){
use sysinfo::{ System, SystemExt };
// monitoring info
let mut my_system = System::new_all();
my_system.refresh_all();
// hostname
let hostname = get_hostname(&my_system);
// logical cpu count
let cpus = get_logical_cpus(&my_system);
(hostname, cpus)
}
我有两个问题。
- engine_name和group_name是从process参数中得到的值。 type 被定义为 Option 的原因是它的值不是必需的。如果未输入引擎名称,则填写主机名。如果未输入组名,则将其作为“”(空字符串)发送。 我使用了 match 语法,但是有没有更合适的语法呢? (如果让 Some/None, 更简洁直观)
None => host_name.clone()
, 如果此处不执行clone(),则会出现借用问题。我正在寻找有关使用 clone() 是否正确的方法,或者是否有更好的方法的建议。
我添加测试代码
//cargo.toml
[dependencies]
sysinfo = "0.23.12"
serde_json = { version = "1.0", features = ["arbitrary_precision"] }
use sysinfo::{System, SystemExt};
use serde_json::json;
struct systemConfig {
pub admin_address: String,
pub engine_name: Option<String>,
pub group_name: Option<String>
}
fn main() {
let config = systemConfig {
admin_address: String::from("127.0.0.1:8080"),
engine_name: Some(String::from("hello")),
group_name: Some(String::from("world"))
};
let msg = make_msg(config);
println!("msg: {}", msg);
}
fn make_msg(config: systemConfig) -> String{
let host_name = get_system_info();
let engine_name = match config.engine_name {
Some(name) => name,
None => host_name.clone(),
};
let group_name = match config.group_name {
Some(name) => name,
None => String::from("")
};
let msg = json!({
"engineName": engine_name,
"groupName": group_name,
"hostName": host_name,
});
msg.to_string()
}
fn get_system_info() -> String {
use sysinfo::{ System, SystemExt };
// monitoring info
let mut my_system = System::new_all();
my_system.refresh_all();
// hostname
let hostname = get_hostname(&my_system);
hostname
}
pub fn get_hostname(s: &System) -> String {
s.host_name().unwrap()
}
两个问题,两个答案:
- 展开或替换
Option
的情况很常见,它有自己的功能:Option::unwrap_or
:
let engine_name = config.engine_name.unwrap_or(host_name.clone());
let group_name = config.group_name.unwrap_or(String::from(""));
- 克隆才是正道。在某些情况下,
engineName
和hostName
将包含相同的字符串,因此在任何时候都需要.clone()
。
I used the match syntax, but is there a more appropriate syntax? (if let Some/None,, more concise and intuitive)
Option
有一些您可以使用的实用程序。在 engine_name
的情况下,unwrap_or_else()
比你的 match
:
let engine_name = config.engine_name
.unwrap_or_else(|| host_name.clone());
对于 group_name
你可以使用 unwrap_or_default()
因为 Default
在 String
returns 上实现了一个空字符串:
let group_name = config.group_name.unwrap_or_default();
请注意,在这种情况下,这两个选项都优于 unwrap_or()
,因为除非需要,否则它们不需要构建替代值。例如,在 engine_name
的情况下,这不会克隆 host_name
除非 config.engine_name
是 None
.
I'm looking for advice on whether using clone() is the right way, or if there is a better way.
您可以只使用像这样的引用使其工作:
let engine_name = match &config.engine_name {
Some(ref name) => name,
None => &host_name,
};
或者,像上面一样,您可以使用 unwrap_or()
(结合 as_ref()
):
let engine_name = config.engine_name.as_ref().unwrap_or(&host_name);
然而,JSON Value::String
变体需要一个拥有的字符串,所以不在这里克隆并不是真正的优化——json!
宏无论如何都会克隆它。