¿Por qué “abcd” .StartsWith (“”) devuelve verdadero?

El título es toda la pregunta. ¿Puede alguien darme una razón por la que esto sucede?

Sí, porque comienza con la cadena vacía. De hecho, la cadena vacía se produce lógicamente entre cada par de caracteres.

Póngalo de esta manera: ¿qué definición de “comienza con” podría dar que lo impediría? Aquí hay una definición simple de “comienza con” que no:

“x comienza con y si los primeros caracteres y.Length de x coinciden con los de y”.

Una definición alternativa (equivalente):

“x comienza con y si x.Substring(0, y.Length).Equals(y)

Trataré de explicar lo que dijo Jon Skeet.

Digamos que x, y y z son cadenas y + el operador es de hecho concatenación, entonces:

Si podemos dividir z para escribir z = x + y eso significa que z comienza con x. Debido a que cada cadena z se puede dividir en z = “” + z, se deduce que cada cadena comienza con “”.

Entonces, como (“” + “abcd”) == “abcd” se deduce que “abcd” comienza con “”

Este método compara el parámetro de valor con la subcadena al comienzo de esta cadena que tiene la misma longitud que el valor y devuelve un valor que indica si son iguales. Para ser igual, el valor debe ser una cadena vacía (Vacío), una referencia a esta misma instancia, o debe coincidir con el comienzo de esta instancia.

.NET String.StartsWith

true si la secuencia de caracteres representada por el argumento es un prefijo de la secuencia de caracteres representada por esta cadena; falso de lo contrario. Tenga en cuenta también que true se devolverá si el argumento es una cadena vacía o es igual a este objeto String según lo determinado por el método equals (Object).

Java String.startsWith

Comenzaré con un hecho relacionado que es más fácil de entender.

El conjunto vacío es un subconjunto de cada conjunto.

¿Por qué? La definición de subconjunto establece que A es un subconjunto de B si cada elemento de A es un elemento de B Por el contrario, A no es un subconjunto de B si hay un elemento de A que no es un elemento de B

Ahora arregla un conjunto B Estableceré que el conjunto vacío es un subconjunto de B Haré esto mostrando que no es el caso que el conjunto vacío no es un subconjunto de B Si el conjunto vacío no fuera un subconjunto de B entonces podría encontrar un elemento del conjunto vacío que no está en B Pero el conjunto vacío no tiene ningún elemento y, por lo tanto, no puedo encontrar un elemento que no esté en B Por lo tanto, no es el caso que el conjunto vacío no sea un subconjunto de B Por lo tanto, el conjunto vacío debe ser un subconjunto de B

Cualquier cadena comienza con la cadena vacía.

Primero, debemos estar de acuerdo con nuestra definición de comienza con . Deje que s y t sean string s Decimos que s comienza con t si s.Length >= t.Length y los primeros t.Length caracteres de t coinciden con los de s . Es decir, en la s.Length >= t.Length y para cada Int32 index tal que 0 <= index < t.Length , s[index] == t[index] es verdadero. Por el contrario, diríamos que s no comienza con t si el enunciado

s.Length < t.Length or s.Length >= t.Length y hay un Int32 index tal que 0 <= index < t.Length s[index] != t[index]

es verdad. En inglés simple, s es más corto que t , o, si no, hay un carácter en t no coincide con el personaje como la misma posición en s .

Ahora arregla una cadena s . Estableceré que s comienza con la cadena vacía. Haré esto mostrando que no es el caso que s no comience con la cadena vacía. Si s no comienza con la cadena vacía, entonces s.Length < String.Empty.Length or s.Length >= String.Empty.Length y hay un Int32 index tal que 0 <= index < String.Empty.Length . Pero a la s.Length >= 0 y String.Empty.Length es igual a cero, por lo que es imposible que s.Length < String.Empty.Length sea ​​verdadero. Del mismo modo, dado que `` String.Empty.Length is equal to zero, there is no índice Int32 que satisfying 0 <= índice

s.Length < String.Empty.Length or s.Length >= String.Empty.Length y hay un Int32 index tal que 0 <= index < String.Empty.Length

Es falso. Por lo tanto, no es el caso que s no comience con la cadena vacía. Por lo tanto, s debe comenzar con la cadena vacía.

La siguiente es una implementación de comienza con código como una extensión de 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; } 

Los dos hechos en negrita anteriores son ejemplos de enunciados vanos y verdaderos . Son ciertos en virtud del hecho de que las declaraciones que los definen ( subconjunto y comienza con ) son cuantificaciones universales sobre universos vacíos. No hay elementos en el conjunto vacío, por lo que no puede haber ningún elemento del conjunto vacío en ningún otro conjunto fijo. No hay caracteres en la cadena vacía, por lo que no puede haber un carácter como posición en la cadena vacía que no coincida con el carácter en la misma posición en alguna otra cadena fija.

Digamos "abcd".StartsWith("") devuelve falso.

si es así, ¿a qué evalúa la siguiente expresión, verdadera o falsa?

  ("abcd".Substring(0,0) == "") 

resulta que evals es verdadero, por lo que la cadena comienza con la cadena vacía ;-), o dicho de otro modo, la subcadena de “abcd” que comienza en la posición 0 y que tiene 0 es igual a la cadena vacía “”. Muy lógico imo.

En C #, así es como la especificación le dice que reaccione;

Para ser igual, el valor debe ser una cadena vacía (Vacío), una referencia a esta misma instancia, o debe coincidir con el comienzo de esta instancia.

¿Por qué “abcd” .StartsWith (“”) devuelve verdadero?

LA RESPUESTA REAL:

Tiene que ser de esa manera, de lo contrario tendrías el caso donde

  "".startsWith("") == false "".equals("") == true but yet "a".startsWith("a") == true "a".equals("a") == true 

y luego tendríamos Y2K de nuevo porque todo el software del banco que depende de cadenas iguales empezando por ellos mismos hará que nuestras cuentas se mezclen y de repente Bill Gates tendrá mi riqueza y yo la suya, ¡y maldita sea! El destino simplemente no es tan bueno para mí.

Los primeros N caracteres de las dos cadenas son idénticos. N es la longitud de la segunda cuerda, es decir, cero.

Solo para el registro, String.StartsWith() llama internamente al método System.Globalization.CultureInfo.IsPrefix() que hace la siguiente verificación explícitamente:

 if (prefix.Length == 0) { return true; } 

Porque una cuerda comienza bien con “nada”.

Si lo piensas en términos de expresiones regulares, tiene sentido. Cada cadena (no solo “abcd”, también “” y “sdf \ nff”), devuelve verdadero al evaluar la expresión regular de ‘comienza con cadena vacía’.

En C #, la razón por la que devuelve true es que los desarrolladores lo codificaron específicamente.

Si revisa el código fuente , encontrará una lógica específica para manejar una cadena vacía:

 public Boolean StartsWith(String value) { return StartsWith(value, StringComparison.CurrentCulture); } public Boolean StartsWith(String value, StringComparison comparisonType) { ... if (value.Length == 0) { return true; }