Когда следует поощрять слабые типы? - PullRequest
3 голосов
/ 28 февраля 2009

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

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

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

Ответы [ 7 ]

16 голосов
/ 08 марта 2009

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

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

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. A Уменьшена вероятность появления некоторых типов ошибок
  3. Производительность

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

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

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

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

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

Недостатки:

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

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

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

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

Недостатки:

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

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

Сильный набор:

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

Слабый набор:

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

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

Для того, чтобы делать такие вещи, требуется слабая печать.

Тип вывода

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

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

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

3 голосов
/ 28 февраля 2009

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

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

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

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

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

2 голосов
/ 06 марта 2012

"

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

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 ++ достаточно мощный, чтобы позволить вам сделать объект, как правило, слабо типизированным, но если вы хотите рассматривать его как чисто слабо типизированный, вы захотите создать только один тип переменной, который можно использовать как любой примитив, и использовать только функции, которые принимают указатель на void. Поверьте, гораздо проще использовать строго типизированное программирование, когда оно доступно.

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

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

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

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

2 голосов
/ 08 марта 2009

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

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

1 голос
/ 08 марта 2009

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

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

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

1 голос
/ 28 февраля 2009

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

0 голосов
/ 28 февраля 2009

Я выполнил кодирование 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 (из строки запроса). Я думал, что это должно работать, но это не Я не могу вспомнить точную часть кода .

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

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

...