小编ust*_*ion的帖子

Rust如何知道是否在堆栈展开期间运行析构函数?

该文档mem::uninitialized指出了使用该函数危险/不安全的原因:调用drop未初始化的内存是未定义的行为.

因此,我相信这段代码应该是未定义的:

let a: TypeWithDrop = unsafe { mem::uninitialized() };
panic!("=== Testing ==="); // Destructor of `a` will be run (U.B)
Run Code Online (Sandbox Code Playgroud)

但是,我编写了这段代码,它在安全的Rust中运行,并且似乎没有受到未定义的行为的影响:

#![feature(conservative_impl_trait)]

trait T {
    fn disp(&mut self);
}

struct A;
impl T for A {
    fn disp(&mut self) { println!("=== A ==="); }
}
impl Drop for A {
    fn drop(&mut self) { println!("Dropping A"); }
}

struct B;
impl T for B {
    fn disp(&mut self) { println!("=== B ==="); }
}
impl …
Run Code Online (Sandbox Code Playgroud)

destructor stack-unwinding undefined-behavior rust

21
推荐指数
2
解决办法
1891
查看次数

是否有设施可以锁定Rust中的多个互斥锁,同时防止死锁?

std::lock()在Rust中是否有像C++ 这样的工具来防止像这样的代码中的死锁:

type Type0 = Arc<Mutex<u8>>;
type Type1 = Arc<Mutex<u16>>;

fn foo(a: Type0, b: Type1) {
    let a_guard = a.lock().unwrap();
    let b_guard = b.lock().unwrap();
}

fn bar(a: Type0, b: Type1) {
    let b_guard = b.lock().unwrap();
    let a_guard = a.lock().unwrap();
}
Run Code Online (Sandbox Code Playgroud)

如果foo由thread-0和barthread-1 调用,则可能出现死锁.有什么东西,希望变量,因为我可以有超过2,帮助我这个或我自己验证锁定顺序的正确性?

以下文档std::lock:

锁定给定Lockable对象lock1,lock2,...,lockn使用死锁避免算法,以避免死锁.

mutex rust

14
推荐指数
2
解决办法
783
查看次数

在Rust中涉及临时的破坏令

在C++中(如果错误请纠正我),通过常量引用的临时绑定应该比它绑定的表达式更长.我认为在Rust中也是如此,但在两种不同情况下我得到了两种不同的行为.

考虑:

struct A;
impl Drop for A { fn drop(&mut self) { println!("Drop A.") } }

struct B(*const A);
impl Drop for B { fn drop(&mut self) { println!("Drop B.") } }

fn main() {
    let _ = B(&A as *const A); // B is destroyed after this expression itself.
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Drop B.
Drop A.
Run Code Online (Sandbox Code Playgroud)

这是你所期望的.但现在如果你这样做:

fn main() {
    let _b = B(&A as *const A); // _b will be dropped when scope exits main()
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Drop …
Run Code Online (Sandbox Code Playgroud)

temporary-objects rust

11
推荐指数
2
解决办法
220
查看次数

适用于Rust的C++ Friend-like构造

在某些情况下,我想利用Rust中的任何替代方法来解决C++的friend关键字.在箱子A中我有以下模块:

mod a0:

pub struct A {
    pub a0: u8,
    a1: SomeType,
}

impl A {
    pub fn fa0(...) { ... }
    fn fa1(...) { ... }
}
Run Code Online (Sandbox Code Playgroud)

模块b0c0需要访问所有公共和私人成员A.代码不能这样做,除非它在mod a0.我只想暴露A,A::a0A::fa0与其他与此箱子接口的箱子,但在这个箱子里我想要访问A(公共和私人)的完整实现.

我通常最终做的事情如下:

mod a0:

pub struct A {
    pub a0: u8,
    inner: Inner
}

pub struct Inner { /* all pub fields */ }

pub fn get_inner<'a>(obj: &'a mut …
Run Code Online (Sandbox Code Playgroud)

encapsulation rust

10
推荐指数
1
解决办法
926
查看次数

我们可以在板条箱之间共享测试用途吗?

我有crate-0,src/lib.rs如下:

#[cfg(test)]
pub mod test_utils {
    pub struct OnlyInTests(pub usize);
    pub fn helper() -> usize { 999 }

    #[test]
    fn test_0() { let _ = OnlyInTests(helper()); }
}
Run Code Online (Sandbox Code Playgroud)

我也有crate-1,我需要在crate-0中定义的测试框架:

extern crate crate_0;

#[cfg(test)]
pub mod test_utils {
    // This will error out - cannot find mod test_utils in crate_0
    use crate_0::test_utils::{OnlyInTests, helper()};

    #[test]
    fn test_1() { let _ = OnlyInTests(helper()); }
}
Run Code Online (Sandbox Code Playgroud)

这里的代码很简单,可以复制粘贴,但实际上我有复杂的测试工具,我想在测试crate-1时使用它.

我无法将测试实用程序分离到不同的包中,因为我会得到循环依赖性错误:test_utils将依赖于crate-0创建内容并crate-0依赖于test_utils测试).我也不想这样做,因为还有更多的板条箱,其测试实用程序我想在依赖板条箱中使用.

unit-testing rust

10
推荐指数
1
解决办法
227
查看次数

如何从其他语言访问Rust

以前当代码库是在C++中时,我有C++包装器文件,它将链接到代码库,我将运行swig(支持C++ 11的版本3)来生成目标语言的接口文件(Python,JavaScript, C#等).然后当然将所有这些文件和库编译成一个共享对象,并从所需的语言中调用它.现在代码库被改为生锈.因此,对于swig工作,我有以下内容:

  1. 主要生锈代码文件编译成rlib.
  2. Rust包装器文件,它调用主代码库但使用no_mangleextern语法FFI并编译成staticlib.
  3. 调用防锈包装器的AC文件,它是它的副本.

现在我swig在C文件上使用,获取目标语言的接口文件,将所有文件(第二步和第三步)和SWIG接口文件组合成一个共享对象,并从目标语言调用.

所以:

  1. 方法好吗?

  2. 我可以获得免费的功能.但是我对如何使成员函数(方法)工作感到困惑.在C++中,成员函数的第一个参数是隐式this指针.所以我可以void*将类或结构的句柄返回给C接口,将其传递给想要存储它的其他人(例如Firefox的jsctypes),然后再将reinterpret_cast它接收到具体/实际类型并调用成员函数在上面.我怎么用Rust做到这一点?

例如,为

pub struct A { id: SomeType, }
impl A {
    pub fn some_funct_0(&mut self) {}
    pub fn some_funct_1(&self) {}
}

impl SomeTrait for A {
    fn some_trait_funct(&mut self) {}
}
Run Code Online (Sandbox Code Playgroud)

那么如何A从目标语言(Python,C等)甚至简单的C接口访问这些成员函数(应该是非托管的,在堆上我猜?)?

swig rust

9
推荐指数
2
解决办法
1835
查看次数

无法使用Rustc-serialize处理JSON中的可选字段

我正在尝试使用rustc_serialize将JSON反序列化为Rust结构.问题是某些JSON具有一些可选字段,即可能存在也可能不存在.遇到第一个缺席字段的那一刻,解码器似乎纾困并且不考虑后续字段,即使它们存在.有办法克服这个问题吗?

这是代码:

extern crate rustc_serialize;

#[derive(Debug)]
struct B {
    some_field_0: Option<u64>,
    some_field_1: Option<String>,
}

impl rustc_serialize::Decodable for B {
    fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
        Ok(B {
            some_field_0: d.read_struct_field("some_field_0", 0, |d| rustc_serialize::Decodable::decode(d)).ok(),
            some_field_1: d.read_struct_field("some_field_1", 0, |d| rustc_serialize::Decodable::decode(d)).ok(),
        })
    }
}

fn main() {
    {
        println!("--------------------------------\n1st run - all field present\n--------------------------------");
        let json_str = "{\"some_field_0\": 1234, \"some_field_1\": \"There\"}".to_string();
        let obj_b: B = rustc_serialize::json::decode(&json_str).unwrap();

        println!("\nJSON: {}\nDecoded: {:?}", json_str, obj_b);
    }

    {
        println!("\n\n--------------------------------\n2nd run - \"some_field_1\" absent\n---------------------------------");
        let json_str = …
Run Code Online (Sandbox Code Playgroud)

json rust json-deserialization

9
推荐指数
1
解决办法
419
查看次数

Rust中的UDP API

1)此处发送的API返回Result<usize>.这是为什么 ?在我看来,UDP发送是全部或全部.返回值似乎表明发送可以成功,但可能不会写入整个数据,这使得我的代码如下:

let mut bytes_written = 0;
while bytes_written < data.len() {
    bytes_written += match udp_socket.send_to(&data[bytes_written..]) {
         Ok(bytes_tx) => bytes_tx,
         Err(_) => break,
    }
}
Run Code Online (Sandbox Code Playgroud)

最近有人告诉我这完全没必要.但我不明白.如果这是真的,为什么回报Result<()>不是,这也是我所期待的?

2) 对于读操作,虽然我明白了.我可以给它一个大小为100字节的缓冲区,但数据报可能只有50个字节长.所以基本上我应该只利用read_buf[..size_read].这里我的问题是如果缓冲区大小为100但数据报大小为150字节会发生什么?将recv_from只填写100个字节并返回Ok(100, some_peer_addr)?如果我重读,它会填写剩下的数据报吗?如果在我第二次读取之前另一个50字节的数据报到达怎么办?我是第二次得到剩余的50个字节,第三次得到50个字节的新数据报还是第二次得到100个字节,还包含新的数据报?或者将是一个错误,我将丢失我的初始读取的第一个数据报,永远无法恢复它?

networking udp rust

9
推荐指数
1
解决办法
550
查看次数

为什么我不能使用函数返回编译时常量作为常量?

let arr0 = [0u8; 15];
let arr1 = [0u8; arr0.len()]; // this fails
Run Code Online (Sandbox Code Playgroud)

我认为编译器应该能够将arr0的长度确定为编译时常量,不是吗?仍然将此标记为错误,表示找到变量而不是常量整数.

  1. 为什么?
  2. Rust中有constexpr(C++)函数吗?

版:

rustc 1.0.0-nightly (ecf8c64e1 2015-03-21) (built 2015-03-22)
Run Code Online (Sandbox Code Playgroud)

rust

8
推荐指数
1
解决办法
1231
查看次数

统一与旧式初始化会产生不同的编译结果

我在用一些琐碎的代码排列时就注意到了这一点:

struct Base0 {};
struct Base1 {};

template<typename... Ts>
struct Derived: Ts... {};

int main() {
    Derived<Base0, Base1> d0 {Base0{}, Base1{}}; // OK
    Derived<Base0, Base1> d1 (Base0{}, Base1{}); // ERROR
}
Run Code Online (Sandbox Code Playgroud)

我认为两者d0d1应导致编译错误,因为我看不出Derived没有任何匹配的构造函数需要构造函数参数如通过和标志d0的编译细。

我可能想念一些明显的东西。使它通过的统一初始化是什么?是聚合初始化还是什么?临时人员传给ctor的情况如何?

在此处使用C ++ 17在线编译器

编辑

根据要求,我提供了喷出的副本粘贴:

main.cpp: In function ‘int main()’:
main.cpp:9:47: error: no matching function for call to ‘Derived::Derived(Base0, Base1)’
     Derived<Base0, Base1> d1 (Base0{}, Base1{}); // ERROR
                                               ^
main.cpp:5:8: note: candidate: constexpr Derived::Derived()
 struct Derived: Ts... {};
        ^~~~~~~
main.cpp:5:8: …
Run Code Online (Sandbox Code Playgroud)

c++ uniform-initialization c++17

7
推荐指数
1
解决办法
104
查看次数