相关疑难解决方法(0)

Rust的`String`和`str`之间有什么区别?

为什么Rust有StringstrString和之间有什么区别str?什么时候使用String而不是str反之亦然?其中一个被弃用了吗?

string rust

341
推荐指数
13
解决办法
4万
查看次数

有没有办法返回对函数中创建的变量的引用?

我想编写一个程序,分两步编写一个文件.在程序运行之前,该文件可能不存在.文件名是固定的.

问题是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)

reference lifetime rust

31
推荐指数
4
解决办法
1万
查看次数

如何在编译时创建静态字符串

我想创建一个&'static str由重复的字符序列组成的长片,例如abcabcabc...

在Rust中有没有办法通过表达式来实现这一点,例如long_str = 1000 * "abc"在Python中,或者我是否必须在Python中生成它并将其复制/粘贴到Rust代码中?

rust

23
推荐指数
3
解决办法
5366
查看次数

在Rust中返回新字符串的正确方法

我只花了一个星期阅读Rust Book,现在我正在开发我的第一个程序,它将文件路径返回到系统壁纸:

pub fn get_wallpaper() -> &str {
    let output = Command::new("gsettings");
    // irrelevant code
    if let Ok(message) = String::from_utf8(output.stdout) {
        return message;
    } else {
        return "";
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到错误expected lifetime parameter on &str,我知道Rust想要一个输入&str,它将作为输出返回,因为&str我在函数内部创建的任何内容都将在函数结束后立即清理.

我知道我可以通过返回一个String而不是一个来回避这个问题&str,并且对类似问题的许多答案已经说了很多.但我似乎也可以这样做:

fn main() {
    println!("message: {}", hello_string(""));
}

fn hello_string(x: &str) -> &str {
    return "hello world";
}
Run Code Online (Sandbox Code Playgroud)

得到&str我的功能.有人可以向我解释为什么这很糟糕,为什么我不应该这样做?或者也许它在某些情况下并不坏并且没问题?

rust

18
推荐指数
1
解决办法
7358
查看次数

从String中删除单个尾随换行而不进行克隆

我写了一个函数来提示输入并返回结果.在此版本中,返回的字符串包含用户的尾随换行符.我想将该换行符(以及该换行符)删除后返回输入:

fn read_with_prompt(prompt: &str) -> io::Result<String> {
    let stdout = io::stdout();
    let reader = io::stdin();
    let mut input = String::new();
    print!("{}", prompt);
    stdout.lock().flush().unwrap();
    reader.read_line(&mut input)?;

    // TODO: Remove trailing newline if present
    Ok(input)
}
Run Code Online (Sandbox Code Playgroud)

仅删除单个尾随换行符的原因是此函数还将用于提示输入密码(适当使用termios以停止回显),如果某人的密码具有尾随空格,则应保留该空格.

在关于如何在字符串末尾实际删除单个换行符之后,我最终使用了trim_right_matches.然而,返回一个&str.我试图用它Cow来处理这个但是错误仍然说input变量不够长.

fn read_with_prompt<'a>(prompt: &str) -> io::Result<Cow<'a, str>> {
    let stdout = io::stdout();
    let reader = io::stdin();
    let mut input = String::new();
    print!("{}", prompt);
    stdout.lock().flush().unwrap();
    reader.read_line(&mut input)?;

    let mut trimmed = false;
    Ok(Cow::Borrowed(input.trim_right_matches(|c| {
        if !trimmed …
Run Code Online (Sandbox Code Playgroud)

string rust

12
推荐指数
4
解决办法
1万
查看次数

有没有办法为 &amp;str 实现 Into&lt;&amp;str&gt; 或 From&lt;T&gt; ?

正在用 Rust 编写一些代码,尝试使用(否则相当不错的) crate 来定义 CLI clap,但遇到了一个相当关键的问题。App接受 an的方法Into<&'help str>,我一直无法找到实现此特征的方法。

事实上,据我了解,这是绝对无法实现的:

struct JustWorkDamnIt {
    string: String
}

impl From<JustWorkDamnIt> for &str {
    fn from(arg: JustWorkDamnIt) -> Self {
        return arg.string.as_str()
    }
}
Run Code Online (Sandbox Code Playgroud)

...产生:

error[E0515]: cannot return value referencing local data `arg.string`
  --> src/cmd/interactive.rs:25:16
   |
25 |         return arg.string.as_str()
   |                ----------^^^^^^^^^
   |                |
   |                returns a value referencing data owned by the current function
   |                `arg.string` is borrowed here
Run Code Online (Sandbox Code Playgroud)

然而有趣的是,返回一个文字编译得很好(我认为这就是为什么clap不介意使用这个特性)。大概这是因为文字被编译到内存的某个静态区域,因此不属于该函数:

error[E0515]: cannot return value referencing …
Run Code Online (Sandbox Code Playgroud)

rust

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

为什么变量的寿命不够长?

考虑这个应该返回给定文件扩展名的函数Path.

pub fn get_extension<'a>(path: &'a Path) -> Option<&'a str> {
    let path_str = path.as_str().unwrap();
    let ext_pos = regex!(".[a-z0-9]+$").find(path_str);

    match ext_pos {
        Some((start, _)) => {
            return Some(path_str.as_slice().slice_from(start))
        },
        None => return None
    }
}
Run Code Online (Sandbox Code Playgroud)

错误消息如下:

`path_str` does not live long enough
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

错误信息很清楚,很遗憾我无法自己解决这个问题.我在理论上理解它,但对我来说还有一些模糊的东西.

据我所知,编译器想告诉我,path_str活动时间不够长,因为返回值标记为生命周期'a.

但这就是它停止的地方:

  • 据我所知,对path(输入参数)的引用应该与strOption(包含在输出参数中)的引用完全一样长

  • 因为我们回来了,Some(path_str.as_slice().slice_from(start))我认为在实践中,这意味着只path_str需要生活path.

我不明白的是到底为什么path_str不活足够长的时间,我怎么能解决这个问题?是什么让它很快死去?

UPDATE

正如在评论中指出的那样以及IRC中删除superflous as_slice()使代码编译.有谁知道那是为什么?还有人指出存在一种直接获得扩展的方法.但是,我实际上更感兴趣的是学习问题背后的故事.

lifetime object-lifetime rust

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

我如何制作格式!从条件表达式返回 &amp;str?

我遇到了这个问题format!,据我所知,在一个没有锚定到任何东西的模式中创建一个临时值。

let x = 42;
let category = match x {
    0...9 => "Between 0 and 9",
    number @ 10 => format!("It's a {}!", number).as_str(),
    _ if x < 0 => "Negative",
    _ => "Something else",
};

println!("{}", category);
Run Code Online (Sandbox Code Playgroud)

在这段代码中, 的类型category是 a &str,它通过返回一个像 的文字来满足"Between 0 and 9"。如果我想使用 将匹配的值格式化为切片as_str(),则会出现错误:

let x = 42;
let category = match x {
    0...9 => "Between 0 and 9",
    number @ 10 => format!("It's a {}!", …
Run Code Online (Sandbox Code Playgroud)

string scope temporary lifetime rust

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

什么"`str`没有在编译时知道的常量大小"是什么意思,什么是最简单的修复方法?

我正在尝试操作从函数参数派生的字符串,然后返回该操作的结果:

fn main() {
    let a: [u8; 3] = [0, 1, 2]; 
    for i in a.iter() {
        println!("{}", choose("abc", *i));
    }
}

fn choose(s: &str, pad: u8) -> String {
    let c = match pad {
        0 => ["000000000000000", s].join("")[s.len()..],
        1 => [s, "000000000000000"].join("")[..16],
        _ => ["00", s, "0000000000000"].join("")[..16],
    };
    c.to_string()
}
Run Code Online (Sandbox Code Playgroud)

在构建时,我收到此错误:

error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> src\main.rs:9:9
  |
9 |     let c = match pad {
  |         ^ `str` does not have a …
Run Code Online (Sandbox Code Playgroud)

string pointers rust

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

借用的值在循环中存活的时间不够长

我正在尝试解析文件并Vec<Vec<&str>>从函数返回。但在推送到向量时,我在文件读取循环内遇到借用值错误。

use std::io::{self, BufReader, prelude::*};
use std::fs::File;

fn read() -> Vec<Vec<&'static str>> {
 let file = File::open("~/test").expect("failed to read file");
 let reader = BufReader::new(file);
 let mut main_vector: Vec<Vec<&str>> = Vec::new();
    for line in reader.lines() {
        match line {
            Ok(v) => {
                let mut sub_vector: Vec<&str> = Vec::new();
                for element in v.split_whitespace().collect::<Vec<&str>>() {
                    sub_vector.push(element);
                }
                main_vector.push(sub_vector);
            },
            Err(e) => panic!("failed to parse: {:?}", e),
        }
    }
    //return main_vector;
}
Run Code Online (Sandbox Code Playgroud)

这是编译器错误:

error[E0597]: `v` does not live long enough
  --> src/main.rs:67:32 …
Run Code Online (Sandbox Code Playgroud)

reference lifetime rust borrowing

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