Почему «abcd» .StartsWith («») возвращает истину?


87

Заголовок - это весь вопрос. Может кто-нибудь назвать мне причину, по которой это происходит?

Ответы:


164

Да, потому что он начинается с пустой строки. Действительно, пустая строка логически встречается между каждой парой символов.

Скажите так: какое определение «начинается с» вы могли бы дать, чтобы это исключить? Вот простое определение слова «начинается с», которого нет:

«x начинается с y, если первые y.Lengthсимволы x совпадают с символами y».

Альтернативное (эквивалентное) определение:

"x начинается с y, если x.Substring(0, y.Length).Equals(y)"


3
x начинается с y, если x.Substring (0, y.Length) .Equals (y) тогда и только тогда, когда y.Length> 0
Винко Врсалович

8
Да, вы действительно можете явно исключить этот случай. Однако это довольно неэлегантное определение, не так ли?
Джон Скит

7
Правда. Это также требует, чтобы они не были равны нулю ... но я бы сказал, что оба из них добавляют точности, убирая дух простого определения :)
Джон Скит,

8
Между каждой парой символов встречается бесконечное количество экземпляров пустой строки.
Lotus Notes

3
Да, это как поставить ноль перед числом - это не меняет значения, но оно все еще существует.
pop850

47

Я постараюсь уточнить то, что сказал Джон Скит.

Допустим, x, y и z - строки, а оператор + - это фактически конкатенация, тогда:

Если мы можем разделить z, чтобы написать z = x + y, это означает, что z начинается с x. Поскольку каждую строку z можно разделить на z = "" + z, следует, что каждая строка начинается с "".

Итак, поскольку ("" + "abcd") == "abcd" следует, что "abcd" начинается с ""


17

Этот метод сравнивает параметр значения с подстрокой в ​​начале этой строки, имеющей ту же длину, что и значение, и возвращает значение, указывающее, равны ли они. Чтобы быть равным, значение должно быть пустой строкой (Empty), ссылкой на этот же экземпляр или соответствовать началу этого экземпляра.

.NET String.StartsWith

истина, если последовательность символов, представленная аргументом, является префиксом последовательности символов, представленной этой строкой; иначе ложь. Также обратите внимание, что true будет возвращено, если аргумент является пустой строкой или равен этому объекту String, как определено методом equals (Object).

Java String.startsWith


17

Я начну со связанного с этим факта, который легче понять.

Пустой набор - это подмножество каждого набора.

Зачем? Определение из подмножества состояний , что Aявляется подмножеством , Bесли каждый элемент Aявляется элементом B. И наоборот, Aне является подмножеством, Bесли есть элемент A, не являющийся элементом B.

Теперь закрепим набор B. Я установлю, что пустой набор является подмножеством B. Я сделаю это, показав, что это не тот случай, когда пустой набор не является подмножеством B. Если бы пустой набор не был подмножеством, Bя мог бы найти элемент пустого набора, которого нет B. Но в пустом наборе нет никаких элементов, и поэтому я не могу найти элемент, которого нет B. Следовательно, это не тот случай, когда пустой набор не является подмножеством B. Таким образом, пустой набор должен быть подмножеством B.

Любая строка начинается с пустой строки.

Во-первых, мы должны согласовать наше определение « начинается с» . Пусть sи tбудет strings Мы говорим, что s начинается с t if, s.Length >= t.Lengthи первые t.Lengthсимволы tсовпадают с символами s. То есть, 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.Length is equal to zero, there is noInt32 index satisfying0 <= index <String.Empty.Length. Следовательно

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;
}

Приведенные выше два факта, выделенные жирным шрифтом, являются примерами абсолютно истинных утверждений . Они верны в силу того факта, что определяющие их утверждения ( подмножество и начинаются с ) являются универсальными количественными характеристиками над пустыми вселенными. В пустом наборе нет элементов, поэтому не может быть никаких элементов пустого набора, которых нет в каком-либо другом фиксированном наборе. В пустой строке нет символов, поэтому не может быть символа в качестве некоторой позиции в пустой строке, не совпадающей с символом в той же позиции в какой-либо другой фиксированной строке.


13

Скажем так, "abcd".StartsWith("")возвращает false.

если да, то что означает следующее выражение eval, true или false:

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

оказывается, что ev принимает значение true, поэтому строка действительно начинается с пустой строки ;-), или, другими словами, подстрока «abcd», начинающаяся с позиции 0 и имеющая длину 0, равна пустой строке «». Довольно логично, imo.


Тот факт, что «abcd» .Substring (0, 0) возвращает пустую строку, не означает, что «abcd» фактически начинается с пустой строки. Результат также мог быть объявлен как «неопределенный», как nullи возвращаемое значение.
Tom Lint

@TomLint Нет. Обычно вы комбинируете условия IE x.FirstName.StartsWith (userEnteredFirstName) && x.LastName.StartsWith (userEnteredLastName) .... Это заставляет условие работать, даже если одно из введенных значений является пустой строкой.
Pop Catalin

7

В C # спецификация предписывает ему реагировать именно так;

Чтобы быть равным, значение должно быть пустой строкой (Empty), ссылкой на этот же экземпляр или соответствовать началу этого экземпляра.


5

Первые N символов двух строк идентичны. N - длина второй строки, т.е. ноль.


5

Почему «abcd» .StartsWith («») возвращает истину?

НАСТОЯЩИЙ ОТВЕТ:

Так должно быть, иначе у вас будет случай, когда

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

    but yet

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

и тогда у нас снова будет проблема 2000 года, потому что все банковское программное обеспечение, которое зависит от равных строк, начинающихся с самих себя, перепутает наши счета, и внезапно Билл Гейтс получит мое богатство, а я его, и черт возьми! Судьба для меня не такая уж добрая.


Я не согласен. "" .startsWith ("") должно быть равно true, потому что строки идентичны, а не из-за какой-то странной бизнес-логики.
Tom Lint

@TomLint Фактически, вы согласны с тезисом в ответе ...
neonblitzer

4

Просто для записи String.StartsWith()внутренне вызывает метод, System.Globalization.CultureInfo.IsPrefix()который явно выполняет следующую проверку:

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

1

Потому что строка хорошо начинается с «ничего».


1
... то есть, если string.empty ничего не значит! Это чрезмерное упрощение нельзя обобщать. Я предлагаю следовать дискуссиям, более ориентированным на теорию множеств.
Pita.O

1

Если вы думаете об этом в терминах регулярных выражений, это имеет смысл. Каждая строка (не только «abcd», но также «» и «sdf \ nff») возвращает истину при оценке регулярного выражения «начинается с пустой строки».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.