为什么“abcd”.StartsWith(“”)返回true?
标题是整个问题。 有人能给我一个原因,为什么发生这种情况?
是的 – 因为它确实从空string开始。 的确,空string逻辑上发生在每对字符之间。
这样说:“开始”的定义是否可以解决这个问题? 这里有一个“开始”的简单定义,不包括:
“x从y开始,如果x的第一个y.Length
字符与y相匹配。
另一种(等同的)定义:
“x从y开始,如果x.Substring(0, y.Length).Equals(y)
”
我会试着详细阐述Jon Skeet所说的。
假设x,y和z是string,+运算符实际上是串联的,那么:
如果我们可以分割z来写z = x + y,这意味着z以x开始。 因为每个stringz可以被分割为z =“”+ z,所以每个string都以“”开始。
所以,因为(“”+“abcd”)==“abcd”,所以“abcd”以“”开始
此方法将value参数与此string的开始处的子string(与该值的长度相同)进行比较,并返回一个指示它们是否相等的值。 为了平等,value必须是一个空string(Empty),对同一个实例的引用,或者匹配这个实例的开始。
.NET String.StartsWith
如果参数表示的字符序列是由此string表示的字符序列的前缀,则为true; 否则为假。 另请注意,如果参数是一个空string,或者等于由equals(Object)方法确定的此String对象, 则将返回true 。
Java String.startsWith
我将从一个更容易理解的相关事实开始。
空集是每个集的子集。
为什么? 如果A
每个元素都是B
一个元素,则子集的定义表示A
是B
一个子集。 相反,如果A
的元素不是B
的元素,则A
不是B
的子集。
现在修理一套B
我将确定空集是B
一个子集。 我将通过显示不是空集不是B
的子集的情况来做到这一点。 如果空集不是B
的子集,那么我可以find不在B
中的空集的一个元素。 但空集没有任何元素,因此我找不到一个不在B
的元素。 因此,空集不是B
一个子集。 因此,空集必须是B
一个子集。
任何string都以空string开始。
首先,我们必须同意我们开始的定义。 设s
和t
是string
s如果s.Length >= t.Length
和t
的前t
字符与s
字符匹配,我们说s
从 t
开始 。 也就是说, s.Length >= t.Length
并且对于每个Int32 index
例如0 <= index < t.Length
, s[index] == t[index]
为true。 相反,我们可以说,如果声明不是从t
开始的
有一个Int32 index
,使得0 <= index < t.Length
和s[index] != t[index]
是真的。 用简单的英语, s
比t
短,或者,如果不是,则与s
的相同位置的字符不匹配。
现在修复一个strings
。 我会build立s
从空string开始。 我将通过显示s
不是以空string开始的情况来做到这一点。 如果s
不是以空string开始,那么s.Length < String.Empty.Length
或s.Length >= String.Empty.Length
并且存在一个Int32 index
,使得0 <= index < String.Empty.Length
。 但s.Length >= 0
且String.Empty.Length
等于零,所以s.Length < String.Empty.Length
不可能为true。 同样,由于“String.Empty.Length” is equal to zero, there is no
satisfying
0 <= index <String.Empty.Length的Int32索引。 因此
s.Length < String.Empty.Length
或s.Length >= String.Empty.Length
并且有一个Int32 index
使得0 <= index < String.Empty.Length
是错误的。 因此, s
不是以空string开始的。 因此, s
必须以空string开始。
以下是编码为string
扩展的开始实现。
public static bool DoStartsWith(this string s, string t) { if (s.Length >= t.Length) { for (int index = 0; index < t.Length; index++) { if (s[index] != t[index]) { return false; } } return true; } return false; }
以上两个粗体的事实是真实的陈述的例子。 它们是真实的,因为定义它们的语句( 子集和开头 )是对空宇宙的普遍量化 。 空集中没有元素,所以不能有空集的任何元素不在其他固定集中。 空string中没有字符,所以空string中的某个位置不能与其他固定string中的相同位置的字符不匹配。
我们只是说"abcd".StartsWith("")
返回false。
如果是这样的话,那么下面的expression式是真的还是假的:
("abcd".Substring(0,0) == "")
事实certificate,certificate是真实的,所以string确实从空string开始;或者换句话说,从位置0开始并具有0长度的子string“abcd”等于空string“”。 非常合乎逻辑的imo。
在C#中,这是规范告诉它做出反应的方式;
为了平等,value必须是一个空string(Empty),对同一个实例的引用,或者匹配这个实例的开始。
为什么“abcd”.StartsWith(“”)返回true?
真正的答案:
它必须是这样的,否则你会有这种情况
"".startsWith("") == false "".equals("") == true but yet "a".startsWith("a") == true "a".equals("a") == true
然后我们再来一遍Y2K,因为所有的银行软件都是以相同的string开头的,会让我们的账户混淆起来,突然比尔·盖茨将有我的财富,我会拥有他的,该死的! 命运对我来说并不那么友善。
两个string的前N个字符是相同的。 N是第二个string的长度,即零。
只是为了logging, String.StartsWith()
内部调用System.Globalization.CultureInfo.IsPrefix()
方法明确地进行以下检查:
if (prefix.Length == 0) { return true; }
因为一个string开始与“没有”很好。
如果你用正则expression式来思考它,这是有道理的。 每个string(不仅仅是“abcd”,还有“”和“sdf \ nff”)在计算'以空string开始'的正则expression式时返回true。
在C#中,它返回true
的原因是开发者专门为它编码的。
如果您签出源代码 ,您会发现处理空string的特定逻辑:
public Boolean StartsWith(String value) { return StartsWith(value, StringComparison.CurrentCulture); } public Boolean StartsWith(String value, StringComparison comparisonType) { ... if (value.Length == 0) { return true; }