Tytuł to całe pytanie. Czy ktoś może mi podać powód, dla którego tak się dzieje?
c#
java
startswith
Zniszczony
źródło
źródło
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 ""
źródło
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.
.NET String.StartsWith
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).
Java String.startsWith
źródło
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 podzbioremB
jeśli każdy elementA
jest elementemB
. I odwrotnie,A
nie jest podzbiorem,B
jeśli istnieje element,A
który nie jest elementemB
.Teraz napraw zestaw
B
. Ustalę, że pusty zbiór jest podzbioremB
. Zrobię to, pokazując, że nie jest tak, że pusty zbiór nie jest podzbioremB
. Gdyby pusty zestaw nie był podzbioremB
, mógłbym znaleźć element pustego zestawu, którego nie maB
. Ale pusty zestaw nie ma żadnych elementów i dlatego nie mogę znaleźć elementu, którego nie maB
. Dlatego nie jest tak, że pusty zbiór nie jest podzbioremB
. Zatem pusty zbiór musi być podzbioremB
.Każdy ciąg zaczyna się od pustego łańcucha.
Po pierwsze, musimy zgodzić się na naszą definicję rozruchów . Let
s
andt
bestring
s Mówimy, żes
zaczyna się odt
if,s.Length >= t.Length
a pierwszet.Length
znakit
pasują do tych zs
. Oznacza to, żes.Length >= t.Length
i dla każdegoInt32 index
takie, że0 <= index < t.Length
,s[index] == t[index]
jest prawdą. I odwrotnie, powiedzielibyśmy, żes
nie zaczyna się od,t
jeśli instrukcjas.Length < t.Length
lubs.Length >= t.Length
i jestInt32 index
taki, że0 <= 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óryt
nie pasuje do znaku w tej samej pozycjis
.Teraz napraw ciąg
s
. Ustalę, żes
zaczyna się od pustego łańcucha. Zrobię to, pokazując, że nie jest tak, żes
nie zaczyna się od pustego ciągu. Jeślis
nie zaczyna się od pustego łańcucha, tos.Length < String.Empty.Length
lubs.Length >= String.Empty.Length
i jestInt32 index
taki, że0 <= index < String.Empty.Length
. Ales.Length >= 0
iString.Empty.Length
jest równe zero, więc nie możes.Length < String.Empty.Length
być prawdziwe. Podobnie, ponieważ `` String.Empty.Lengthis equal to zero, there is no
Int32 indexsatisfying
0 <= index <String.Empty.Length`. W związku z tyms.Length < String.Empty.Length
lubs.Length >= String.Empty.Length
i jestInt32 index
taki, że0 <= index < String.Empty.Length
to fałsz. Dlatego nie jest tak, że
s
nie zaczyna się od pustego ciągu. Dlategos
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.
źródło
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.
źródło
null
byłaby równie odpowiednią wartością zwracaną.W C # w ten sposób specyfikacja nakazuje mu reagować;
źródło
Pierwsze N znaków z dwóch ciągów jest identycznych. N jest długością drugiego łańcucha, czyli zero.
źródło
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.
źródło
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; }
źródło
Ponieważ ciąg zaczyna się dobrze od „niczego”.
źródło
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”.
źródło