Дайка печатается, должно быть, она динамична?
Википедия говорила * о утка-типизация:
В компьютерном программировании с объектно-ориентированные языки программирования, утиная типизация - стиль динамического ввод, в котором текущий объект набор методов и свойств определяет действительную семантику, а чем его наследование от конкретного класса или реализации конкретного интерфейс.
(* Примечание: Поскольку этот вопрос был опубликован, статья Википедии была отредактирована для удаления слова "динамический".)
В нем описывается структурная типизация:
Система структурного типа (или основанная на собственности система) является основным класс типа системы, в котором тип совместимость и эквивалентность определяется структурой типа, а не через явные декларации.
Это контрастирует структурный подтипирование с утиным типом:
[Структурные системы] контрастирует с... утка, в которой только часть структуры, доступ к которой время выполнения проверяется на совместимость.
Однако термин "утка-типизация" мне кажется, по крайней мере, для интуитивного подбора структурных систем подпечатывания. Фактически Wikipedia говорит:
Название понятия [утка-типизация] ссылается на утиный тест, приписываемый Джеймс Уиткомб Райли, который может быть сформулирован как следует: "Когда я вижу птицу, которая ходит как утка, и плавает, как утка и кляки, как утка, я называю эту птицу утка".
Итак, мой вопрос: почему я не могу назвать структурный подтипирование утиной печати? Существуют ли даже динамически типизированные языки, которые также нельзя отнести к типу?
Постскриптум:
Как кто-то назвал daydreamdrunk на reddit.com, поэтому красноречиво положить-это "Если он компилируется как утка и ссылки, как утка..."
Пост-постскриптум
Многие ответы, похоже, в основном просто перефразируют то, что я уже цитировал здесь, не обращаясь к более глубокому вопросу, поэтому не следует использовать термин "утиная печать" для покрытия как динамического набора текста, так и структурного подтипа? Если вы хотите только поговорить о наборе утиных, а не о структурном подтипе, просто назовите его: динамический поиск элементов. Моя проблема в том, что ничего не говорит о термине duck-typing, это относится только к динамическим языкам.
Ответы
Ответ 1
С++ и D-шаблоны - прекрасный пример утиного набора текста, который не является динамическим. Это определенно:
в котором объект текущий набор методов и свойства определяет действительный семантика, а не ее наследование из определенного класса или реализации конкретных интерфейс.
Вы явно не указываете интерфейс, который должен наследовать ваш тип, чтобы создать экземпляр шаблона. Он просто должен иметь все функции, которые используются в определении шаблона. Тем не менее, все решается во время компиляции и сводится к необработанным шестнадцатеричным числам. Я называю это "компиляция времени утка". Я написал целые библиотеки из этого мышления, что неявное создание шаблона - это компиляция времени утиного ввода текста и думаю, что это одна из самых недооцененных функций.
Ответ 2
Система структурного типа
Система структурного типа сравнивает один полный тип с другим целым типом, чтобы определить, совместимы ли они. Для совместимости двух типов A
и B
A
и B
должны иметь одинаковую структуру, то есть каждый метод на A
и на B
должен иметь одну и ту же подпись.
Duck Typing
Утиная печать считает, что два типа эквивалентны для задачи, если они могут обрабатывать эту задачу. Для двух типов A
и B
эквивалентны фрагменту кода, который хочет записать в файл, A
и B
оба должны реализовать метод записи.
Резюме
Системы структурного типа сравнивают каждую сигнатуру метода (целая структура). Утка набирает сравнение методов, относящихся к конкретной задаче (структура, относящаяся к задаче).
Ответ 3
Утиная печать означает Если она просто подходит, она ОК
Это относится как к динамически типизированному
def foo obj
obj.quak()
end
или статически типизированные, скомпилированные языки
template <typename T>
void foo(T& obj) {
obj.quak();
}
Дело в том, что в обоих примерах информация о типе не указана. Просто при использовании (во время выполнения или времени компиляции!) Типы проверяются, и если все требования выполняются, код работает. Значения не имеют явного типа в момент объявления.
Структурная типизация основывается на явно набрав ваши значения, как обычно. Разница только в том, что конкретный тип не идентифицируется по наследованию, а по его структуре.
Структурно типизированный код (Scala -стиль) для приведенного выше примера будет
def foo(obj : { def quak() : Unit }) {
obj.quak()
}
Не путайте это с тем, что некоторые структурно типизированные языки, такие как OCaml, объединяют это с выводом типа, чтобы мы не могли явно определять типы.
Ответ 4
Я не уверен, действительно ли он отвечает на ваш вопрос, но...
Шаблонный код на С++ очень похож на утиную печать, но является статическим, время компиляции, структурное.
template<typename T>
struct Test
{
void op(T& t)
{
t.set(t.get() + t.alpha() - t.omega(t, t.inverse()));
}
};
Ответ 5
Я понимаю, что структурная типизация используется указателями типа и т.п. для определения информации о типе (думаю, Haskell или OCaml), в то время как утиная типизация не заботится о "типах" как таковой, просто то, что вещь может обрабатывать конкретную метод invocation/доступ к свойствам и т.д. (подумайте respond_to?
в Ruby или проверяйте возможности в Javascript).
Ответ 6
Всегда есть примеры из некоторых языков программирования, которые нарушают некоторые определения различных терминов. Например, ActionScript поддерживает выполнение программирования стиля утиного ввода в случаях, которые не являются технически динамическими.
var x:Object = new SomeClass();
if ("begin" in x) {
x.begin();
}
В этом случае мы протестировали, если экземпляр объекта в "x" имеет метод "начать" перед вызовом его вместо использования интерфейса. Это работает в ActionScript и в значительной степени печатается утки, хотя класс SomeClass() не может быть динамическим.
Ответ 7
Существуют ситуации, когда динамическая утиная печать и аналогичный статический код (например, С++) ведут себя по-другому:
template <typename T>
void foo(T& obj) {
if(obj.isAlive()) {
obj.quak();
}
}
В С++ объект должен иметь методы isAlive
и quak
для компиляции кода; для эквивалентного кода в динамически типизированных языках, объект должен иметь метод quak
, если isAlive()
возвращает true. Я интерпретирую это как различие между структурой (структурной типизацией) и поведением (утиная печать).
(Тем не менее, я дошел до этой интерпретации, взяв Википедию "утиная печать должна быть динамичной" по номинальной стоимости и пытаться сделать ее понятной. Альтернативная интерпретация, которая подразумевает структурную типизацию, - это утка, набирающая текст также является когерентной.)
Ответ 8
Я вижу "утиную типизацию" больше как стиль программирования, тогда как "структурная типизация" - это системная функция типа.
Структурная типизация относится к способности системы типов выражать типы, которые включают все значения, которые имеют определенные структурные свойства.
Утиная печать относится к написанию кода, который просто использует функции передаваемых им значений, которые действительно необходимы для работы под рукой, без наложения каких-либо других ограничений.
Поэтому я мог бы использовать структурные типы для кодирования в стиле утиной печати, формально объявляя мои "типы уток" структурными. Но я мог бы также использовать структурные типы, не "делая утиную печать". Например, если я пишу интерфейсы к набору связанных функций/методов/процедур/предикатов/классов/независимо, объявляя и называя общий структурный тип, а затем используя это везде, очень вероятно, что некоторые из блоков кода не нужны все особенности структурного типа, и поэтому я излишне ограничил некоторые из них, чтобы отклонить значения, на которых они теоретически могли бы корректно работать.
Итак, пока я вижу, как существует общая точка зрения, я не думаю, что утиная печать вводит структурную типизацию. То, как я думаю о них, печатание утки - это даже не то, что могло бы привести к структурной типизации, потому что это не то же самое. Думая о том, что утка набирает динамические языки как "неявные, неконтролируемые структурные типы", что-то не хватает, ИМХО. Duck typing - это стиль кодирования, который вы предпочитаете использовать или нет, а не только техническую особенность языка программирования.
Например, можно использовать isinstance
проверки в Python для подделки типов типа "класс-подкласс" типа OO. Также можно проверить определенные атрибуты и методы, подделать структурные ограничения типа (вы даже можете поместить проверки во внешнюю функцию, тем самым эффективно получив именованный структурный тип!). Я бы сказал, что ни один из этих вариантов не является примером утиного набора текста (если структурные типы не очень мелкие и не находятся в тесной синхронизации с проверкой кода для них).