如何在没有目录部分的情况下获取当前程序的名称?

vvv*_*vvv 4 rust

在Bash中,这将是${0##*/}.

use std::env;
use std::path::Path;

fn prog() -> String {
    let prog = env::args().next().unwrap();
    String::from(Path::new(&prog).file_name().unwrap().to_str().unwrap())
}

fn main() {
    println!("{}", prog());
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?(我特别不喜欢那些无数unwrap()的.)

She*_*ter 9

如果你不关心为什么你不能让程序的名称,你可以处理所有的明智组合的潜在错误mapand_then.另外,返回一个Option表示可能的失败:

use std::env;
use std::path::Path;
use std::ffi::OsStr;

fn prog() -> Option<String> {
    env::args().next()
        .as_ref()
        .map(Path::new)
        .and_then(Path::file_name)
        .and_then(OsStr::to_str)
        .map(String::from)
}

fn main() {
    println!("{:?}", prog());
}
Run Code Online (Sandbox Code Playgroud)

如果你想追随delnan的真棒建议使用std::env::current_exe(我刚刚得知!),替换env::args().next()env::current_exe().ok().


如果你想知道为什么你不能得到程序名称(并且知道为什么通常是解决问题的第一步),那么请查看ker的答案.


imb*_*olc 6

只剩下一个Option版本了:)

fn prog() -> Option<String> {
    std::env::current_exe()
        .ok()?
        .file_name()?
        .to_str()?
        .to_owned()
        .into()
}
Run Code Online (Sandbox Code Playgroud)


oli*_*obk 5

您也可以摆脱包装,并仍然正确报告所有错误原因(而不是将它们塞入“失败的事物”中None)。您甚至不需要指定转换方法的完整路径:

fn prog() -> Result<String, ProgError> {
    let path = try!(env::current_exe());
    let name = try!(path.file_name().ok_or(ProgError::NoFile));
    let s_name = try!(name.to_str().ok_or(ProgError::NotUtf8));
    Ok(s_name.to_owned())
}
Run Code Online (Sandbox Code Playgroud)

与将来的问号运算符一起,也可以将其编写为单个点调用链:

fn prog() -> Result<String, ProgError> {
    Ok(env::current_exe()?
        .file_name().ok_or(ProgError::NoFile)?
        .to_str().ok_or(ProgError::NotUtf8)?
        .to_owned())
}
Run Code Online (Sandbox Code Playgroud)

当然,这具有以下ProgError类型的先决条件:

use std::io::Error;

#[derive(Debug)]
enum ProgError {
    NoFile,
    NotUtf8,
    Io(Error),
}

impl From<Error> for ProgError {
    fn from(err: Error) -> ProgError {
        ProgError::Io(err)
    }
}
Run Code Online (Sandbox Code Playgroud)

在操场上尝试