你的代码没有汇编,因为你使用了汇编者认为在运作期间是好的参考资料——即使持有该软件的<代码>Arc可能寿命更长。
But what would happen in the following scenario:
- a
User
holds the last Arc to TcpStream
User
is dropped, but the stream
field is dropped first
?
在退约时,你应当谨慎行事——重新宣布声明令涉及:田地按宣布的顺序放弃。
That being said, there is indeed a recommended way to achieve self references -- it is documented in the Pin
module:
https://doc.rust-lang.org/std/pin/index.html#example- Self-referential-struct
但你在此不需要,因为你不使用你自己的结构,而“搭桥”是阿尔塞在你的法典中发挥的作用。
即便如此,如果你希望通过<代码>unsafe的路线,那么你需要告诉汇编者,不要进行某些检查,因为你“知道你正在做什么”。
这里不安全的情况几乎没有任何好处(见John Kugelman关于安全版本的回答),但是,这里的任何好处都是,因为它避免了制造和安放;销毁了每条连接的2个阿尔塞,这可能会使你节省几十个或几秒。
如果没有其他文件,本文是一份比照你原来的法典的版本,汇编如下:
(但请注意,编辑人员不再证明该守则正确)
use std::io::{BufReader, BufWriter};
use std::net::TcpStream;
use std::sync::Arc;
struct User {
reader: BufReader<& static TcpStream>,
writer: BufWriter<& static TcpStream>,
// notice the field order is important here:
// `stream` must be dropped after `reader` and `writer` or else they
// would hold invalid references. Dropping is done in the same order as declaration.
stream: Arc<TcpStream>,
}
fn accept_socket(users: &mut Vec<User>, stream: Arc<TcpStream>) {
let stream_ref = unsafe { &*Arc::as_ptr(&stream) };
let user = User {
reader: BufReader::new(stream_ref),
writer: BufWriter::new(stream_ref),
stream,
};
users.push(user);
}
fn main() {
let stream = Arc::new(TcpStream::connect("google.com:80").unwrap());
let mut users = Vec::with_capacity(16); // giving a big enough capacity may squeeze a little bit more performance -- avoids reallocations
accept_socket(&mut users, stream);
}