标题是整个问题。有人可以给我一个发生这种情况的原因吗?
11 回答
是的 - 因为它确实以空字符串开头。实际上,空字符串逻辑上出现在每对字符之间。
这么说吧:你能给出什么“开始于”的定义来排除这种情况?这是一个简单的“开始于”的定义,它不是:
“如果 x 的第一个字符与 y 的第一个y.Length
字符匹配,则 x 以 y 开头。”
另一种(等效)定义:
"x 以 y 开头如果x.Substring(0, y.Length).Equals(y)
"
我将尝试详细说明 Jon Skeet 所说的内容。
假设 x、y 和 z 是字符串,而 + 运算符实际上是连接,那么:
如果我们可以将 z 拆分为 z = x + y,这意味着 z 以 x 开头。因为每个字符串 z 都可以拆分为 z = "" + z,所以每个字符串都以 "" 开头。
所以,因为 ("" + "abcd") == "abcd" 所以 "abcd" 以 "" 开头
我将从一个更容易理解的相关事实开始。
空集是每个集合的子集。
为什么?如果 的每个元素都是 的元素,则子集状态的定义是的子集。相反,不是 的子集,如果有 的元素不是 的元素。A
B
A
B
A
B
A
B
现在修一套B
。我将确定空集是 的子集B
。我将通过证明空集不是B
. 如果空集不是的子集,B
那么我可以找到不在的空集的元素B
。但是空集没有任何元素,因此我找不到不在B
. 因此,空集并不是 的子集B
。因此,空集必须是 的子集B
。
任何字符串都以空字符串开头。
首先,我们必须同意我们对以开头的定义。Let s
and t
be string
s 我们说s
以 t
if开头,并且matchs.Length >= t.Length
的第一个t.Length
字符。也就是说,对于每一个这样的,都是真的。相反,我们会说if 语句不以 if 开头t
s
s.Length >= t.Length
Int32 index
0 <= index < t.Length
s[index] == t[index]
s
t
s.Length < t.Length
或者s.Length >= t.Length
并且有一个Int32 index
这样的0 <= index < t.Length
和s[index] != t[index]
是真的。在简单的英语中,s
比 短t
,或者,如果不是,则有一个字符在t
不匹配字符作为相同位置的字符s
。
现在修复一个字符串s
。我将从s
空字符串开始。我将通过证明它不是s
不以空字符串开头的情况来做到这一点。Ifs
不以空字符串开头 then s.Length < String.Empty.Length
or s.Length >= String.Empty.Length
and 有一个Int32 index
这样的0 <= index < String.Empty.Length
。但是s.Length >= 0
andString.Empty.Length
等于 0,所以不可能为s.Length < String.Empty.Length
真。同样,由于``String.Empty.Length is equal to zero, there is no
Int32 index satisfying
0 <= index < String.Empty.Length`。所以
s.Length < String.Empty.Length
或者s.Length >= String.Empty.Length
并且有一个Int32 index
这样的0 <= index < String.Empty.Length
是假的。因此,不是s
不以空字符串开头的情况。因此,s
必须以空字符串开头。
下面是一个以编码为扩展的开头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;
}
以上两个加粗的事实是空洞真实的陈述的例子。它们是正确的,因为定义它们的语句(子集和开头)是对空宇宙的普遍量化。空集中没有元素,所以不能有任何不在其他固定集中的空集元素。空字符串中没有字符,因此不能有一个字符作为空字符串中的某个位置与其他某个固定字符串中相同位置的字符不匹配。
该方法将 value 参数与该字符串开头的与 value 长度相同的子字符串进行比较,并返回一个表明它们是否相等的值。要相等,value 必须是空字符串 (Empty)、对同一实例的引用或匹配此实例的开头。
如果参数表示的字符序列是此字符串表示的字符序列的前缀,则为 true;否则为假。另请注意,如果参数是空字符串或等于由 equals(Object) 方法确定的此 String 对象,则将返回 true 。
让我们说"abcd".StartsWith("")
返回false。
如果是这样,那么下面的表达式 eval 是什么,真或假:
("abcd".Substring(0,0) == "")
事实证明,evals 为真,所以字符串确实以空字符串开头;-),或者换句话说,“abcd”的子字符串从位置 0 开始并且长度为 0 等于空字符串“”。很合乎逻辑的海事组织。
在 C# 中,这是规范告诉它做出反应的方式;
要相等,value 必须是空字符串 (Empty)、对同一实例的引用或匹配此实例的开头。
两个字符串的前 N 个字符相同。N 是第二个字符串的长度,即零。
为什么“abcd”.StartsWith(“”) 返回 true?
真正的答案:
必须是这样,否则你会遇到这样的情况
"".startsWith("") == false
"".equals("") == true
but yet
"a".startsWith("a") == true
"a".equals("a") == true
然后我们将再次拥有千年虫,因为所有依赖于以自身开头的相同字符串的银行软件都会混淆我们的账户,突然间比尔盖茨将拥有我的财富,而我将拥有他的财富,该死!命运对我不是那么好。
只是为了记录,String.StartsWith()
内部调用了System.Globalization.CultureInfo.IsPrefix()
明确进行以下检查的方法:
if (prefix.Length == 0)
{
return true;
}
因为字符串以“nothing”开头。
如果您以正则表达式的形式考虑它,那是有道理的。每个字符串(不仅是 "abcd",还有 "" 和 "sdf\nff")在评估“以空字符串开头”的正则表达式时都返回 true。