“两个句号”运算符在方括号内的下标的上下文中意味着什么?

问题描述 投票:3回答:2

我正在查看Rust的源代码,以便更好地熟悉该语言。我遇到了这个片段。

// Collect program arguments as a Vec<String>.
let cmd: Vec<_> = env::args().collect();

// Some unrelated code omitted here.

match subcommand::parse_name(&cmd[1][..]) {
    // It did some stuff here.
}

我不明白[..]。所以,我去检查了parse_name的声明:

pub fn parse_name(name: &str) -> Option<Box<Subcommand>>

这是我的预期,但我仍然没有得到[..]。在这种情况下它意味着什么?是不是只是将String中的第一个cmd作为&str传递?如果是这样,这相当于只写cmd[1]?他们为什么这样做?

rust
2个回答
9
投票

这只是明确强制从String&str的一种方式。在这种情况下,[..]实际上是不必要的,因为Deref强制意味着parse_name(&args[1])也是有效的:&String将隐含地借用&str

[ ]索引运算符调用std::ops::Index特征,而..语法正在创建a std::ops::RangeFull valuecmd是一个Vec<String>,因为std::env::args()返回an Iterator over Strings

因此,foo[..]语法为Index<RangeFull>调用String的实现(您可以在Index页面上的实现者列表中看到)。 implementation看起来像:

impl ops::Index<ops::RangeFull> for String {
    type Output = str;

    #[inline]
    fn index(&self, _index: ops::RangeFull) -> &str {
        unsafe { mem::transmute(&*self.vec) }
    }
}

&*self.vec借用String的内部Vec<u8>&[u8],然后transmute明确地将其投射到&str,这是安全的,因为String的API确保内部Vec<u8>是有效的UTF-8,这是str所需要的。


9
投票

两个周期(..)是范围运算符。你可以在Rust书的Operators and Symbols Appendix找到这个。有六种口味:

  1. Range1..10
  2. RangeFrom1..
  3. RangeTo..10
  4. RangeFull..
  5. RangeInclusive1..=10
  6. RangeToInclusive..=10

当没有项目占据结束位置时,该范围在该方向上“永远”。

这与Index特征(或IndexMut,如果需要突变)相结合。在您的示例中,您有一个字符串切片(有点,见下一点),您正在应用索引:"foo"[2..]

具体来说,&str实施Index

从字节范围返回给定字符串的切片

然后有第三点人体工程学发生:Deref(或类似情况下的DerefMut)。 String通过返回Deref来实现&str,因此任何&str可用的方法都可用于String

© www.soinside.com 2019 - 2024. All rights reserved.