假设我想用 Tokio 同时下载两个网页......
我可以用以下方法来实现tokio::spawn():
async fn v1() {
let t1 = tokio::spawn(reqwest::get("https://example.com"));
let t2 = tokio::spawn(reqwest::get("https://example.org"));
let (r1, r2) = (t1.await.unwrap(), t2.await.unwrap());
println!("example.com = {}", r1.unwrap().status());
println!("example.org = {}", r2.unwrap().status());
}
Run Code Online (Sandbox Code Playgroud)
或者我可以通过以下方式实现tokio::join!():
async fn v2() {
let t1 = reqwest::get("https://example.com");
let t2 = reqwest::get("https://example.org");
let (r1, r2) = tokio::join!(t1, t2);
println!("example.com = {}", r1.unwrap().status());
println!("example.org = {}", r2.unwrap().status());
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,两个请求都是同时发生的。但是,在第二种情况下,两个请求在同一任务中运行,因此在同一线程上运行。
所以,我的问题是:
tokio::join!()超过有优势吗tokio::spawn()?我猜生成一个新任务的开销非常小,但真的是这样吗?
这是一个用 Rust 编写的简单第 n 个素数程序。实施效率低下,但这不是重点。
use std::time::Instant;
fn main() {
let n = 10_000;
let now = Instant::now();
let nth = nth_prime(n);
let elapsed = now.elapsed().as_micros();
println!("prime #{} = {}", n, nth);
println!("elapsed = {} µs", elapsed);
}
fn nth_prime(n: u64) -> u64 {
let mut count = 1;
let mut num = 2;
while count < n {
num += 1;
if is_prime(num) {
count += 1;
}
}
num
}
fn is_prime(num: u64) -> bool {
for i …Run Code Online (Sandbox Code Playgroud) 真正让我相信 Node 强大的演示之一是 Ryan Dahl 在此视频中展示的简单 TCP 聊天服务器:https : //www.youtube.com/watch?v=jo_B4LTHi3I&t=28m23s
演示中的代码如下所示:
const net = require('net');
const server = net.createServer();
const sockets = [];
server.on('connection', (socket) => {
sockets.push(socket);
socket.on('data', (message) => {
for (const current_socket of sockets) {
if (current_socket !== socket) {
current_socket.write(message);
}
}
});
socket.on('end', () => {
const index = sockets.indexOf(socket);
sockets.splice(index, 1);
});
});
server.listen(8000, () => console.log('tcp server listening on port 8000'));
Run Code Online (Sandbox Code Playgroud)
我在 Deno 网站上找到的唯一 TCP 示例是一个回显服务器,如下所示:
const listener = Deno.listen({ port: 8080 …Run Code Online (Sandbox Code Playgroud) 当我编译以下代码片段时:
struct Packet([u8; 4]);
impl Packet {
const fn from(labels: [&[u8; 2]; 2]) -> Packet {
let mut bytes = [0; 4];
bytes[..2].copy_from_slice(labels[0]);
bytes[2..].copy_from_slice(labels[1]);
Packet(bytes)
}
}
const AA: &[u8; 2] = b"AA";
const BB: &[u8; 2] = b"BB";
const CC: &[u8; 2] = b"CC";
const AABB: Packet = Packet::from([AA, BB]);
const AACC: Packet = Packet::from([AA, CC]);
Run Code Online (Sandbox Code Playgroud)
我收到以下编译器错误:
error[E0723]: mutable references in const fn are unstable
--> src/main.rs:7:9
|
7 | bytes[..2].copy_from_slice(labels[0]);
| ^^^^^^^^^^
|
= note: see issue #57563 …Run Code Online (Sandbox Code Playgroud) 考虑这个Config包含结构向量的结构Host:
use serde::Deserialize;
use std::net::IpAddr;
#[derive(Debug, Deserialize)]
struct Config {
name: String,
hosts: Vec<Host>
}
#[derive(Debug, Deserialize)]
struct Host {
addr: IpAddr,
user: String,
}
Run Code Online (Sandbox Code Playgroud)
使用派生实现,可以使用和Deserialize成功反序列化以下 JSON 和 YAML 配置文件:serde_jsonserde_yaml
{
"name": "example",
"hosts": [
{ "addr": "1.1.1.1", "user": "alice" },
{ "addr": "2.2.2.2", "user": "bob" }
]
}
Run Code Online (Sandbox Code Playgroud)
---
name: example
hosts:
- addr: 1.1.1.1
user: alice
- addr: 2.2.2.2
user: bob
Run Code Online (Sandbox Code Playgroud)
但是,我还希望能够Host从字符串反序列化结构。但是,重要的是我还可以从地图中反序列化它,并且理想情况下向量可以由两种格式组成。例如:
{
"name": "example",
"hosts": [
"alice@1.1.1.1", …Run Code Online (Sandbox Code Playgroud) rust ×4
chat ×1
constants ×1
deno ×1
docker ×1
javascript ×1
macos ×1
node.js ×1
rust-tokio ×1
serde ×1
serde-json ×1
tcp ×1