Не допускающие NULL-значения ссылочные типы

Спасибо, Даг, за то, что удостоил мой вопрос честным комментарием.

batch.update (sfRef, {регионов: firebase.firestore.FieldValue.arrayUnion ("great_virginia")});

12
задан Zifre 28 March 2009 в 19:09
поделиться

6 ответов

Мои текущие языковые принципы проектирования - то, что nullability должен быть чем-то, что программиста вынуждают попросить, не дают по умолчанию на ссылочных типах (в этом, я соглашаюсь с Tony Hoare - Google для его недавнего разговора о QCon).

На этом определенном примере, с unnullable b2, это даже не прошло бы статические проверки: консервативный анализ не может гарантировать, что b2 не является ПУСТЫМ, таким образом, программа не семантически значима.

Мой идеал достаточно прост. Ссылки являются косвенным дескриптором к некоторому ресурсу, который мы можем пересечь для получения доступа к тому ресурсу. Ссылки Nullable являются или косвенным дескриптором к ресурсу или уведомлением, что ресурс не доступен, и каждый никогда не не уверен честный, какая семантика используются. Это дает любому множество проверок впереди (Действительно ли это является пустым? Нет? Yay!), или неизбежный NPE (или эквивалентный). Большинство ресурсов программирования является, в эти дни, не в широком масштабе ресурсом, ограниченным или связанным к некоторой конечной базовой модели - нулевые ссылки являются, упрощенно, одним из...

  • Лень: "Я просто закупорю пустой указатель в здесь". С которым откровенно говоря, у меня нет слишком большого согласия
  • Беспорядок: "Я не знаю, что вставить здесь все же". Обычно также наследие более старых языков, где необходимо было объявить имена ресурса перед знанием, каковы ресурсы были.
  • Ошибки: "Это пошло не так, как надо, вот ПУСТОЙ УКАЗАТЕЛЬ". Лучшие механизмы сообщения об ошибке таким образом важны на языке
  • Дыра: "Я знаю, что буду скоро иметь что-то, дам мне заполнителя". Это имеет больше заслуги, и мы можем думать о способах сражаться с этим.

Конечно, решение каждого из случаев, которые обслуживает ПУСТОЙ ток с лучшим лингвистическим выбором, не является никаким маленьким подвигом и может добавить больше беспорядка, которому это помогает. Мы можем всегда переходить к неизменным ресурсам, так ПУСТОЙ УКАЗАТЕЛЬ в, он - только полезные состояния (ошибка, и дыра) не много реального использования. Императив technqiues устанавливается, хотя, и я откровенно рад - это делает поиск лучших решений в этом пространстве стоящим.

16
ответ дан 2 December 2019 в 03:49
поделиться

Наличие ссылочных типов быть не допускающим NULL-значения по умолчанию является единственным разумным выбором. Мы заполоняемся языками и временем выполнения, которое завинтило это; необходимо сделать Правильную Вещь.

11
ответ дан 2 December 2019 в 03:49
поделиться

Эта функция была в Spec#. Они приняли значение по умолчанию к nullable ссылкам и использовали! указать на non-nullables. Это было то, потому что они хотели обратную совместимость.

На моем языке мечты (которых я, вероятно, был бы единственным пользователем!) я сделал бы тот же выбор как Вы, не допускающий NULL-значения по умолчанию.

Я также сделал бы это недопустимым для использования. оператор на nullable ссылке (или что-либо еще, что разыменовало бы его). Как Вы использовали бы их? Необходимо было бы преобразовать их в non-nullables сначала. Как Вы сделали бы это? Путем тестирования их на пустой указатель.

В Java и C#, if оператор может только принять a bool проверяемое выражение. Я расширил бы его для принятия названия nullable ссылочной переменной:

if (myObj)
{
    // in this scope, myObj is non-nullable, so can be used
}

Этот специальный синтаксис был бы неудивителен программистам C/C++. Я предпочел бы, чтобы специальный синтаксис как это прояснил, что мы делаем проверку, которая изменяет тип имени myObj в рамках ответвления истины.

Я добавил бы дальнейший бит сахара:

if (SomeMethodReturningANullable() into anotherObj)
{
    // anotherObj is non-nullable, so can be used
}

Это просто дает имя anotherObj к результату выражения слева от into, таким образом, это может использоваться в объеме, где это допустимо.

Я сделал бы тот же вид вещи для ?: оператор.

string message = GetMessage() into m ? m : "No message available"; 

Отметьте это string message является не допускающим NULL-значения, но так два возможных результата теста выше, таким образом, присвоение является значением.

И затем возможно, немного сахара для, по-видимому, общего падежа заменения значением для пустого указателя:

string message = GetMessage() or "No message available";

Очевидно, or был бы только законно применен к nullable типу на левой стороне и не допускающему NULL-значения на правой стороне.

(У меня также было бы встроенное понятие владения, например, полями; компилятор генерировал бы IDisposable.Dispose метод автоматически, и ~Destructor синтаксис использовался бы для увеличения Dispose, точно как в C++ / CLI.)

Spec# имел другое синтаксическое расширение, связанное с non-nullables, из-за проблемы обеспечения, что non-nullables был инициализирован правильно во время конструкции:

class SpecSharpExampleClass
{
    private string! _nonNullableExampleField;

    public SpecSharpExampleClass(string s)
        : _nonNullableExampleField(s) 
    {

    }
}

Другими словами, необходимо инициализировать поля таким же образом, как Вы вызвали бы других конструкторов с base или this - если, конечно, Вы не инициализируете их непосредственно рядом с объявлением поля.

9
ответ дан 2 December 2019 в 03:49
поделиться

Взгляните на предложение по оператору Elvis по Java 7. Это делает что-то подобное, в котором это инкапсулирует пустую проверку и отправку метода в одном операторе с указанным возвращаемым значением, если объект является несуществующим. Следовательно:

String s = mayBeNull?.toString() ?: "null";

проверки, если Строка s является пустой, и возвращает строку "пустой указатель" и значение строки если нет. Пища для размышления, возможно.

4
ответ дан 2 December 2019 в 03:49
поделиться

Несколько примеров подобных функций на других языках:

Существует также Nullable<T> (от C#), но это не такой хороший пример из-за другого отношения ссылки по сравнению с типами значения.

В Вашем примере Вы могли добавить, что условное сообщение отправляет оператор, например.

b?->DoSomething();

Отправить сообщение в b только если это является непустым.

3
ответ дан 2 December 2019 в 03:49
поделиться

Я думаю, что нулевые значения хороши: Они - ясный признак, что Вы сделали что-то не так. Если Вы не инициализируете ссылку где-нибудь, то Вы получите непосредственное уведомление.

Альтернатива была бы то, что значения иногда инициализируются к значению по умолчанию. Логические ошибки затем намного более трудно обнаружить, если Вы не помещаете логику обнаружения в те значения по умолчанию. Это совпало бы только с получением исключения нулевого указателя.

-3
ответ дан 2 December 2019 в 03:49
поделиться
Другие вопросы по тегам:

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