正如我在一些关于 rust 的视频中看到的那样,它有这样的东西(我使用 c++ 而不是 rust 来展示想法):
template<typename T>
class Synchronized {
public:
Synchronized(T);
Something<T> get();
private:
std::mutex lock_;
};
Run Code Online (Sandbox Code Playgroud)
和这样的用法:
Synchronized<std::string> obj;
auto s = obj.get();
//after that you can work with s as with std::string
//and obj.lock_ in locked state, after s was destroyed
//obj.lock_ will be unlocked
Run Code Online (Sandbox Code Playgroud)
是boost或其他一些C ++通俗图书馆都有这样的模式实现?
我有一个很老的风格enum而不是c ++ 11强类型枚举,我想迭代它的值,如下所示:
enum Enum {
enBEGIN = 0,
eFirst,
eSecond,
//many lines
enEND
};
Enum val;
for (auto i = make_big_enough_integer<Enum>(val); i != enEND; ++i)
;
Run Code Online (Sandbox Code Playgroud)
问题是如何以make_big_enough_integer
最简单的方式实施?
make_big_enough_integer应该返回val转换为整数类型int32_t,uint32_t或者uint64_t可以处理所有值enum.
注意1:转换为强类型枚举不是一个选项,因为它在程序的太多地方使用,并且无法想象可以替换其所有出现的正则表达式.
注意2:我可以在循环之前插入,类似这样static_cast(sizeof(Enum) <= sizeof(int), "error");
或者只是使用uint64_t,但我有兴趣将自动采用写入平台代码.
我有这个C代码:
typedef void (*f_t)(int a);
struct Foo {
f_t f;
};
extern void f(struct Foo *);
Run Code Online (Sandbox Code Playgroud)
bindgen生成以下Rust代码(我删除了不重要的细节):
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct Foo {
pub f: ::std::option::Option<extern "C" fn(a: ::std::os::raw::c_int)>,
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么Option在这里.显然Rust enum和C指针在位级别上是不一样的,所以Rust编译器如何处理这个?
当我调用C f函数并将指针传递给Rust结构时Foo,编译器是否转换Foo_rust为Foo_C然后仅将指针传递Foo_C给f?
我有返回的Vec<PathBuf>函数和接受的函数&[&Path],基本上是这样的:
use std::path::{Path, PathBuf};
fn f(paths: &[&Path]) {
}
fn main() {
let a: Vec<PathBuf> = vec![PathBuf::from("/tmp/a.txt"), PathBuf::from("/tmp/b.txt")];
f(&a[..]);
}
Run Code Online (Sandbox Code Playgroud)
是否可以在没有内存分配的情况下转换Vec<PathBuf>为&[&Path]?
如果不是,我应该如何更改f签名以接受带有Path和的切片PathBuf?
Clippy警告这样的代码:
fn func<T>(data: &Option<T>) {
if let &Some(ref value) = data {}
}
Run Code Online (Sandbox Code Playgroud)
warning: you don't need to add `&` to all patterns
--> src/main.rs:2:5
|
2 | if let &Some(ref value) = data {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(match_ref_pats)] on by default
= help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.210/index.html#match_ref_pats
help: instead of prefixing all patterns with `&`, you can dereference the expression
|
2 | if let Some(ref value) = *data {}
| ^^^^^^^^^^^^^^^ ^^^^^
Run Code Online (Sandbox Code Playgroud)
从编译器的角度来看,这些构造是否相同:
if …Run Code Online (Sandbox Code Playgroud) 玩具示例:
macro_rules! boo {
($T:ident) => {
let x: $T;
};
}
fn main() {
boo!(i32); // WORKS
boo!(Option<i32>); // PROBLEM
}
Run Code Online (Sandbox Code Playgroud)
boo!(Option<i32>); 导致错误:
macro_rules! boo {
($T:ident) => {
let x: $T;
};
}
fn main() {
boo!(i32); // WORKS
boo!(Option<i32>); // PROBLEM
}
Run Code Online (Sandbox Code Playgroud)
我可以解决它:
type Opti32 = Option<i32>;
boo!(Opti32);
Run Code Online (Sandbox Code Playgroud)
但是为宏的每次使用添加别名太无聊了。是否可以使用像这样的宏boo!(Option<i32>);并将困难隐藏在里面macro_rules?
我读了为什么Java 8的Optional不能用在参数中.但是Optional(Int|Long|Double),有什么理由反对使用它们作为输入参数?
正如我所理解的那样,它们不能是空的,而是null(Optional<X>输入参数中的主要参数参数),但可能还有其他的珊瑚礁?我应该使用OptionalInt或Integer使用null而不是null重视?
我包装了C API。为了简化这个问题,我NonNull::dangling改用了。
use std::ptr::NonNull;
struct Foo(NonNull<i32>);
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop: {:?}", self.0);
}
}
struct Moo(NonNull<i32>);
//impl Drop for Moo exists, but not important for question
fn f1() -> Result<Foo, String> {
Ok(Foo(unsafe { NonNull::dangling() }))
}
fn f2() -> Result<Moo, String> {
f1().map(|Foo(x)| Moo(x))//1
}
fn main() {
f2();
}
Run Code Online (Sandbox Code Playgroud)
在第(1)点,我解包/分解Foo。我希望在那之后Foo::drop不应该调用它,但是出于某种原因Foo::drop会打印出来。
销毁(let Struct1 { field1, field2, .. } = struct1;)应该阻止调用,这是我错了Struct1::drop吗?
我的程序解析了足够大的 json 文档(30MB),在 CPU 速度较慢的机器上需要 70 毫秒,我想加快这个过程,我发现 27% 的解析发生在我的foo_document_type_deserialize.有没有办法在String这里跳过分配:let s = String::deserialize(deserializer)?;?
我完全确定表示枚举值的字符串不包含特殊的 json 字符,例如\b \f \n \r \t \" \\,因此使用未转义的字符串应该是安全的。
use serde::{Deserialize, Deserializer};
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FooDocument {
// other fields...
#[serde(rename = "type")]
#[serde(deserialize_with = "foo_document_type_deserialize")]
doc_type: FooDocumentType,
}
fn foo_document_type_deserialize<'de, D>(deserializer: D) -> Result<FooDocumentType, D::Error>
where
D: Deserializer<'de>,
{
use self::FooDocumentType::*;
let s = String::deserialize(deserializer)?;
match s.as_str() {
"tir lim bom bom" => Ok(Var1), …Run Code Online (Sandbox Code Playgroud) 我想在 a 的二进制表示中找到第一个非零位 u32。leading_zeros/trailing_zeros看起来像我想要的:
let x: u32 = 0b01000;
println!("{}", x.trailing_zeros());
Run Code Online (Sandbox Code Playgroud)
这会按预期和文档中的描述打印3。在大端机器上会发生什么,是3还是其他数字?
文档说
返回二进制表示中尾随零的数量
它与机器二进制表示(因此结果trailing_zeros取决于体系结构)或基数为 2 的数字系统(因此结果始终为3)有关?