Почему nodejs допускает эту, казалось бы, недопустимую последовательность символов? - PullRequest
0 голосов
/ 22 апреля 2020

Я искал, есть ли способ отличить guish между возвратом в файл (следующая строка) и типизированной новой строкой (\ n в файле). Пока я играл в REPL, я сделал опечатку в сравнении, и, к моему удивлению, ноду было все равно. Это даже дало то, что я считаю неопределенным поведением, если только я полностью не пропустил что-то в мои годы близости узлов. И я также обнаружил несколько других вещей в моей игре, я спрошу об этом ниже.

Код находится внизу поста.

Основной вопрос:

Почему Node.js не жалуется на синтаксис в двух последних сравнениях (== + и == -)? Это где-то правильный синтаксис где-то? И почему это делает сравнение истинным, когда без конечного +/- оно ложно? (обновления в комментариях к записи)

Главный вопрос:

Почему результаты «Самостоятельное сравнение по буферу» и «Сравнение по буферу» оказываются ложными, если все остальные тесты верны ? И почему буфер не сравнивается с буфером тех же данных?

Также:

Если кто-нибудь знает, как надежно различить guish между возвратом в файл и набрал символ новой строки, как описано выше, я был бы очень признателен за эту мудрость.

Спасибо всем

Вот код:


const nl = '\n'
const newline = `
`

const NL = Buffer.from('\n')
const NEWLINE = Buffer.from(`
`)
const NEWLINE2 = Buffer.from(`
`)
console.log("Buffer separate self comparison: "+(NEWLINE2 == NEWLINE))
console.log("Buffer comparison: "+(NL == NEWLINE))
console.log("Non buffer comparison: "+(nl == newline))
console.log("Buffer self comparison 1: "+(NL == NL))
console.log("Buffer self comparison 2: "+(NEWLINE == NEWLINE))
console.log("Buffer/String comparison 1: "+(nl == NL))
console.log("Buffer/String comparison 2: "+(newline == NEWLINE))
console.log("Buffer/String cross comparison 1: "+(nl == NEWLINE))
console.log("Buffer/String cross comparison 2: "+(newline == NL))
console.log("Buffer toString comparison: "+(NL.toString() == NEWLINE.toString()))
console.log("Strange operator comparison 1: "+(NL ==+ NEWLINE))
console.log("Strange operator comparison 2: "+(NL ==- NEWLINE))

1 Ответ

1 голос
/ 22 апреля 2020
NEWLINE2 == NEWLINE (false)
NL == NEWLINE (false)

Выражение, сравнивающее Объекты, истинно, только если операнды ссылаются на один и тот же Объект. ср c

Это не так: это два отдельных объекта, даже если их начальные значения одинаковы, поэтому результат равен false.

Редактировать: Если вы хотите сравнить значения , а не идентификатор двух буферов, вы можете использовать Buffer.compare . Buffer.compare(NEWLINE2, NEWLINE) === 0 означает, что оба они равны.

nl == newline (true)

Две строки строго равны, если они имеют одинаковую последовательность символов, одинаковую длину и одинаковые символы в соответствующих позициях. sr c

Строки равны, поэтому true.

NL == NL (true)
NEWLINE == NEWLINE (true)

Выражение, сравнивающее Objects, истинно, только если операнды ссылаются на один и тот же объект. ср c

nl == NL (true)
newline == NEWLINE (true)
nl == NEWLINE (true)
newline == NL (true)

Здесь происходит сравнение двух разных типов. Один - строка, другой - объект.

Каждый из этих операторов будет приводить свои операнды к примитивам перед выполнением сравнения. Если оба заканчиваются как строки, они сравниваются с использованием лексикографического порядка c, в противном случае они приводятся к числам для сравнения. Сравнение с NaN всегда даст ложь. sr c

Buffer имеет метод toString, поэтому он вызывается для того, чтобы иметь одинаковые примитивные типы с обеих сторон ==. Результатом этого метода является строка, содержащая \n. '\n' == '\n' равно true.

В качестве отступления, если ваше сравнение было NEWLINE == 0, то это произойдет:

' 1 ' == 1 равно true. При приведении пробелов отбрасывается, поэтому ' 1 ' будет приведен к числу со значением 1. Результирующее сравнение будет 1 == 1.

Строка только из пробельных символов будет приведена к 0. Буфер сначала преобразуется в строку, а затем в целое число, так что это должно произойти: 0 == 0, поэтому результат будет true.

NL.toString() == NEWLINE.toString() (true)

Две строки строго равны, если они имеют одинаковую последовательность символов, одинаковую длину и одинаковые символы в соответствующих позициях. ср c

Строки равны, поэтому true.

NL ==+ NEWLINE (true)
NL ==- NEWLINE (true)

Это то же самое, что и == +NEWLINE. Вы используете унарный + или - для явного приведения к числу. Здесь интересно то, что вы делаете эти сравнения после приведения: 0 == +0 и 0 == -0. Отрицательный и положительный ноль считаются равными .

Ни одно из действий здесь не является «неопределенным».

Кроме «да, это здорово», на самом деле очень небольшая причина не использовать оператор строгого равенства (===), который бы не приводил вещи в одинаковые примитивы.


Что касается вашего вопроса:

Новая строка в файл (\n) совпадает с символом новой строки в самонабираемой строке ('\ n'). Они оба ASCII или Unicode-символ 0x0A, в байтовом выражении.

Некоторые документы содержат как символ новой строки, так и возврат каретки. Новая строка тогда состоит из двух символов: 0x0D 0x0A (или \r\n).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...