Вопрос

В Википедии обычно говорилось * о утиный набор текста:

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

(* Ред.примечание:С момента публикации этого вопроса статья в Википедии была отредактирована, чтобы удалить слово "динамический".)

В нем говорится о структурная типизация:

Структурная система типов (или система типов на основе свойств) является основным классом систем типов, в котором тип совместимость и эквивалентность определяются структурой типа, а не посредством явных объявлений.

Это противопоставляет структурное подтипирование утиному типизированию как таковому:

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

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

Название концепции [утиный ввод] относится к утиный тест, отнести к Джеймс Уитком Райли, которые могут быть сформулированы как образом:"когда я вижу птицу, которая ходит как утка, плавает как утка и крякает как утка, я называю эту птицу уткой".

Итак, мой вопрос заключается в следующем:почему я не могу назвать структурный подтип утиным типированием?Существуют ли вообще языки с динамической типизацией, которые также нельзя классифицировать как языки с утиной типизацией?

Постскриптум:

Как некто по имени сон наяву вкл. reddit.com итак красноречиво выражаясь, это "Если он компилируется как утка и связывается как утка ..."

Пост-приписка

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

Это было полезно?

Решение

Шаблоны C ++ и D - прекрасный пример "утиного набора текста", который не является динамическим.Это определенно:

типизация, при которой текущий набор методов и свойств объекта определяет допустимую семантику, а не ее наследование от определенного класса или реализацию определенного интерфейса.

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

Другие советы

Система структурного типа

Система структурных типов сравнивает один полный тип с другим полным типом, чтобы определить, совместимы ли они.Для двух типов A и B быть совместимым, A и B должна иметь такую же структуру– то есть, каждый способ включения A и дальше B должна быть та же подпись.

Утиный набор текста

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

Краткие сведения

Системы структурного типа сравнивают каждую сигнатуру метода (всю структуру).Утиный ввод сравнивает методы, которые имеют отношение к конкретной задаче (структура, имеющая отношение к задаче).

Утиный набор текста означает Если это просто подходит, все в порядке

Это относится как к динамически типизированным

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, сочетают это с выводом типов, чтобы помешать нам определять типы явно.

Я не уверен, действительно ли это отвечает на ваш вопрос, но...

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

template<typename T>
struct Test
{
    void op(T& t)
    {
        t.set(t.get() + t.alpha() - t.omega(t, t.inverse()));
    }
};

Насколько я понимаю, структурная типизация используется средствами вывода типов и т.п. Для определения информации о типе (например, Haskell или OCaml), в то время как утиная типизация не заботится о "типах" как таковых, просто о том, что вещь может обрабатывать вызов определенного метода / доступ к свойству и т.д.(подумай respond_to? в Ruby или проверка возможностей в Javascript).

Всегда найдутся примеры из некоторых языков программирования, которые нарушают некоторые определения различных терминов.Например, ActionScript поддерживает программирование в стиле "утиного ввода" в экземплярах, которые технически не являются динамическими.

var x:Object = new SomeClass();
if ("begin" in x) {
    x.begin();
}

В этом случае мы проверили, имеет ли экземпляр объекта в "x" метод "begin", прежде чем вызывать его вместо использования интерфейса.Это работает в ActionScript и в значительной степени использует утиный ввод, хотя класс SomeClass() сам по себе не может быть динамическим.

Существуют ситуации, в которых динамическая утиная типизация и аналогичный код со статической типизацией (т. е.C ++) ведут себя по-другому:

template <typename T>
void foo(T& obj) {
    if(obj.isAlive()) {
        obj.quak();
    }
}

В C ++ объект должен иметь оба isAlive и quak методы компиляции кода;для эквивалентного кода на динамически типизированных языках объекту необходимо только иметь quak способ, если isAlive() возвращает значение true.Я интерпретирую это как разницу между структурой (структурная типизация) и поведением (утиная типизация).

(Однако я пришел к такой интерпретации, приняв за чистую монету фразу Википедии "утиный ввод должен быть динамическим" и попытавшись придать ей смысл.Альтернативная интерпретация, согласно которой неявная структурная типизация - это утиная типизация, также последовательна.)

Я рассматриваю "утиный ввод" скорее как стиль программирования, в то время как "структурный ввод" - это функция системы типов.

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

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

Чтобы я мог использование структурные типы для кодирования в стиле утиного ввода, формально объявляя мои "утиные типы" как структурные типы.Но я мог бы также использовать структурные типы без "печатаю по-утиному".Например, если я пишу интерфейсы к куче связанных функций / методов / процедур / предикатов / классов / чего угодно, объявляя и называя общий структурный тип, а затем используя его везде, очень вероятно, что некоторые из блоков кода не нужны ВСЕ из особенностей структурного типа, и поэтому я излишне ограничил некоторые из них, отказавшись от значений, с которыми они теоретически могли бы корректно работать.

Поэтому, хотя я вижу, что есть точки соприкосновения, я не думаю, что утиный ввод включает структурный ввод.То, как я думаю о них, утиная типизация - это даже не то, что можно было бы отнести к структурной типизации, потому что это не одно и то же.Думая о том, что утиный ввод в динамических языках - это просто "неявные, непроверенные структурные типы", чего-то не хватает, ИМХО.Утиный ввод - это стиль кодирования, который вы выбираете использовать или нет, а не просто техническая особенность языка программирования.

Например, можно использовать isinstance проверяет в Python, чтобы подделать ограничения типа "класс или подкласс" в стиле OO.Также возможно проверять наличие определенных атрибутов и методов, подделывать ограничения структурного типа (вы могли бы даже поместить проверки во внешнюю функцию, таким образом эффективно получая именованный структурный тип!).Я бы сказал, что ни один из этих вариантов не иллюстрирует утиный ввод (если только структурные типы не являются достаточно мелкозернистыми и не поддерживаются в тесной синхронизации с кодом, проверяющим их).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top