不方便访问的话直接贴出来:
fn main() {
let mut buf = Buffer::new(vec![1,2,3, 4, 5,6]);
// let b1 = buf.read_bytes();
let b1 = &buf.read_bytes().to_owned();
let b2 = buf.read_bytes();
print(b1,b2)
}
fn print(b1 :&[u8], b2: &[u8]) {
println!("{:#?} {:#?}", b1, b2)
}
struct Buffer {
buf: Vec<u8>,
pos: usize,
}
impl Buffer {
fn new(b: Vec<u8>) -> Buffer {
Buffer {
buf: b,
pos: 0,
}
}
fn read_bytes(&mut self) -> &[u8] {
self.pos += 3;
&self.buf[self.pos-3..self.pos]
}
}
b1
变量不能如注释所写,会报mut二次借用,只能赋予所有权后引用传给print()
。
这个错是因为read_bytes()
使用了可变引用,但其实返回的buf可以是不可变借用的,就不知该如何实现这个功能。
1
共 14 条评论, 1 页
评论区
写评论&mut self
本身调用完就结束了啊,不会一直存在,当然返回的新引用另算。@xiaopengli89和@laizy的代码我疑惑了很久,从可变引用中弄出不可变引用且存在多个居然不会报错,后来想明白了,这是因为buffer里存的是数组的不可变引用而不是数组本身,而不可变引用是Copy的,对于
&mut self
的self.buf
直接就得到了一个不可变引用,而不需要间接经过&mut self
。不知道我这么理解对吗?
--
👇
linuxwyn: 老哥,你这个简单清晰,。但我有一点不明白的就是,为什么带生命周期的Buffer结构体在一个作用域内可以有两个可变引用呢,read_bytes函数的签名也还是&mut self啊?麻烦老哥指点一二
--
👇
xiaopengli89: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7a55943515bfb0268d5011d9fedb0150
data是数据,b1和b2都是对data的immutable借用,lifetime要明确他们的关系;而buf是一个游标,它是mutable的
老哥,你这个简单清晰,。但我有一点不明白的就是,为什么带生命周期的Buffer结构体在一个作用域内可以有两个可变引用呢,read_bytes函数的签名也还是&mut self啊?麻烦老哥指点一二
--
👇
xiaopengli89: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7a55943515bfb0268d5011d9fedb0150
data是数据,b1和b2都是对data的immutable借用,lifetime要明确他们的关系;而buf是一个游标,它是mutable的
不需要unsafe的写法, https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b1be3e206cdf64e482c083648478c9ae
之前知乎上写了篇类似的文章供参考:https://zhuanlan.zhihu.com/p/104742696
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7a55943515bfb0268d5011d9fedb0150
data是数据,b1和b2都是对data的immutable借用,lifetime要明确他们的关系;而buf是一个游标,它是mutable的
直接unsafe
感谢。
--
👇
whfuyn: 另外这里报多次可变借用的原因是
read_bytes
返回的不可变引用是从可变引用中拿出来的,这样的引用相当于一个不可以通过它修改的可变引用,同时拥有两者的缺点又失去了各自的优点。另外这里报多次可变借用的原因是
read_bytes
返回的不可变引用是从可变引用中拿出来的,这样的引用相当于一个不可以通过它修改的可变引用,同时拥有两者的缺点又失去了各自的优点。用Cell,这样:
嗯 我去瞅瞅。
--
👇
Neutron3529: 另有一种方法大概是把pos改成“内部可变”的形式,比如Box,然后在保证Box不变的同时可以改Box里面的值,从而只需要&self而非&mut self
你或许可以看看slice关于windows或者chunks这两个函数的实现
虽不知有没有用但我只会这么多了……
好的 感谢。
--
👇
gwy15: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=42935974e83d10f8ab1a76af8496f88a
用迭代器更方便一点,分离数据和操作(算法)
另有一种方法大概是把pos改成“内部可变”的形式,比如Box,然后在保证Box不变的同时可以改Box里面的值,从而只需要&self而非&mut self
你或许可以看看slice关于windows或者chunks这两个函数的实现
虽不知有没有用但我只会这么多了……
我并不会写Struct
只好这样改了
可以用Cell吧
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=42935974e83d10f8ab1a76af8496f88a
用迭代器更方便一点,分离数据和操作(算法)