C# / Java 中的 IndexOf 方法在应该返回 -1 的情况下返回了 0

7

我的一个朋友向我反映了一个奇怪的行为,我无法解释,请帮忙提供一些见解。

我正在使用VS 2005(C# 2.0),以下代码显示了这种行为:

int rr = "test".IndexOf("");
Console.WriteLine(rr.ToString());

上述代码中,打印出了“0”,这清楚地表明它应该返回-1。

在Java中也会出现这种情况,以下类展示了这种行为:

public class Test{
 public static void main(String[] args){
   System.out.println("Result->"+("test".indexOf("")));
 }
}

我正在运行Java 1.6.0_17版本。


重复的问题:https://dev59.com/6W865IYBdhLWcg3wUs7z和https://dev59.com/4nVC5IYBdhLWcg3w7Vtq。 - Peter Lawrey
8个回答

21

C# 文档中的引用:

如果 value 是 Empty,则返回值为 0。

你描述的行为在 C# 中是完全符合预期的。


谢谢你指出这个问题(所以它似乎是规则的一个例外)。在它的对应语言JavaDoc中,没有很好地解释这种行为会被期望。 - jcgarciam
@jcgarciam:说得好,我会更新答案并指出它与C#有关。 - Fredrik Mörk

11

0 是正确的。从位置零开始,您可以(轻而易举地)匹配一个零长度的字符串。同样,"" 包含 ""。


那样做也没关系,如果那是我的例子,我尝试了:"Test".IndexOf("");这与你所解释的不同。 - jcgarciam
1
@jcgarciam 不完全是这样。从另一个角度来看,它在哪个方面不是以(或包含)""开头的呢?给我展示一下不匹配的字符。没有不匹配的字符,因此它是匹配的。 - Marc Gravell

10
这并非是例外,而是由于 indexOfstartsWith 的定义方式自然产生的结果。
您认为 "test".indexOf("") 应该返回 -1。这实质上等同于声称 "test".startsWith("") 应该返回 false。为什么呢?虽然文档中明确指出这种情况将返回 true,但这不仅仅是一个任意的决定。
例如,如何确定 "test".startsWith("te") 呢?最简单的方法是使用递归。由于两个字符串都以字符 't' 开头,因此您会调用 "est".startsWith("e") 并返回结果。同样地,您将调用 "st".startsWith("") 并返回结果。但是您已经知道答案应该是 true,因此每个字符串都以 "" 开头。

6

0是正确的。Javadocs指出indexOf的工作原理如下:

The integer returned is the smallest value k such that:

 this.startsWith(str, k)

""开头的任何字符串都等于原始字符串(每个字符串都以""开头),因此对于str = "",最小的k始终为0。


抱歉,我无法理解你的推理。 - jcgarciam
5
每个字符串都以""开头,同样,每个集合都是空集的超集。等等...这是一个非常方便的约定。 - glebm

3
想象一下:当使用 IndexOf 查找一个字符串时,它将从位置 0 开始尝试匹配该字符串,如果不匹配,则继续移动到位置 1、2 等等。当你使用空字符串调用它时,它会尝试在长度为 0 的字符串中从位置 0 开始匹配空字符串。好了,什么都等于空。
顺便说一下:当你使用 Console.Write/WriteLine 时,没有必要使用 ToString。该函数会自动调用问题对象的 ToString 方法。(除非重载 ToString)

在索引位置0,“test”并不是“nothing”,它有一个“t”。我为你的表述方式投了+1的赞:) - ring bearer
就像ring所说的,在位置0处它并不是“nothing”。但还是谢谢!看起来这在文档中有解释。我会将其作为IndexOf应该工作规则的异常处理。 - jcgarciam

2
它应该返回0。你是在寻找第一次出现空字符串的位置,对吧? :)

1

只是出于好玩而已。在Python中也可以这样做

>>> "test".startswith("")
True
>>> "test".index("")
0

Python会抛出一个ValueError,而不是-1,这是比较友好的行为。

>>> "test".index('r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: substring not found

1

更有趣的 PHP 实际上做得更好!

php -r "print strpos('test','');"
PHP Warning:  strpos(): Empty delimiter. in Command line code on line 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接