Почему делает! 1 ничего не дают мне в Perl?

В то время как различие очень, Очень мало, различие все еще существуют.

1) "" создает объект в то время как Строка. Пустой не делает. Но этот объект будет создан однажды и будет сослан от строкового пула позже, если у Вас будет другой "" в коде.

2) Строка и строка являются тем же, но я рекомендовал бы использовать Строку. Пустой (а также Строка. Формат, Строка. Копия и т.д.), так как запись через точку указывает на класс, не оператор, и класс наличия, запускающийся с прописной буквы, соответствует стандартам кодирования C#.

18
задан brian d foy 16 July 2009 в 19:49
поделиться

5 ответов

Будьте осторожны: то, что вы написали, не делает того, что вы думаете. Помните, что у perl нет реального логического типа данных. В нем есть скаляры, хэши, списки и ссылки. Таким образом, способ обработки истинных / ложных значений зависит от контекста. В perl все оценивается как «истина», за исключением неопределенных переменных, пустого списка, пустой строки и числа 0.

То, что делает ваш код, принимает значение, обратное значению, которое оценивается как «ложь». , который может быть любым, чего нет в списке выше. По соглашению и для простоты perl возвращает 1 (хотя вы не должны на это полагаться; он вполне может вернуть список, содержащий серию случайных чисел, потому что он также будет оцениваться как «истина». )

Аналогичная вещь происходит, когда вы запрашиваете инверсию значения, которое оценивается как «истина». На самом деле печатается не «ничего», а пустая строка (''), которая, как я уже упоминал, в логических выражениях принимает значение «ложь». Вы можете проверить это:

print "This evaluates to false\n" if( (!1) eq '');

Если вы спрашиваете, почему perl выдает пустую строку вместо одного из других «ложных» значений, то, вероятно, потому, что perl создан для обработки строк, и это вполне разумная строка для рука назад.

41
ответ дан 30 November 2019 в 05:59
поделиться

операторы, которые возвращают только логический результат, всегда будут возвращать 1 для истины и специальное значение false, которое "" в строковом контексте, но 0 в числовом контексте.

9
ответ дан 30 November 2019 в 05:59
поделиться

Оператор ! выполняет логические операции. "" (Пустая строка) является таким же ложным , как 0 . 1 - удобное истинное значение. ! не следует полагаться ни на что иное, кроме получения некоторого истинного / ложного значения. Опасно полагаться на точное значение сверх этого, и оно может меняться в зависимости от версии Perl.

3
ответ дан 30 November 2019 в 05:59
поделиться

См. perldoc perlsyn :

Истина и ложь

Число 0, строки «0» и «», пустой список () и undef все false в логическом контексте. Все остальные ценности верны. Отрицание истинного значение по! или не возвращает специальный ложное значение. При оценке как строка рассматривается как '', но как число, оно обрабатывается как 0.

Там, если вы напечатаете значение как число, вы получите 0 вместо пустой строки:

printf "%d\n", $_ for map { !$_ } (1, 0);

или

print 0 + $_, "\n" for map { !$_ } (1, 0);

Сравните их с

printf "%s\n", $_ for map { !$_ } (1, 0);

] и

print $_, "\n" for map { !$_ } (1, 0);
3
ответ дан 30 November 2019 в 05:59
поделиться

Вот дополнение к другим отличным ответам, которые вы уже получили.

Not is Not Not

Рассмотрим следующий код, который проверяет каждый из операторов Perl «not»:

#!/usr/bin/perl

use strict;
use warnings;

for( '!1', 'not 1', '~0' ) {
    my $value = eval;
    my $zero_plus = 0 + $value;

    print join "\n", 
        "\nExpression: $_",
        "Value:     '$value'",
        "Defined:   " . defined $value,
        "Length:    " . length($value),
        "Plus:      " . +$value,
        "Plus Zero: '$zero_plus'",
        '';
}

print "\nTest addition for a literal null string:  ";
print 0+'', "\n";

use Scalar::Util qw(dualvar);

{   # Test a dualvar 
    my $value = dualvar 0, '';
    my $zero_plus = 0+$value;

    print join "\n", 
        "\nExpression: dualvar",
        "Value:     '$value'",
        "Defined:   " . defined $value,
        "Length:    " . length($value),
        "Plus:      " . +$value,
        "Plus Zero: '$zero_plus'",
        '';

}

Его выполнение приводит к следующему. Обратите внимание на предупреждающее сообщение:

Argument "" isn't numeric in addition (+) at test.pl line 21.

Expression: !1
Value:     ''
Defined:   1
Length:    0
Plus:
Plus Zero: '0'

Expression: not 1
Value:     ''
Defined:   1
Length:    0
Plus:
Plus Zero: '0'

Expression: ~0
Value:     '4294967295'
Defined:   1
Length:    10
Plus:      4294967295
Plus Zero: '4294967295'

Test addition for a literal null string:  0

Expression: dualvar
Value:     ''
Defined:   1
Length:    0
Plus:
Plus Zero: '0'

Из этого мы узнаем несколько вещей.

Первые два элемента не так уж интересны:

  • ! 1 и not 1 ведут себя в основном одинаково.
  • Неудивительно, что ~ 1 отличается (не поразрядно).

Теперь интересный пункт:

  • Пока мы получаем предупреждение для строки 21 ( 0+ ' '), при добавлении 0+! 1 предупреждений не возникает.

Для запутывания нужны двое

Происходит что-то подозрительное, и эта подозрительность связана со специальными скалярными контекстами в Perl. В этом случае различие между числовым и строковым контекстами. И возможность создать переменную, которая имеет разные значения в каждом контексте, также известную как двойная переменная.

Похоже, ! 1 возвращает двойную переменную, которая возвращает 0 в числовом контексте и пустую строку в строке контекст.

Тест на двойную переменную в конце показывает, что самодельная двойная переменная работает так же, как ! 1 .

Но это хорошая вещь

Как и многие функции Perl, двойные переменные на первый взгляд кажутся бросать вызов ожиданиям и сбивать с толку. Однако, как и эти другие функции, при правильном использовании они значительно облегчают жизнь.

Насколько мне известно, двойная переменная 0 и ». - единственное определенное значение, которое вернет ложь во всех скалярных контекстах. Так что это очень разумное возвращаемое значение для ! 1 . Можно возразить, что undef - хороший ложный результат, но тогда неинициализированная переменная не отличима от ложного значения. Кроме того, попытки распечатать или добавить результаты логических значений будут сопровождаться ненужными предупреждениями.

Еще одна известная двойная переменная - $! или $ OS_ERROR , если вы используете английский язык . В числовой форме вы получаете код ошибки, в строковой форме код ошибки переводится для вас.

Это не ничего, это пусто, но это ничего

Таким образом, вы ничего не получаете, вы не получают пустую строку, и вы не получаете ноль.

6
ответ дан 30 November 2019 в 05:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: