Когда следует поощрять слабые типы?

Когда следует поощрять слабые типы? Слабые типы не поощряются в больших проектах? Если левая сторона строго напечатана, как показано ниже, будет ли это исключением из правила?

   int i = 5
   string sz = i
   sz = sz + "1"
   i  = sz

Поддерживает ли какой-либо язык синтаксис, аналогичный приведенному выше? Расскажите мне больше о плюсах и минусах слабых типов и связанных ситуаций.

7 ответов

Решение

Я думаю, что вы путаете "слабую типизацию" с "динамической типизацией".

Термин "слабая типизация" означает "не строго типизированный", что означает, что значение ячейки памяти может отличаться от того, что указывает ее тип.

C является примером слабо типизированного языка. Это позволяет писать код, подобный этому:

typedef struct
{
    int x;
    int y;

} FooBar;

FooBar foo;
char * pStr = &foo;
pStr[0] = 'H';
pStr[1] = 'i';
pStr[2] = '\0';

То есть он позволяет обрабатывать экземпляр FooBar, как если бы он был массивом символов.

На строго типизированном языке это не допускается. Либо будет сгенерирована ошибка компилятора, либо будет сгенерировано исключение во время выполнения, но никогда в любой момент адрес памяти FooBar не будет содержать данные, которые не являются допустимыми FooBar.

C#, Java, Lisp, Java Script и Ruby являются примерами языков, в которых подобные вещи запрещены. Они сильно напечатаны.

Некоторые из этих языков "статически типизированы", что означает, что типы переменных назначаются во время компиляции, а некоторые "динамически типизированы", что означает, что типы переменных не известны до времени выполнения. "Статический против динамического" и "Слабый против сильного" являются ортогональными вопросами. Например, Лисп - это "сильный динамически типизированный" язык, тогда как "C" - это "слабый статически типизированный язык".

Также, как отмечали другие, существует различие между "выведенными типами" и типами, указанными программистом. Ключевое слово "var" в C# является примером вывода типа. Тем не менее, это все еще статически типизированная конструкция, потому что компилятор определяет тип переменной во время компиляции, а не во время выполнения.

Итак, на самом деле ваш вопрос:

Каковы относительные достоинства и недостатки статической типизации, динамической типизации, слабой типизации, строгой типизации, предполагаемых статических типов и пользовательских статических типов.

Я даю ответы на все эти вопросы ниже:

Статическая печать

Статическая типизация имеет 3 основных преимущества:

  1. Лучшая поддержка инструментов
  2. Уменьшенный вероятный капот некоторых типов ошибок
  3. Спектакль

Пользовательский опыт и точность таких вещей, как интеллектуальность и рефакторинг, значительно улучшены в языке со статической типизацией благодаря дополнительной информации, которую предоставляют статические типы. Если вы введете "а". в редакторе кода "a" имеет статический тип, тогда компилятор знает все, что может легально появиться после "." и, таким образом, может показать вам точный список завершения. Можно поддерживать некоторые сценарии на динамически типизированном языке, но они намного более ограничены.

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

Второе преимущество несколько спорно. Сторонники статически типизированных языков любят делать такие заявления. Противники статически типизированных языков, однако, утверждают, что обнаруженные ими ошибки тривиальны и что они все равно будут обнаружены при тестировании. Но вы получаете уведомление о таких вещах, как неправильно написанные переменные или имена методов, что может быть полезно.

Языки со статической типизацией также обеспечивают лучший "анализ потока данных", который в сочетании с такими вещами, как Microsoft SAL (или аналогичными инструментами), может помочь обнаружить потенциальные проблемы безопасности.

Наконец, со статической типизацией компиляторы могут выполнять гораздо больше оптимизации и, следовательно, могут создавать более быстрый код.

Недостатки:

Основным недостатком статической типизации является то, что она ограничивает то, что вы можете делать. Вы можете писать программы на динамически типизированных языках, которые вы не можете писать на статически типизированных языках. Ruby on Rails является хорошим примером этого.

Динамический набор текста

Большим преимуществом динамической типизации является то, что она намного мощнее, чем статическая. Вы можете сделать много действительно крутых вещей с этим.

Еще один, это требует меньше печатать. Вам не нужно указывать типы повсюду.

Недостатки:

Динамическая типизация имеет 2 основных недостатка:

  1. Вы не получаете столько "удержания руки" от компилятора или IDE
  2. Это не подходит для критических сценариев производительности. Например, никто не пишет ядра ОС в Ruby.

Строгая типизация:

Самым большим преимуществом строгой типизации является безопасность. Обеспечение строгой типизации обычно требует некоторой поддержки во время выполнения. Если программа может доказать безопасность типов, то многие проблемы безопасности, такие как переполнение буфера, просто исчезнут.

Слабый набор текста:

Большим недостатком сильной типизации и большим преимуществом слабой типизации является производительность.

Когда вы можете получить доступ к памяти любым удобным вам способом, вы можете написать более быстрый код. Например, база данных может выгружать объекты на диск, просто записывая их необработанные байты и не прибегая к таким вещам, как "ISerializable" интерфейсы. Видеоигра может отбросить все данные, связанные с одним уровнем, просто запустив один свободный на большом буфере, вместо того, чтобы запускать деструкторы для многих маленьких объектов.

Возможность делать такие вещи требует слабой типизации.

Тип вывода

Вывод типа дает много преимуществ статической типизации, не требуя так много типизации.

Пользовательские типы

Некоторым людям просто не нравится вывод типов, потому что им нравится быть явными. Это больше похоже на стиль.

Слабая типизация - это попытка упрощения языка. Хотя это достойная цель, слабая типизация - плохое решение.

Слабая типизация, такая как используется в COM Variants, была ранней попыткой решить эту проблему, но это чревато опасностями и, честно говоря, вызывает больше проблем, чем оно того стоит. Даже программисты на Visual Basic, которые будут мириться со всякой ерундой, правильно расценили это как плохую идею и сделали обратное преобразование ETC (Extended Type Conversion) от Microsoft в Evil Type Cast.

Не путайте выводимую типизацию со слабой типизацией. Предполагаемая типизация - это строгая типизация, выведенная из контекста во время компиляции. Хорошим примером является var ключевое слово, используемое в C# для объявления переменной, подходящей для получения значения выражения LINQ.

Напротив, слабая типизация выводится каждый раз, когда вычисляется выражение. Это показано в примере кода вопроса. Другим примером может быть использование нетипизированных указателей на C. Очень удобно, но все же просит о неприятностях.

Предполагаемая типизация решает ту же проблему, что и слабая типизация, без введения проблем, связанных со слабой типизацией. Поэтому он является предпочтительной альтернативой, когда язык хоста делает его доступным

"

Когда следует поощрять слабые типы? Слабые типы не поощряются в больших проектах? Если левая сторона строго напечатана, как показано ниже, будет ли это исключением из правила?

int i = 5 string sz = i sz = sz + "1" i = sz

Поддерживает ли какой-либо язык синтаксис, аналогичный приведенному выше? Расскажите мне больше о плюсах и минусах слабых типов и связанных ситуаций.

"

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

В C++ вы можете использовать нечто, называемое "перегрузка оператора", что означает, что вы можете объявить переменную одного типа для инициализации как переменную другого типа. Вот что делает заявление:

[std::string str = "Hello World";][1]

в частности, вы бы определили функцию (где тип переменной - T, а B - это тип, который вы хотите установить как)

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

T& T::operator= ( const B s );

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

B& T::operator= ( const T s);

C++ достаточно мощный, чтобы позволить вам сделать объект, как правило, слабо типизированным, но если вы хотите рассматривать его как чисто слабо типизированный, вы захотите создать только один тип переменной, который можно использовать в качестве любого примитива, и использовать только функции, которые принимают указатель на пустоту. Поверьте мне, гораздо проще использовать строго типизированное программирование, когда оно доступно.

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

Что касается плюсов слабо типизированных, вы можете захотеть привыкнуть к слабо типизированному программированию, если вы программируете что-то для запуска в программе (например, веб-браузер или оболочка UNIX). JavaScript и Shell Script слабо типизированы.

Я бы предположил, что такой язык программирования, как ассемблер, является одним из немногих слаботипизированных языков уровня аппаратного обеспечения, но вид языка ассемблера, который я видел, прикрепляет тип к каждой переменной в зависимости от назначенного размера, то есть word, dword, qword,

Надеюсь, я дал вам хорошее объяснение и не вставил ни слова в ваш рот.

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

И чтобы ответить на ваш вопрос, C поддерживает такой код (за исключением, разумеется, отсутствия строкового типа), и это звучит так, как если бы PHP или Perl имели (но я могу быть совершенно неправ в этом).

Слабые типы по своей природе менее устойчивы, чем сильные, потому что вы не указываете машине точно, что делать - вместо этого машина должна понять, что вы имели в виду. Это часто работает вполне адекватно, но в целом не ясно, каким должен быть результат. Что такое, например, строка, умноженная на число с плавающей точкой?

Поддерживает ли какой-либо язык синтаксис, аналогичный приведенному выше?

Perl позволяет обрабатывать некоторые числа и строки взаимозаменяемо. Например, "5" + "1" даст вам 6. Проблема с такими вещами в целом заключается в том, что может быть трудно избежать двусмысленности: должно ли "5" + 1 быть "51" или "6"? Perl справляется с этим, имея отдельный оператор для конкатенации строк и резервируя + для сложения чисел.

Другие языки должны были бы разобраться, хотите ли вы сделать конкатенацию или сложение, и (если это уместно), какого типа или представления будет результат.

Я сделал кодирование ASP/VBScript и работал с унаследованным кодом без "строгой опции", которая допускает слабую типизацию.

Во многих случаях это был ад, особенно в руках менее опытных программистов. Мы получили все глупые ошибки, чтобы диагностировать целую вечность.

Один из глупых примеров был такой:

'Config 
    Dim pass
    pass = "asdasd"


If NOT pass = Request("p") Then
Response.Write "login failed"
REsponse.End()
End If

Пока все хорошо, но если пользователь меняет пароль на целочисленный пароль, угадайте, что он больше не будет работать, потому что int pass!= String pass (из строки запроса). Я думал, что это должно работать, но это не так, я не могу вспомнить точную часть кода.

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

Проще говоря, по моему опыту, особенно в больших проектах и ​​особенно с неопытными разработчиками, это просто проблема.

Другие вопросы по тегам