Por que “abcd” .StartsWith (“”) retorna verdadeiro?


87

O título é toda a questão. Alguém pode me dar um motivo para isso acontecer?

Respostas:


164

Sim - porque começa com a string vazia. Na verdade, a string vazia ocorre logicamente entre cada par de caracteres.

Coloque desta forma: que definição de "começa com" você poderia dar para impedir isso? Aqui está uma definição simples de "começa com" que não funciona:

"x começa com y se os primeiros y.Lengthcaracteres de x corresponderem aos de y."

Uma definição alternativa (equivalente):

"x começa com y se x.Substring(0, y.Length).Equals(y)"


3
x começa com y se x.Substring (0, y.Length) .Equals (y) se e somente se y.Length> 0
Vinko Vrsalovic

8
Sim, você poderia excluir explicitamente este caso. É uma definição bastante deselegante, não é?
Jon Skeet

7
Verdadeiro. Também requer que eles sejam não nulos ... mas eu diria que ambos aumentam a precisão ao mesmo tempo que afastam o espírito da definição simples :)
Jon Skeet

8
Ocorrências infinitas da string vazia ocorrem entre cada par de caracteres.
Lotus Notes

3
Sim, é como colocar um zero antes de um número - não altera o valor, mas ainda existe.
pop850 de

47

Vou tentar elaborar o que Jon Skeet disse.

Digamos que x, y e z sejam strings e o operador + seja de fato concatenação, então:

Se pudermos dividir z para escrever z = x + y, isso significa que z começa com x. Como toda string z pode ser dividida em z = "" + z, segue-se que toda string começa com "".

Portanto, como ("" + "abcd") == "abcd" segue-se que "abcd" começa com ""


17

Este método compara o parâmetro value com a substring no início desta string que tem o mesmo comprimento que value e retorna um valor que indica se eles são iguais. Para ser igual, o valor deve ser uma string vazia (Vazio), uma referência a esta mesma instância ou corresponder ao início desta instância.

.NET String.StartsWith

true se a seqüência de caracteres representada pelo argumento for um prefixo da seqüência de caracteres representada por esta string; caso contrário, false. Observe também que true será retornado se o argumento for uma string vazia ou igual a este objeto String, conforme determinado pelo método equals (Object).

Java String.startsWith


17

Vou começar com um fato relacionado que é mais fácil de entender.

O conjunto vazio é um subconjunto de cada conjunto.

Por quê? A definição de subconjunto indica que Aé um subconjunto de Bse cada elemento de Afor um elemento de B. Por outro lado, Anão é um subconjunto de, Bse houver um elemento de Aque não seja um elemento de B.

Agora conserte um conjunto B. Vou estabelecer que o conjunto vazio é um subconjunto de B. Farei isso mostrando que não é o caso em que o conjunto vazio não é um subconjunto de B. Se o conjunto vazio não fosse um subconjunto de B, eu poderia encontrar um elemento do conjunto vazio que não está em B. Mas o conjunto vazio não possui nenhum elemento e, portanto, não consigo encontrar um elemento que não esteja em B. Portanto, não é o caso de que o conjunto vazio não seja um subconjunto de B. Portanto, o conjunto vazio deve ser um subconjunto de B.

Qualquer string começa com uma string vazia.

Primeiro, devemos concordar em nossa definição de começa com . Let sand tbe strings Dizemos que s começa com t se s.Length >= t.Lengthe os primeiros t.Lengthcaracteres de tcorrespondem aos de s. Isso é, s.Length >= t.Lengthe para tudo Int32 indexisso 0 <= index < t.Length, s[index] == t[index]é verdade. Por outro lado, diríamos que snão começa com tse a declaração

s.Length < t.Lengthou s.Length >= t.Lengthe existe Int32 indextal que 0 <= index < t.Lengthes[index] != t[index]

é verdade. Em português simples, sé menor que tou, se não, existe um caractere em tnão corresponder ao caractere da mesma posição em s.

Agora conserte uma corda s. Vou estabelecer que scomeça com a string vazia. Farei isso mostrando que não é o caso de snão começar com a string vazia. Se snão começar com a string vazia, então s.Length < String.Empty.Lengthou s.Length >= String.Empty.Lengthe existe Int32 indextal que 0 <= index < String.Empty.Length. Mas s.Length >= 0e String.Empty.Lengthé igual a zero, então é impossível s.Length < String.Empty.Lengthser verdade. Da mesma forma, como `` String.Empty.Length is equal to zero, there is noInt32 index satisfying0 <= index <String.Empty.Length`. Portanto

s.Length < String.Empty.Lengthou s.Length >= String.Empty.Lengthe existe Int32 indextal que0 <= index < String.Empty.Length

é falso. Portanto, não é o caso de snão começar com a string vazia. Portanto, sdeve começar com a string vazia.

A seguir está uma implementação de starts with codificado como uma extensão 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;
}

Os dois fatos em negrito acima são exemplos de afirmações vagamente verdadeiras . Eles são verdadeiros em virtude do fato de que as afirmações que os definem ( subconjunto e começa com ) são quantificações universais sobre universos vazios. Não há elementos no conjunto vazio, portanto não pode haver nenhum elemento do conjunto vazio que não esteja em algum outro conjunto fixo. Não há caracteres na string vazia, então não pode haver um caractere como alguma posição na string vazia que não corresponda ao caractere na mesma posição em alguma outra string fixa.


13

Digamos que "abcd".StartsWith("")retorna falso.

em caso afirmativo, o que significa a seguinte expressão, verdadeiro ou falso:

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

Acontece que evals para true, então a string começa com a string vazia ;-), ou em outras palavras, a substring de "abcd" começando na posição 0 e tendo comprimento 0 é igual à string vazia "". Muito lógico, sim.


O fato de "abcd" .Substring (0, 0) retornar uma string vazia não significa que "abcd" realmente comece com uma string vazia. O resultado também pode ter sido declarado 'indefinido', pois nullseria um valor de retorno igualmente apropriado.
Tom Lint

@TomLint Não. Você normalmente combina condições IE x.FirstName.StartsWith (userEnteredFirstName) && x.LastName.StartsWith (userEnteredLastName) .... Isso faz com que a condição funcione mesmo se um dos valores inseridos for uma string vazia.
Pop Catalin

7

Em C #, é assim que a especificação o instrui a reagir;

Para ser igual, o valor deve ser uma string vazia (Vazio), uma referência a esta mesma instância ou corresponder ao início desta instância.


5

Os primeiros N caracteres das duas strings são idênticos. N sendo o comprimento da segunda corda, ou seja, zero.


5

Por que “abcd” .StartsWith (“”) retorna verdadeiro?

A REAL RESPOSTA:

Tem que ser assim, caso contrário, você teria o caso em que

    "".startsWith("") == false 
    "".equals("") == true

    but yet

    "a".startsWith("a") == true
    "a".equals("a") == true

e então teríamos o Y2K novamente, porque todo o software do banco que depende de cordas iguais começando com eles mesmos vai misturar nossas contas e de repente Bill Gates terá minha riqueza e eu teria a dele, e dane-se! O destino simplesmente não é tão bom para mim.


Discordo. "" .startsWith ("") deve ser igual a true, porque as strings são idênticas e não por causa de alguma lógica de negócios estranha.
Tom Lint

@TomLint Você está de fato concordando com a afirmação da resposta ...
neonblitzer

4

Apenas para registro, String.StartsWith()chama internamente o método System.Globalization.CultureInfo.IsPrefix()que faz a seguinte verificação explicitamente:

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

1

Porque uma string começa bem com "nada".


1
... isto se string.empty não for nada! Esta simplificação excessiva não pode ser generalizada. Sugiro que sigamos as discussões mais orientadas para a teoria do conjunto.
Pita.O

1

Se você pensar nisso em termos de expressões regulares, faz sentido. Cada string (não apenas "abcd", também "" e "sdf \ nff"), retorna verdadeiro ao avaliar a expressão regular de 'começa com string vazia'.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.