大家对下面这段Rust程序觉得好奇吗?

发布一下 0 0

有位小伙伴发了如下一段代码, 要求帮忙解释下, 觉得好奇为什么Path::new能接受不同类型的入参.

use std::path::Path;fn main() {    let str: &str = "/Users/zjl/project/1.txt";    // Path::new 接受了 字符串字面量(切片) 作为参数    let path_from_str: &Path = Path::new(str);    let string: String = String::from("/Users/zjl/project/1.txt");    // Path::new 接受了 String的引用 作为参数    let path_from_string: &Path = Path::new(&string);    // 获取文件名    if let Some(file_name) = path_from_str.file_name() {        println!("文件名: {:?}", file_name);    }    // 获取文件名    if let Some(file_name) = path_from_string.file_name() {        println!("文件名: {:?}", file_name);    }}

其实知识点很简单: trait作为参数来接受多种不同类型的参数, 提供更灵活的参数接受方式, 并增加代码的可重用性和泛化性.

关于 trait 作为参数的教程: Trait:定义共同行为 - Rust 程序设计语言 简体中文版、Traits: Defining Shared Behavior - The Rust Programming Language

Path::new的源代码如下:

pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path {    unsafe { &*(s.as_ref() as *const OsStr as *const Path) }}

参数类型S要求是实现了 AsRef<OsStr> trait.

AsRef 字面含义是"作为引用", 理解为将一种类型的引用转化为另一种类型的引用.

pub trait AsRef<T>where    T: ?Sized,{    // Required method    fn as_ref(&self) -> &T;}

通过以上Trait源码也是这个含义(将一种类型的引用转化为另一种类型的引用)

new的入参要求只要是实现了 AsRef<OsStr> trait的类型其实都可以.

查看标准库文库, 不难发现:

impl AsRef<OsStr> for strimpl AsRef<OsStr> for OsStrimpl AsRef<OsStr> for OsStringimpl AsRef<OsStr> for Components<'_>impl AsRef<OsStr> for std::path::Iter<'_>impl AsRef<OsStr> for Pathimpl AsRef<OsStr> for PathBufimpl AsRef<OsStr> for String

以上类型都实现了 AsRef trait, 不光是str、String能作为参数, 其实还有 OsStr、OsString、Components<'>、std::path::Iter<'>、Path、PathBuf 都可以作为参数.

希望对大家有用, 多多交流.

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/211436.html