Tytuł to całe pytanie. Czy ktoś może mi podać powód, dla którego tak się dzieje?
Tytuł to całe pytanie. Czy ktoś może mi podać powód, dla którego tak się dzieje?
Odpowiedzi:
Tak - ponieważ zaczyna się od pustego ciągu. Rzeczywiście, pusty ciąg logicznie występuje między każdą parą znaków.
Ujmując to w ten sposób: jaką definicję „zaczyna się od” mógłbyś podać, która by to wykluczała? Oto prosta definicja „zaczyna się od”, która nie:
„x zaczyna się od y, jeśli pierwsze y.Length
znaki x są zgodne z y”.
Alternatywna (równoważna) definicja:
„x zaczyna się od y, jeśli x.Substring(0, y.Length).Equals(y)
”
Spróbuję rozwinąć to, co powiedział Jon Skeet.
Powiedzmy, że x, y i z są łańcuchami, a operator + jest w rzeczywistości konkatenacją, a następnie:
Jeśli możemy podzielić z, aby zapisać z = x + y, oznacza to, że z zaczyna się od x. Ponieważ każdy ciąg z można podzielić na z = "" + z, wynika z tego, że każdy ciąg zaczyna się od "".
Tak więc, ponieważ ("" + "abcd") == "abcd" wynika z tego, że "abcd" zaczyna się od ""
Ta metoda porównuje parametr value z podciągiem na początku tego ciągu, który ma taką samą długość jak value, i zwraca wartość wskazującą, czy są one równe. Aby być równe, wartość musi być pustym ciągiem (Empty), odwołaniem do tego samego wystąpienia lub odpowiadać początkowi tego wystąpienia.
true, jeśli sekwencja znaków reprezentowana przez argument jest przedrostkiem sekwencji znaków reprezentowanej przez ten ciąg; w przeciwnym razie fałsz. Należy również zauważyć, że wartość true zostanie zwrócona, jeśli argument jest pustym ciągiem lub jest równy temu obiektowi String, zgodnie z metodą equals (Object).
Zacznę od powiązanego faktu, który jest łatwiejszy do zrozumienia.
Pusty zbiór jest podzbiorem każdego zestawu.
Czemu? Definicja z podzbioru stanów, które A
jest podzbiorem B
jeśli każdy element A
jest elementem B
. I odwrotnie, A
nie jest podzbiorem, B
jeśli istnieje element, A
który nie jest elementem B
.
Teraz napraw zestaw B
. Ustalę, że pusty zbiór jest podzbiorem B
. Zrobię to, pokazując, że nie jest tak, że pusty zbiór nie jest podzbiorem B
. Gdyby pusty zestaw nie był podzbiorem B
, mógłbym znaleźć element pustego zestawu, którego nie ma B
. Ale pusty zestaw nie ma żadnych elementów i dlatego nie mogę znaleźć elementu, którego nie ma B
. Dlatego nie jest tak, że pusty zbiór nie jest podzbiorem B
. Zatem pusty zbiór musi być podzbiorem B
.
Każdy ciąg zaczyna się od pustego łańcucha.
Po pierwsze, musimy zgodzić się na naszą definicję rozruchów . Let s
and t
be string
s Mówimy, że s
zaczyna się od t
if, s.Length >= t.Length
a pierwsze t.Length
znaki t
pasują do tych z s
. Oznacza to, że s.Length >= t.Length
i dla każdego Int32 index
takie, że 0 <= index < t.Length
, s[index] == t[index]
jest prawdą. I odwrotnie, powiedzielibyśmy, że s
nie zaczyna się od, t
jeśli instrukcja
s.Length < t.Length
lub s.Length >= t.Length
i jest Int32 index
taki, że 0 <= index < t.Length
is[index] != t[index]
jest prawdziwy. Mówiąc prostym językiem, s
jest krótszy niż t
, lub, jeśli nie, jest znak, który t
nie pasuje do znaku w tej samej pozycji s
.
Teraz napraw ciąg s
. Ustalę, że s
zaczyna się od pustego łańcucha. Zrobię to, pokazując, że nie jest tak, że s
nie zaczyna się od pustego ciągu. Jeśli s
nie zaczyna się od pustego łańcucha, to s.Length < String.Empty.Length
lub s.Length >= String.Empty.Length
i jest Int32 index
taki, że 0 <= index < String.Empty.Length
. Ale s.Length >= 0
i String.Empty.Length
jest równe zero, więc nie może s.Length < String.Empty.Length
być prawdziwe. Podobnie, ponieważ `` String.Empty.Length is equal to zero, there is no
Int32 index satisfying
0 <= index <String.Empty.Length`. W związku z tym
s.Length < String.Empty.Length
lub s.Length >= String.Empty.Length
i jest Int32 index
taki, że0 <= index < String.Empty.Length
to fałsz. Dlatego nie jest tak, że s
nie zaczyna się od pustego ciągu. Dlatego s
musi zaczynać się od pustego ciągu.
Poniżej przedstawiono implementację startów z zakodowanym jako rozszerzenie 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;
}
Powyższe dwa pogrubione fakty są przykładami twierdzeń bezmyślnie prawdziwych . Są one prawdziwe z tego względu, że stwierdzenia je definiujące ( podzbiór i rozpoczynają się od ) są uniwersalnymi kwantyfikacjami pustych wszechświatów. W pustym zestawie nie ma elementów, więc nie może być żadnych elementów z pustego zestawu, których nie ma w innym ustalonym zestawie. W pustym ciągu nie ma żadnych znaków, więc nie może być znaku, ponieważ jakaś pozycja w pustym ciągu nie pasuje do znaku na tej samej pozycji w innym ustalonym ciągu.
Powiedzmy, że "abcd".StartsWith("")
zwraca fałsz.
jeśli tak, to do czego zmienia się następujące wyrażenie, prawda czy fałsz:
("abcd".Substring(0,0) == "")
okazuje się, że evals to true, więc łańcuch zaczyna się od pustego łańcucha ;-), czyli innymi słowy, podciąg „abcd” zaczynający się na pozycji 0 i mający 0 długości równa się pustemu ciągowi „”. Całkiem logiczne imo.
null
byłaby równie odpowiednią wartością zwracaną.
W C # w ten sposób specyfikacja nakazuje mu reagować;
Aby być równe, wartość musi być pustym ciągiem (Empty), odwołaniem do tego samego wystąpienia lub odpowiadać początkowi tego wystąpienia.
Dlaczego „abcd” .StartsWith („”) zwraca prawdę?
PRAWDZIWA ODPOWIEDŹ:
Musi tak być, w przeciwnym razie miałbyś przypadek, w którym
"".startsWith("") == false
"".equals("") == true
but yet
"a".startsWith("a") == true
"a".equals("a") == true
a potem znowu mielibyśmy Y2K, ponieważ całe oprogramowanie bankowe, które opiera się na równych łańcuchach zaczynających się od siebie, pomieszałoby nasze konta i nagle Bill Gates będzie miał moje bogactwo, a ja będę miał jego, do cholery! Po prostu los nie jest dla mnie taki łaskawy.
Dla przypomnienia, String.StartsWith()
wewnętrznie wywołuje metodę, System.Globalization.CultureInfo.IsPrefix()
która jawnie dokonuje następującego sprawdzenia:
if (prefix.Length == 0)
{
return true;
}
Jeśli myślisz o tym w terminach wyrażeń regularnych, ma to sens. Każdy ciąg (nie tylko „abcd”, ale także „” i „sdf \ nff”) zwraca prawdę podczas obliczania wyrażenia regularnego „zaczyna się od pustego ciągu”.