为啥 "abcd".StartsWith("") 返回 true?
Posted
技术标签:
【中文标题】为啥 "abcd".StartsWith("") 返回 true?【英文标题】:Why does "abcd".StartsWith("") return true?为什么 "abcd".StartsWith("") 返回 true? 【发布时间】:2010-09-13 19:35:04 【问题描述】:标题是整个问题。谁能告诉我为什么会发生这种情况?
【问题讨论】:
【参考方案1】:是的 - 因为它确实以空字符串开头。事实上,空字符串逻辑上出现在每对字符之间。
这样说吧:你能给出什么“开始于”的定义来排除这种情况?以下是“开头”的简单定义:
"如果 x 的第一个 y.Length
字符与 y 匹配,则 x 以 y 开头。"
另一种(等效)定义:
"如果x.Substring(0, y.Length).Equals(y)
,则x以y开头"
【讨论】:
x 以 y 开头 if x.Substring(0,y.Length).Equals(y) 当且仅当 y.Length > 0 是的,您确实可以明确排除这种情况。不过,这是一个非常不雅的定义,不是吗? 是的。它还要求它们也是非空的......但我想说这两者都增加了准确性,同时又远离了简单定义的精神 :) 每对字符之间出现无数次空字符串。 是的,就像在数字前加一个零一样——它不会改变值,但它仍然存在。【参考方案2】:我将尝试详细说明 Jon Skeet 所说的内容。
假设x、y和z是字符串,而+运算符实际上是连接,那么:
如果我们可以将 z 拆分为 z = x + y,这意味着 z 以 x 开头。 因为每个字符串 z 都可以拆分为 z = "" + z,所以每个字符串都以 "" 开头。
所以,因为 ("" + "abcd") == "abcd" 所以 "abcd" 以 "" 开头
【讨论】:
【参考方案3】:我将从一个更容易理解的相关事实开始。
空集是每个集的子集。
为什么?如果A
的每个元素都是B
的元素,则子集 的definition 声明A
是B
的子集。相反,如果A
的元素不是B
的元素,则A
不是B
的子集。
现在修复一组B
。我将确定空集是B
的子集。我将通过证明空集不是B
的子集的情况来做到这一点。如果空集不是B
的子集,那么我可以找到不在B
中的空集元素。但是空集没有任何元素,因此我找不到不在B
中的元素。因此,空集并不是B
的子集。因此,空集必须是B
的子集。
任何字符串都以空字符串开头。
首先,我们必须就以开头的定义达成一致。让s
和t
成为string
s 我们说s
以 t
如果s.Length >= t.Length
和t
的第一个t.Length
字符匹配@ 987654348@。也就是说,s.Length >= t.Length
和每个Int32 index
使得0 <= index < t.Length
、s[index] == t[index]
为真。相反,我们会说s
不是以t
开头的 if 语句
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
不是以空字符串开头的情况来做到这一点。如果s
不以空字符串开头,则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
不可能为真。同样,由于“String.Empty.Lengthis equal to zero, there is no
Int32 indexsatisfying
0
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;
以上两个加粗的事实是vacuously true statements的例子。它们是正确的,因为定义它们的语句(子集和以开头)在空域上是universal quantifications。空集中没有元素,所以不能有任何不在其他固定集中的空集元素。空字符串中没有字符,所以不能有一个字符作为空字符串中的某个位置与其他某个固定字符串中相同位置的字符不匹配。
【讨论】:
【参考方案4】:该方法将value参数与该字符串开头与value长度相同的子字符串进行比较,并返回一个值,表示它们是否相等。 要相等,value 必须是空字符串(Empty)、对同一个实例的引用,或者匹配这个实例的开头。
.NET String.StartsWith
如果参数表示的字符序列是该字符串表示的字符序列的前缀,则为true;否则为假。 另请注意,如果参数为空字符串或等于由 equals(Object) 方法确定的此 String 对象,则将返回 true。
Java String.startsWith
【讨论】:
【参考方案5】:假设 "abcd".StartsWith("")
返回 false。
如果是这样,那么下面的表达式 eval 是什么,是真还是假:
("abcd".Substring(0,0) == "")
原来 eval 为真,所以字符串确实以空字符串开头 ;-),或者换句话说,“abcd”的子字符串从位置 0 开始并且长度为 0 等于空字符串“” .非常合乎逻辑。
【讨论】:
“abcd”.Substring(0, 0) 返回空字符串的事实并不意味着“abcd”实际上以空字符串开头。结果也可以声明为“未定义”,因为null
将是一个同样合适的返回值。
@TomLint 否。您通常会结合条件 IE x.FirstName.StartsWith(userEnteredFirstName) && x.LastName.StartsWith(userEnteredLastName) .... 即使输入的值之一,这也会使条件起作用是空字符串。【参考方案6】:
在 C# 中,这是 specification 告诉它做出反应的方式;
要相等,value 必须是空字符串(Empty)、对同一个实例的引用,或者匹配这个实例的开头。
【讨论】:
【参考方案7】:两个字符串的前 N 个字符相同。 N是第二个字符串的长度,即零。
【讨论】:
【参考方案8】:为什么“abcd”.StartsWith(“”) 返回 true?
真正的答案:
必须是这样,否则你会遇到这种情况
"".startsWith("") == false
"".equals("") == true
but yet
"a".startsWith("a") == true
"a".equals("a") == true
然后我们将再次拥有千年虫,因为所有依赖于以自身开头的相同字符串的银行软件都会混淆我们的帐户,突然间比尔盖茨将拥有我的财富,而我将拥有他的,该死的!命运对我并不那么好。
【讨论】:
我不同意。 "".startsWith("") 应该等于 true,因为字符串是相同的,而不是因为一些奇怪的业务逻辑。 @TomLint 您实际上同意答案中的断言......【参考方案9】:为了记录,String.StartsWith()
内部调用了方法System.Globalization.CultureInfo.IsPrefix()
,它显式地进行了以下检查:
if (prefix.Length == 0)
return true;
【讨论】:
【参考方案10】:因为字符串以“nothing”开头。
【讨论】:
... 那就是如果 string.empty 什么都不是!这种过度简化不能一概而论。我建议我们遵循更多面向集合理论的讨论。【参考方案11】:如果你用正则表达式来思考它,它是有道理的。 每个字符串(不仅仅是“abcd”,还有“”和“sdf\nff”), 在评估 'starts with empty string' 的正则表达式时返回 true。
【讨论】:
以上是关于为啥 "abcd".StartsWith("") 返回 true?的主要内容,如果未能解决你的问题,请参考以下文章
为啥“”.abcd 返回未定义的值而不是在 Javascript 中抛出未定义的错误(但 Typescript 抛出警告)
swift为啥不使用string自带的rangeofstring
QT里QTimer为啥stop停不,每次start就会有一个新的计时器跟着一起跑?