我想编写一个程序,分两步编写一个文件.在程序运行之前,该文件可能不存在.文件名是固定的.
问题是OpenOptions.new().write()
可能会失败.在这种情况下,我想调用自定义函数trycreate()
.我们的想法是创建文件而不是打开它并返回一个句柄.由于文件名是固定的,trycreate()
没有参数,我不能设置返回值的生命周期.
我该如何解决这个问题?
use std::io::Write;
use std::fs::OpenOptions;
use std::path::Path;
fn trycreate() -> &OpenOptions {
let f = OpenOptions::new().write(true).open("foo.txt");
let mut f = match f {
Ok(file) => file,
Err(_) => panic!("ERR"),
};
f
}
fn main() {
{
let f = OpenOptions::new().write(true).open(b"foo.txt");
let mut f = match f {
Ok(file) => file,
Err(_) => trycreate("foo.txt"),
};
let buf = b"test1\n";
let _ret = f.write(buf).unwrap();
}
println!("50%");
{
let f = OpenOptions::new().append(true).open("foo.txt");
let mut f …
Run Code Online (Sandbox Code Playgroud) 我有一个内部可变性的结构.
use std::cell::RefCell;
struct MutableInterior {
hide_me: i32,
vec: Vec<i32>,
}
struct Foo {
//although not used in this particular snippet,
//the motivating problem uses interior mutability
//via RefCell.
interior: RefCell<MutableInterior>,
}
impl Foo {
pub fn get_items(&self) -> &Vec<i32> {
&self.interior.borrow().vec
}
}
fn main() {
let f = Foo {
interior: RefCell::new(MutableInterior {
vec: Vec::new(),
hide_me: 2,
}),
};
let borrowed_f = &f;
let items = borrowed_f.get_items();
}
Run Code Online (Sandbox Code Playgroud)
产生错误:
error[E0597]: borrowed value does not live long enough
--> …
Run Code Online (Sandbox Code Playgroud) encapsulation contravariance mutability rust interior-mutability
我有一个RefCell<HashMap>
并想借用表,找到一个键,并返回对结果的引用:
use std::cell::RefCell;
use std::collections::HashMap;
struct Frame {
map: RefCell<HashMap<String, String>>,
}
impl Frame {
fn new() -> Frame {
Frame {
map: RefCell::new(HashMap::new()),
}
}
fn lookup<'a>(&'a self, k: &String) -> Option<&'a String> {
self.map.borrow().get(k)
}
}
fn main() {
let f = Frame::new();
println!("{}", f.lookup(&"hello".to_string()).expect("blargh!"));
}
Run Code Online (Sandbox Code Playgroud)
(游乐场)
如果我删除RefCell
然后一切正常:
struct Frame {
map: HashMap<String, String>,
}
impl Frame {
fn lookup<'a>(&'a self, k: &String) -> Option<&'a String> {
self.map.get(k)
}
}
Run Code Online (Sandbox Code Playgroud)
在不复制哈希表中的字符串的情况下编写查找函数的正确方法是什么?
我正在尝试从以下位置返回移动的值Rc
:
if let Some(last_elem) = self.tail.take() {
let last = Rc::clone(&last_elem);
let tmp_node = last.borrow();
let tmp = tmp_node.deref();
return Some(*tmp);
}
Run Code Online (Sandbox Code Playgroud)
在哪里:
self.tail
有类型Option<Rc<RefCell<Node<T>>>>
;tmp_node
有类型Ref<Node<T>>
;和Option<Node<T>>
。然而编译器抱怨说,“无法移出*tmp
共享引用后面的内容”。
我怎样才能解决这个问题?
有时我有一个struct
包含在a 中的值RefCell
,我想借用该值,但我不想让访问器函数的签名依赖于内部实现.为了使它工作,我需要返回引用Ref<T>
而不是a &T
.
例如,如果这是我的结构:
use std::cell::RefCell;
pub struct Outer<T> {
inner: RefCell<T>,
}
Run Code Online (Sandbox Code Playgroud)
我可以写一个这样的访问器:
use std::cell::Ref;
impl<T> Outer<T> {
fn get_inner_ref(&self) -> Ref<T> {
self.inner.borrow()
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用.我可以像这样使用它:
fn main() {
let outer = Outer { inner: RefCell::new(String::from("hi")) };
let inner: &str = &outer.get_inner_ref();
println!("inner value = {:?}", inner);
}
Run Code Online (Sandbox Code Playgroud)
但是,这会暴露Ref
为公共API的一部分,这将使以后更改内部更加困难,而不会破坏向后兼容性.
如果我尝试更改签名以返回&T
- &Ref<T>
可以强制执行 - 那么我会遇到终生错误:
impl<T> Outer<T> {
fn get_inner_ref(&self) -> &T {
&self.inner.borrow()
}
}
Run Code Online (Sandbox Code Playgroud)
错误是:
error[E0597]: …
Run Code Online (Sandbox Code Playgroud)