- 主题:rust新手问一下
use tokio::task::yield_now;
use std::rc::Rc;
#[tokio::main]
async fn main() {
tokio::spawn(async {
let rc = Rc::new("hello");
// `rc` is used after `.await`. It must be persisted to
// the task's state.
yield_now().await;
println!("{}", rc);
});
}
这里为什么要求rc可send?
rc是堆栈变量在await切换时不是跟task一块移动的吗?
或者说这个task在切换时它的局部变量如何保持的?
发自「今日水木 on MRX-W29」
--
修改:txgx FROM 42.234.95.*
FROM 42.234.95.*
大概是明白了,rust担心rc被其他人使用,所以用规则一棍子打死。
!send的不能穿越await
就是懒政。
实际上没有问题,rc只有一个owner.
【 在 ilovecpp 的大作中提到: 】
: tokio和你这个rc没有关系。
:
: 你的rc是async的状态(可以简单想像成stack frame)的一部分。只要任何一个状态是!Send,整个async就是!Send。
:
: 然后tokio::spawn:
: pub fn spawn<T>(task: T) ->
: ..................
发自「今日水木 on MRX-W29」
--
FROM 42.234.95.*
再问一个问题, 这个怎么搞 ?
只是想 print vals 长度而已 , 编译不了
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];
for val in vals { // vals moved,
tx.send(val).unwrap();
//println!("Len in vec {:?}", vals.len()); // so invalide here!!
thread::sleep(Duration::from_secs(1));
}
});
for received in rx {
println!("Got: {}", received);
}
}
【 在 ilovecpp 的大作中提到: 】
: 不是!Send不能穿越await,而是!Send的状态跨过await,会使得async fn变成!Send。
: 一个async fn是!Send本身没有任何问题,只是不满足tokio::spawn的要求。
: 就Rc而言,的确理论上可以在不同线程间传递,只要保证不同时访问即可。
: ...................
--
FROM 42.234.95.*
你看错了,tx.send的是,val,需要输出的是vals的长度。
vals被for拿走了。
【 在 z16166 的大作中提到: 】
: 传给tx.send之前先clone到临时变量中,print那个临时变量
: --
发自「今日水木 on MRX-W29」
--
FROM 42.234.95.*
这样子也不行,牵扯到channel, 异至&vals有生命周期问题。
error[E0597]: `vals` does not live long enough
--> src/main.rs:15:20
|
6 | let (tx, rx) = mpsc::channel();
| -- lifetime `'1` appears in the type of `tx`
...
15 | for val in &vals {
| ^^^^^ borrowed value does not live long enough
16 | tx.send(val).unwrap();
| ------------ argument requires that `vals` is borrowed for `'1`
...
20 | });
| - `vals` dropped here while still borrowed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
error: could not compile `test-vec`
就是要在 中间 !!
【 在 leadu 的大作中提到: 】
: 你想要的是不是这个
:
: for val in &vals { // vals moved,
: tx.send(val.clone()).unwrap();
: println!("Len in vec {:?}", vals.len()); // so invalide her
: ..................
发自「今日水木 on MRX-W29」
--
修改:txgx FROM 42.234.93.*
FROM 42.234.93.*
就是要在中间,搞不懂为啥有生命周期问题。
val这个时候是&string, tx.send 为啥不行呢?
应该是发送完了才退出,这时候vals不是一直有效吗?
【 在 leadu 的大作中提到: 】
: 在不少的编程语言中 for val in vals {
: 是只读的,长度的话提前取一下就行
: --
发自「今日水木 on MRX-W29」
--
FROM 42.234.93.*
综合15楼的分析,有一点可以肯定
for v in vals 把vector 清空了!
如果println可以工作的话,那么输出应该是4,3,2,1,0
这太令人窒息了!我只是想看一眼,结果人家流产了!
这到哪里说理去?!
最关键的是let vals = vec![] 用的immutable !!!!
rust 不给一个解释吗?自己都不遵守规则了?
婶可忍,叔不可忍!!!
【 在 z16166 的大作中提到: 】
: 所以打印vals.len()其实没用,一直都是4
:
: 要在for的里面引用vals,就不能让for一开始把vals给move走了,
: 但是不move走的话,只是ref或者clone的话,vals.len()就会不变,就不需要在for的里面打印。
:
: for val in
: ..................
发自「今日水木 on MRX-W29」
--
FROM 42.234.93.*
还是你牛。
不过看函数原型用的是mut self 怎么回事?
【 在 txgx 的大作中提到: 】
: use tokio::task::yield_now;
: use std::rc::Rc;
:
: #\[tokio::main\]
: async fn main() {
: tokio::spawn(async {
: let rc = Rc::new("he
: ..................
发自「今日水木 on MRX-W29」
--
修改:txgx FROM 42.234.93.*
FROM 42.234.93.*
self的ownership发生了转移,所以是mut self。
这个怎么理解,哪本书里面有解释?
【 在 z16166 的大作中提到: 】
: self的ownership发生了转移,所以是mut self。
:
: 可以改用for val in vals.iter()这个,iter()是ref,不是mut ref,这样for循环里面可以继续使用vals。
:
: "Rust 中的集合(Collection)提供三个公共方法
: ..................
发自「今日水木 on MRX-W29」
--
FROM 42.234.93.*