我有一个自定义结构,如下所示:
struct MyStruct {
first_field: i32,
second_field: String,
third_field: u16,
}
Run Code Online (Sandbox Code Playgroud)
是否有可能以编程方式获取结构字段的数量(例如,通过方法调用field_count()):
let my_struct = MyStruct::new(10, "second_field", 4);
let field_count = my_struct.field_count(); // Expecting to get 3
Run Code Online (Sandbox Code Playgroud)
对于这个结构:
struct MyStruct2 {
first_field: i32,
}
Run Code Online (Sandbox Code Playgroud)
......以下电话应该返回1:
let my_struct_2 = MyStruct2::new(7);
let field_count = my_struct2.field_count(); // Expecting to get count 1
Run Code Online (Sandbox Code Playgroud)
有没有像这样的API field_count()或者只能通过宏获得它?
如果使用宏可以实现这一点,那么应该如何实现?
我在工作时遇到了这种僵局 Mutex
包含Mutex类型字段的结构如下:
struct MyStruct {
inner_map: Arc<Mutex<HashMap<i32, Vec<i32>>>>,
}
Run Code Online (Sandbox Code Playgroud)
我已经通过互斥锁访问了此内部地图:
impl MyStruct {
fn test_lock(&self, key: &i32) {
let my_option = self.inner_map.lock().unwrap().remove(key);
if let Some(my_vec) = my_option {
for _inner_val in my_vec {
self.inner_map.lock().unwrap();
println!("Passed test_lock1");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这没有死锁,可以正常工作,因为我从中删除了价值HashMap并获得了所有权HashMap
与test_lock非常相似的函数,仅具有区别,而不是my_option在动态if let调用中使用已声明的变量删除值,并且在这种情况下会导致死锁:
impl MyStruct{
// Why this function goes to deadlock since remove gets the ownership of the data?
fn test_lock2(&self, key: &i32) {
if let Some(my_vec) …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建Error实现的枚举to_string().我曾试图derive(Debug)为他们,但似乎还不够.
这是我正在研究的枚举:
#[derive(Debug, Clone)]
pub enum InnerError {
InnerErrorWithDescription(String),
}
#[derive(Debug, Clone)]
pub enum OuterError {
OuterErrorWithDescription(String),
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是:
// result type <T,InnerErrorWithDescription>
result.map_err(|err| { Error::OuterErrorWithDescription(err.to_string())}) // .to_string() is not available
Run Code Online (Sandbox Code Playgroud)
我无法将InnerError枚举类型转换为OuterError.
我应该改变什么来实现它?
我在这里写了一个编写枚举类型及其值的例子:
但是,我仍然必须在匹配情况下指定类型和它的描述,是否有更通用的实现?
我正在检查代码中的Clippy调查结果,发现学究规则needless_pass_by_value可能是假阳性。
它说:
警告:此参数按值传递,但未在函数主体中使用
帮助:考虑参考:
&Arc<Mutex<MyStruct>>
由于克隆Arc只是参考计数,因此移动Arc并不是一个坏主意。在质量和性能方面,发送参考而不是价值真的有什么区别Arc吗?
#![warn(clippy::pedantic)]
use std::sync::{Arc, Mutex};
fn main() {
let my_struct = MyStruct { value: 3 };
let arc = Arc::new(Mutex::new(my_struct));
arc_taker(arc.clone());
}
fn arc_taker(prm: Arc<Mutex<MyStruct>>) {
prm.lock().unwrap().do_something();
}
struct MyStruct {
value: i32,
}
impl MyStruct {
fn do_something(&self) {
println!("self.value: {}", self.value);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望通过条件编译对所有导入进行分组。
我知道该#[cfg(target_os = "windows")]属性组织导入,但它仅适用于一次导入。
如何使用一个条件编译属性导入多个包?
我正在寻找类似的东西:
#[cfg(target_os = "windows")]
{
use windows_lib1;
use windows_lib2;
}
#[cfg(target_os = "linux")]
{
use linux_lib1;
use linux_lib2;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试用 Rust 实现 TCP 客户端。我能够读取来自服务器的数据,但无法发送数据。
这是我正在处理的代码:
extern crate bytes;
extern crate futures;
extern crate tokio_core;
extern crate tokio_io;
use self::bytes::BytesMut;
use self::futures::{Future, Poll, Stream};
use self::tokio_core::net::TcpStream;
use self::tokio_core::reactor::Core;
use self::tokio_io::AsyncRead;
use std::io;
#[derive(Default)]
pub struct TcpClient {}
struct AsWeGetIt<R>(R);
impl<R> Stream for AsWeGetIt<R>
where
R: AsyncRead,
{
type Item = BytesMut;
type Error = io::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
let mut buf = BytesMut::with_capacity(1000);
self.0
.read_buf(&mut buf)
.map(|async| async.map(|_| Some(buf)))
}
}
impl TcpClient {
pub fn …Run Code Online (Sandbox Code Playgroud) 我正在尝试了解如何futures::sync::mpsc::Receiver运作。在下面的示例中,接收方线程休眠两秒,发送方每秒发送一次。
我预计发送方需要因等待而被阻塞,然后在缓冲区释放时发送。
相反,我看到的是一段时间后陷入僵局。增加通道的缓冲区只会延长通道被阻塞的时间。
我应该怎么做才能让发送方在缓冲区可用时发送数据,并在这种情况下向发送方施加一些背压?futures::sync::mpsc::channel有它自己的文档,但我不明白如何正确使用它。
extern crate futures;
extern crate tokio_core;
use std::{thread, time};
use futures::sync::mpsc;
use futures::{Future, Sink, Stream};
use tokio_core::reactor::Core;
#[derive(Debug)]
struct Stats {
pub success: usize,
pub failure: usize,
}
fn main() {
let mut core = Core::new().expect("Failed to create core");
let remote = core.remote();
let (tx, rx) = mpsc::channel(1);
thread::spawn(move || loop {
let tx = tx.clone();
let delay = time::Duration::from_secs(1);
thread::sleep(delay);
let f = ::futures::done::<(), ()>(Ok(()));
remote.spawn(|_| {
f.then(|res| {
println!("Sending");
tx.send(res).wait(); …Run Code Online (Sandbox Code Playgroud) 我的自定义字段JSON是动态的,需要解析为具有HashMap如下字段的结构:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
use std::collections::HashMap;
#[derive(Serialize, Deserialize)]
struct MyStruct {
field1: String,
custom: HashMap<String, String>,
}
fn main() {
let json_string = r#"{"field1":"3","custom":{"custom1":"15000","custom2":"60"}}"#;
let my_struct = serde_json::from_str::<MyStruct>(json_string).unwrap();
println!("{}", serde_json::to_string(&my_struct).unwrap());
}
Run Code Online (Sandbox Code Playgroud)
当我的 json 字符串在自定义字段中有字符串字段时,它可以轻松解析为字符串。
但问题是我的 json 字符串是:
let json_string_wrong = r#"{"field1":"3","custom":{"custom1":15000,"custom2":"60"}}"#; // Need to parse this
Run Code Online (Sandbox Code Playgroud)
如何在 serde 中处理此类铸件?
我有以下功能,包括一些错误恢复逻辑和process::exit(0)最后:
fn gracefully_shutdown() {
// Do some logic for the recover
process::exit(7);
}
Run Code Online (Sandbox Code Playgroud)
我想在错误的情况下调用该函数,但match抱怨incompatible arms.但是当我将它明确地写入匹配臂时,它不会抱怨,如下所示:
fn handle_result(my_result: Result<i32, MyError>) -> i32 {
match my_result {
Ok(val) => val,
//Err(_error) => { process::exit(0); } // Does not complain
Err(_error) => {
gracefully_shutdown();
} // Does complain
}
}
Run Code Online (Sandbox Code Playgroud)
编译器真的难以理解其本身gracefully_shutdown()包含process::exit(0)的内容吗?
我希望我能以这种方式编写代码:
fn handle_result(my_result: Result<i32, MyError>) -> i32 {
match my_result {
Ok(val) => val,
Err(_error) => {
gracefully_shutdown();
}
}
}
Run Code Online (Sandbox Code Playgroud)
任何使这项工作的想法? …
我正在尝试创建自己的模拟框架,但遇到了这个问题。当我尝试向下转换我的Any类型时,它找不到downcast_ref方法:
use std::any::Any;
use std::collections::HashMap;
struct X;
struct Y;
fn main() {
let mut map: HashMap<&'static str, Box<Any + Sync>> = HashMap::new();
map.insert("x", Box::new(X));
map.insert("y", Box::new(Y));
get_x(map);
}
fn get_x(map: HashMap<&'static str, Box<Any + Sync>>) {
let ref any = map["x"];
let res = Any::downcast_ref::<X>(any); // Works
let res = any.downcast_ref::<X>(); // Fails
}
Run Code Online (Sandbox Code Playgroud)
use std::any::Any;
use std::collections::HashMap;
struct X;
struct Y;
fn main() {
let mut map: HashMap<&'static str, Box<Any + Sync>> = HashMap::new(); …Run Code Online (Sandbox Code Playgroud) rust ×10
rust-tokio ×2
casting ×1
clippy ×1
concurrency ×1
future ×1
import ×1
mutex ×1
package ×1
rust-macros ×1
serde ×1
string ×1
struct ×1
tcp ×1
traits ×1