如何避免结构方法中的双重借用错误
How to avoid a double borrow error in struct method
我是 Rust 的新手,我正在尝试找出如何修复下面代码段中的 Trader.gateway_client
方法。它是由可变的双重借用引起的。修复代码的正确方法是什么(之前没有克隆 self.gateway
字符串)。
use std::collections::{HashMap};
pub struct GatewayClient {
gateway: String,
strategy: String,
}
pub struct Trader {
gateway_clients: HashMap<String, GatewayClient>,
strategy: String,
}
impl GatewayClient {
pub fn new(gateway: &str, strategy: &str) -> Self {
GatewayClient {
gateway: String::from(gateway),
strategy: String::from(strategy),
}
}
}
impl Trader {
pub fn new(strategy: &str) -> Self {
Trader {
gateway_clients: HashMap::default(),
strategy: String::from(strategy),
}
}
pub fn gateway_client(&mut self, gateway: &str) -> &mut GatewayClient {
self.gateway_clients.entry(String::from(gateway)).or_insert_with(|| {
GatewayClient::new(gateway, &self.strategy)
})
}
}
编译器抛出的错误是
63 | pub fn gateway_client(&mut self, gateway: &str) -> &mut GatewayClient {
| - let's call the lifetime of this reference `'1`
64 | self.gateway_clients.entry(String::from(gateway)).or_insert_with(|| {
| -------------------- ^^ immutable borrow occurs here
| |
| _________mutable borrow occurs here
| |
65 | | GatewayClient::new(gateway, &self.strategy)
| | ------------- second borrow occurs due to use of `self` in closure
66 | | })
| |__________- returning this value requires that `self.gateway_clients` is borrowed for `'1`
您只是不需要使用允许通过闭包执行自定义代码的 .or_insert_with
。您只想插入一个值,并且有一个方法 .or_insert
接受一个值。
pub fn gateway_client(&mut self, gateway: &str) -> &mut GatewayClient {
self.gateway_clients
.entry(gateway.to_string())
.or_insert(GatewayClient::new(gateway, &self.strategy))
}
此外,如果您想要摆脱使用 String::from(...)
创建的一百万个新字符串,您可以查看 std::borrow::Cow
类型
解决借用冲突的一种方法是通过从 self
外部提取您需要的内容来消除回调中的第二个显式借用。
pub fn gateway_client(&mut self, gateway: &str) -> &mut GatewayClient {
let strategy = &self.strategy;
self.gateway_clients
.entry(gateway.into())
.or_insert_with(|| GatewayClient::new(gateway, strategy))
}
这看起来可能是回调中对 self
的第二次借用,但编译器接受了这一点。
.or_insert_with()
对比 .or_insert()
建议使用 .or_insert()
进行修复,但您选择使用 .or_insert_with()
是正确的。
在这种情况下,使用 .or_insert_with()
优于 .or_insert()
的优点是只有在条目不存在时才会执行回调。如果使用.or_insert()
,无论条目是否存在,每次都会调用GatewayClient::new()
。
我是 Rust 的新手,我正在尝试找出如何修复下面代码段中的 Trader.gateway_client
方法。它是由可变的双重借用引起的。修复代码的正确方法是什么(之前没有克隆 self.gateway
字符串)。
use std::collections::{HashMap};
pub struct GatewayClient {
gateway: String,
strategy: String,
}
pub struct Trader {
gateway_clients: HashMap<String, GatewayClient>,
strategy: String,
}
impl GatewayClient {
pub fn new(gateway: &str, strategy: &str) -> Self {
GatewayClient {
gateway: String::from(gateway),
strategy: String::from(strategy),
}
}
}
impl Trader {
pub fn new(strategy: &str) -> Self {
Trader {
gateway_clients: HashMap::default(),
strategy: String::from(strategy),
}
}
pub fn gateway_client(&mut self, gateway: &str) -> &mut GatewayClient {
self.gateway_clients.entry(String::from(gateway)).or_insert_with(|| {
GatewayClient::new(gateway, &self.strategy)
})
}
}
编译器抛出的错误是
63 | pub fn gateway_client(&mut self, gateway: &str) -> &mut GatewayClient {
| - let's call the lifetime of this reference `'1`
64 | self.gateway_clients.entry(String::from(gateway)).or_insert_with(|| {
| -------------------- ^^ immutable borrow occurs here
| |
| _________mutable borrow occurs here
| |
65 | | GatewayClient::new(gateway, &self.strategy)
| | ------------- second borrow occurs due to use of `self` in closure
66 | | })
| |__________- returning this value requires that `self.gateway_clients` is borrowed for `'1`
您只是不需要使用允许通过闭包执行自定义代码的 .or_insert_with
。您只想插入一个值,并且有一个方法 .or_insert
接受一个值。
pub fn gateway_client(&mut self, gateway: &str) -> &mut GatewayClient {
self.gateway_clients
.entry(gateway.to_string())
.or_insert(GatewayClient::new(gateway, &self.strategy))
}
此外,如果您想要摆脱使用 String::from(...)
创建的一百万个新字符串,您可以查看 std::borrow::Cow
类型
解决借用冲突的一种方法是通过从 self
外部提取您需要的内容来消除回调中的第二个显式借用。
pub fn gateway_client(&mut self, gateway: &str) -> &mut GatewayClient {
let strategy = &self.strategy;
self.gateway_clients
.entry(gateway.into())
.or_insert_with(|| GatewayClient::new(gateway, strategy))
}
这看起来可能是回调中对 self
的第二次借用,但编译器接受了这一点。
.or_insert_with()
对比 .or_insert()
建议使用 .or_insert()
进行修复,但您选择使用 .or_insert_with()
是正确的。
在这种情况下,使用 .or_insert_with()
优于 .or_insert()
的优点是只有在条目不存在时才会执行回调。如果使用.or_insert()
,无论条目是否存在,每次都会调用GatewayClient::new()
。