#thread #sharing #resources #cross-thread #value #move #semantics

sinner

为 Rust 实现易用的跨线程资源共享!

3 个版本

0.1.2 2021 年 12 月 19 日
0.1.1 2021 年 12 月 17 日
0.1.0 2021 年 12 月 17 日

#6 in #semantics

MIT 许可证

24KB
156 行代码(不包括注释)

Rust 罪人

Crates.io

内部可变!


嗨,友好的 Rust 开发者!你是否有过这样的经历,一个值就在你需要的时刻突然消失了?你的线程函数需要移动语义,但你没有时间去做这件事?

别担心,只需在它上面撒一点 sin 就行了,然后就可以结束了!

sinner = "0.1"

示例

线程

线程和内部可变性?没问题,老兄!

之前(YIKES!) 之后(GLORIOUS!)

use std::thread::{spawn, sleep};


struct Stuff {
    pub content: String,
}

impl Stuff {
    fn bang(&self) {
        println!("bang! {}", self.content);
    }
}

fn main() {
    let mut x = Stuff { content: "old".to_string() };
    let t = spawn({
        move || {
            sleep(std::time::Duration::from_secs(1));
            x.content = "new".to_string();
            x.bang();
        }
    });
    x.bang();
    t.join().unwrap();
    x.bang();
}
use sinner::Sin;  // <--
use std::thread::{spawn, sleep};

#[derive(Debug, Clone)]
struct Stuff {
    pub content: String,
}

impl Stuff {
    fn bang(&self) {
        println!("bang! {}", self.content);
    }
}

fn main() {
    let mut x = Sin::new(Stuff { content: "old".to_string() });  // <--
    let t = spawn({
        move || {
            sleep(std::time::Duration::from_secs(1));
            x.content = "new".to_string();
            x.bang();
        }
    });
    x.bang();
    t.join().unwrap();
    x.bang();
}
error[E0382]: borrow of moved value: `x`
   --> src/main.rs:144:5
    |
136 |     let mut x = Stuff { content: "old".to_string() };
    |         ----- move occurs because `x` has type `Stuff`
137 |     let t = spawn({
138 |         move || {
    |         ------- value moved into closure here
...
141 |             x.bang();
    |             - variable moved due to use in closure
...
144 |     x.bang();
    |     ^^^^^^^^ value borrowed here after move

For more information about this error, try `rustc --explain E0382`.
error: could not compile `sinner` due to previous error
    Finished dev [unoptimized + debuginfo] target(s) in 0.37s
     Running `target/debug/sinner`
bang! old
bang! n̴e̷w̸
b̸̙̚a̸̘̓n̵̥̔g̵͚̓!̵̤̓ ǹ̴̘e̵̺̾w̴̛̦

双链表

只需一点 sin,你就可以快速实现双链表!

之前(UGH!) 之后(JOLLY!)



struct Item<T> {
    pub prev: Option<Self>,
    pub next: Option<Self>,
    pub value: T
}

struct List<T> {
    pub head: Option<Item<T>>,
    pub tail: Option<Item<T>>,
}

impl Default for List<u32> {
    fn default() -> Self {
        List {
            head: None,
            tail: None,
        }
    }
}

impl <T> List<T> where T: Clone {
    pub fn append(&mut self, other: T) {
        let mut item = Item {
            prev: None,
            next: None,
            value: other,
        };
        if let Some(ref mut tail) = self.tail {
            tail.next = Some(item);
            item.prev = Some(tail.clone());
            self.tail = Some(item);
        } else {
            self.head = Some(item);
            self.tail = Some(item);
        }
    }
}

fn main () {
    let mut list = List::default();
    list.append(1);
    list.append(2);
    list.append(3);

    let mut ptr = list.head;
    while let Some(item) = ptr {
        println!("{}", item.value);
        ptr = item.next;
    }
}
use sinner::Sin;  // <--

#[derive(Clone)]
struct Item<T> {
    pub prev: Option<Sin<Self>>,  // <--
    pub next: O̷p̷t̵i̴o̷n̵≮S̶i̴n̶<Self>>,  // <--
    pub value: T
}

struct List<T> {
    pub head: Option<Sin<Item<T>>>,  // <--
    pub tail: Option<S̶i̸n̵≮I̷t̷e̷m̵<T>>>,  // <--
}

impl Default for List<u32> {
    fn default() -> Self {
        List {
            head: None,
            tail: None,
        }
    }
}

impl <T> List<T> where T: Clone {
    pub fn append(&mut self, other: T) {
        let mut item = S̸i̷n̴:̵:̷n̸e̸w̷(̶I̵t̵e̴m̷ {  // <--
            p̷r̴e̴v̶:̴ ̶N̸o̴n̷e̷,̴
            n̵e̴x̸t̶:̷ ̸N̸o̴n̸e̸,̶
            v̵a̷l̸u̶e̴:̷ ̴o̸t̸h̸e̷r̶,
        });
        if let Some(ref mut tail) = self.tail {
            tail.next = Some(item);
            item.prev = Some(tail.clone());
            self.tail = Some(item);
        } else {
            self.head = Some(item);
            self.tail = Some(item);
        }
    }
}

fn main () {
    let mut list = List::default();
    list.append(1);
    list.append(2);
    list.append(3);

    let mut ptr = list.head;
    while let Some(item) = ptr {
        println!("{}", item.value);
        ptr = item.next;
    }
}
error[E0072]: recursive type `Item` has infinite size
  --> src/main.rs:71:1
   |
71 | struct Item<T> {
   | ^^^^^^^^^^^^^^ recursive type has infinite size
72 |     pub prev: Option<Self>,
   |               ------------ recursive without indirection
73 |     pub next: Option<Self>,
   |               ------------ recursive without indirection
   |
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Item` representable
   |
72 ~     pub prev: Box<Option<Self>>,
73 ~     pub next: Box<Option<Self>>,
   |

   --> src/main.rs:100:35
    |
100 |             item.prev = Some(tail.clone());
    |                                   ^^^^^ method not found in `&mut Item<T>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
            candidate #1: `Clone`

Some errors have detailed explanations: E0072, E0599.
For more information about an error, try `rustc --explain E0072`.
error: could not compile `sinner` due to 2 previous errors
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     R̸u̷n̴n̴i̷n̸g̸ ̸`̶t̸a̸r̷g̵e̶t̶/̸d̴e̵b̴u̷g̶/ç̴̠͌̚u̵̦̅r̶̓̆͜͜s̶̤̫̊̕e̴͇̼̔ḑ̸̇ ̷̩̜̓c̶̯͆ḧ̶̯́͝ì̶̗̣̆l̸̪̓̈́d̵̪̔̀`̷
̴1̴
̸2̷
̶3̶

常见问题解答

任何类型都可以安全地被捕获吗?

嗯,几乎可以!由于内部库结构,类型参数需要实现 Clone

访问底层值是线程安全的吗?

我可以确保你不需要与你的资源self并发。CHILL OUT, OF COURSE YOU CAN. THE TYPE PARAMETER NEEDS TO IMPLEMENT Clone DUE TO INTERNAL LIBRARY STRUCTURES.



RUST SINNER IS A THREAD-SAFE LIBRARY FOR MANAGING MUTABLE VALUES ACROSS THREADS. IT USES INTERNAL LIBRARY STRUCTURES TO ENABLE THREAD-SAFE MUTABLE VALUES. THIS MAKES IT EASIER TO HANDLE COMPLEX THREAD INTERACTIONS IN RUST APPLICATIONS.





没有描述

没有运行时依赖