LINUX.ORG.RU

Rust 1.12

 


1

6

Команда разработчиков Rust рада представить релиз Rust 1.12 — системного языка программирования, нацеленного на безопасную работу с памятью, скорость и параллельное выполнение кода. В этот релиз вошёл 1361 патч.

Новое в 1.12

По словам разработчиков, релиз 1.12 является, возможно, самым значительным с момента выпуска релиза 1.0. Самое заметное для пользователей изменение в версии 1.12 — это новый формат ошибок, выдаваемых rustc. Сообществом была проделана многочасовая работа по переводу вывода ошибок на новый формат. Кроме того, для лучшей интеграции и взаимодействия со средой разработки и другим инструментарием ошибки теперь можно выводить в формате JSON при помощи специального флага --error-format=json.

Самое большое внутреннее изменение — это переход на новый формат внутреннего представления программы MIR. Незаметное сегодня, это изменение открывает путь к череде будущих оптимизаций компилятора, и для некоторых кодовых баз оно уже показывает улучшения времени компиляции и уменьшение размера кода. Переход на MIR открывает ранее сложнодоступные возможности анализа и оптимизации. Первое из многочисленных грядущих изменений — переписывание прохода, генерирующего промежуточное представление LLVM, того, что rustc называет «трансляцией». После многомесячных усилий новый бэкенд, основанный на MIR, доказал, что готов к реальной работе. MIR содержит точную информацию о потоке управления программы, поэтому компилятор точно знает, перемещены типы или нет. Это значит, что он статически получает информацию о том, нужно ли выполнять деструктор значения. В случаях, когда значение может быть перемещено или не перемещено в конце области действия, компилятор просто использует флаг из одного бита на стеке, что, в свою очередь, проще для оптимизации проходов в LLVM. Конечный результат — уменьшенный объем работы компилятора и менее раздутый код во время исполнения.

Другие улучшения:

  • Множество мелких улучшений документации.
  • rustc теперь поддерживает три новые цели MUSL на платформе ARM: arm-unknown-linux-musleabi, arm-unknown-linux-musleabihf и armv7-unknown-linux-musleabihf. Эти цели поддерживают статически скомпонованные бинарные файлы. Однако, в собранном виде они пока не распространяются.
  • Повышена читабельность описаний ошибок в ссылках и неизвестных числовых типах.
  • Компилятор теперь может быть собран с LLVM 3.9.
  • Тестовые бинарные файлы теперь поддерживают аргумент --test-threads для указания количества потоков для запуска тестов, который действует точно так же, как переменная окружения RUST_TEST_THREADS.
  • В случае продолжительности выполнения тестов больше минуты показывается предупреждение.
  • Вместе с выпусками Rust теперь доступны пакеты с исходными кодами, которые можно установить при помощи rustup через команду % rustup component add rust-src. Исходные коды могут быть использованы для интеграции и взаимодействия со средой разработки и другим инструментарием.
  • Ускорено обновление индекса реестра.
  • cargo new получил флаг --lib.
  • Добавлен вывод профиля сборки (release/debug) после компиляции.
  • cargo publish получил флаг --dry-run.
  • Сокеты на Linux в подпроцессах теперь закрываются правильно через вызов SOCK_CLOEXEC.
  • Определения Unicode обновлены до 9.0.

Стабилизация библиотек:

  • Cell::as_ptr и RefCell::as_ptr.
  • IpAddr, Ivp4Addr и Ipv6Addr получили несколько новых методов.
  • LinkedList и VecDeque теперь имеют новый метод contains.
  • iter::Product и iter::Sum.
  • Option реализует From для содержащегося в нём типа.
  • Cell, RefCell и UnsafeCell реализует From для содержащихся в них типах.
  • Cow<str> реализует FromIterator для char, &str и String.
  • String реализует AddAssign.

Возможности Cargo

Самая большая возможность, добавленная в Cargo в этом цикле — «рабочие области». Описанные в RFC 1525, рабочие области позволяют группе пакетов разделять один общий файл Cargo.lock. Это позволяет намного легче придерживаться единственной версии общих зависимостей при наличии у вас проекта, который делится на несколько пакетов. Для включения этой возможности в большинстве мультипакетных проектов достаточно добавить одну единственную строчку [workspace] в Cargo.toml верхнего уровня, более сложным установкам может потребоваться дополнительная настройка.

Другая существенная возможность — переопределение источника пакета. При помощи инструментов cargo-vendor и cargo-local-registry можно переопределять зависимости локально (vendoring). Со временем это станет фундаментом для построения инфраструктуры зеркал crates.io.

>>> Подробный список изменений

>>> Подробности

Ответ на: комментарий от red75prim

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

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

В этом смысле наследование реализации провоцирует нарушение инкапсуляции.

red75prim ()
Ответ на: комментарий от asaw

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

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

khrundel ()
Ответ на: комментарий от mersinvald

Массив из std::result например. Если результат и ошибка оба реализуют дебаг, то и для резалта он определён. Аналогичный енум можно реализовать и для своего набора типов, реализовать для этого enumа нужный трейт.

khrundel ()
Ответ на: комментарий от khrundel

Я написал, что отделение деталей реализации от интерфейса это и есть инкапсуляция.

нет, это совершенно разные, хотя возможно и связанные вещи

инкапсуляция это невозможность нарушить инварианты объекта; например, у нас есть объект time_interval и для любого такого объекта всегда

time_interval.start() + time_interval.length() == time_interval.end()

то это инкапсуляция вместе с отделением деталей реализации от интерфейса; а если у нас

time_interval.start + time_interval.length() == time_interval.end

или

time_interval.start + time_interval.length == time_interval.end()

или

...

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

а если же можно так хитро вызвать какие-то методы, чтобы равенство

time_interval.start() + time_interval.length() == time_interval.end()

оказалось нарушено, то это отделение деталей реализации от интерфейса, но без инкапсуляции

www_linux_org_ru ★★★★★ ()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от WatchCat

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

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

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

я лично считаю, что «язык с ооп, близкий к железу» следует понимать как «язык, где (в т.ч. мои) ооп-практики из с++ не придется ломать, за исключением тех, для которых предъявлено достаточное обоснование их опасности и список приемлемых замен»

и в общем-то дальше плевать на определение ооп (ну не совсем конечно; интерфейсы, ко- и контра-вариантность и мультиметоды нужны, и еще meta-object protocol по мере возможности тоже хотелось бы иметь)

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

www_linux_org_ru ★★★★★ ()
Последнее исправление: www_linux_org_ru (всего исправлений: 2)
Ответ на: комментарий от eao197

а насчет наследования реализации — оно нужно, но не все с ним так просто, я напишу потом

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от khrundel

более точно, конечно, сказать не «инкапсуляция это невозможность нарушить инварианты объекта»

а «инкапсуляция это способ сделать невозможным нарушение инвариантов объекта», хотя и это не совсем точно, но идея я думаю ясна

www_linux_org_ru ★★★★★ ()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от www_linux_org_ru

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

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

khrundel ()
Ответ на: комментарий от anonymous

Понятно на что я намекаю?

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

DarkEld3r ★★★★★ ()
Ответ на: комментарий от eao197

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

а что там осознавать?

ООП «в общем виде» — это модель вычислений, парадигма, способ думать о программе в виде компонентной среды, системы из повторно используемых компонент-модулей (например: модульная система, рассредоточенный набораспектно-ориентированные компоненты, компонентно-ориентированное программирование, компонетное ПО)

«высокое понятие», ога

ООП «в виде реализации объектной модели runtime языка» — это понимание этого высокого понятия в конкретном языке.

при этом у каждого языка идеи ООП понимание и реализация идеи свои, разные.

* механизм реализации КОП — ООП (хотя может быть и не ООП как расширение АТД, а АТД + более reusable интерфейсы)

* механизм реализации ООП как идеи — реализация какой-то объектной модели ООП в каком-то языке.

* понимание того, что такое «повторно используемый модуль» (компонент) и как устроена система типов модулей, отношения в системе типов — разные. насколько получается composable и compositable.

* механизмы реализации объектной модели — разные, но в основном относятся к полиморфизму какого-то вида системы типов. и отношений. например, динамическая/статическая диспетчеризация по типам объектов, или типам типов объектов, типам метаобъектов и т.п.

* механизмы реализации интерфейсов повторно используемых компонент — тоже разные. например, трейты. метаклассы. метаобъектный протокол.

то есть: ООП это не только модель С++. в компонентно-ориентированное программировании, КОП, например, вообще считается наследование бякой и слишком жёстким типом связи.

поэтому, как пишет Пфистер или Клеменс Шипёрски в книге «КОП» (например)

КОП = ООП + модульность «лучше чем в С++» + безопасность - наследование реализации через границы модулей.

то есть, реализация модульной системы, как КОП среды

(с рефлексией, фабриками объектов по запросу, репозиторием сервисов типа SOA и т.п.)

anonymous ()
Ответ на: комментарий от anonymous

Следующая таблица дает историческую перспективу эволюции императивного программирования:\

Десятилетие 	Технология программирования 	Ключевое нововведение
1940-е 	машинные коды 	программируемые машины
1950-е 	ассемблерные языки 	символы
1960-е 	языки высокого уровня 	выражения и независимость от машины
1970-е 	структурное программирование 	структурные типы и управляющие конструкции
1980-е 	модульное прогаммирование 	отделение интерфейса от реализации
1990-е 	объектно-орентированное пр-е 	полиморфизм
2000-е 	компонентно-ориентированное пр-е 	[b]динамическая и безопасная композиция[/b]

Таблица 4-1. Эволюция императивного программирования

anonymous ()
Ответ на: комментарий от anonymous

Тут проблемка. Вы специально не написали сюда тупиковые ветви типа функционального программирования? И с чего вы взяли что КОП не тупиковая ветвь. Истории успеха то нет.

anonymous ()
Ответ на: комментарий от eao197

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

WatchCat ★★★★ ()
Ответ на: комментарий от WatchCat

Наследование никогда не было прибито гвоздями к данным или реализации.

Если не наследуются ни данные, ни реализации, то в чем тогда смысл наследования? И если для статически-типизированных языков здесь хоть что-то можно приплести за уши, то как тогда быть с динамически-типизированными языками вроде SmallTalk, Ruby и Python?

eao197 ★★★★★ ()
Ответ на: комментарий от khrundel

Только размер объекта будет равен размеру самого большого объекта. В итоге можем получить дикий провал по памяти.

И такой подход везде можно накостылять.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от RazrFalcon

Только размер объекта будет равен размеру самого большого объекта.

Плюс 4 байта на дискриминант.

anonymous ()
Ответ на: комментарий от tailgunner

И с каких это пор пейсатели обертки на Rust над оберткой на Си, над FreeRTOS уже стали моими конкурентами?

shkolnick-kun ★★★ ()
Ответ на: комментарий от FilosofeM

Попов, - это тот, кто стырил и изуродовал чужое.

Я пишу свой велосипед с костылями, так что мимо.

shkolnick-kun ★★★ ()
Ответ на: комментарий от shkolnick-kun

Твой конкурент - FreeRTOS. Скоро она обзаведется интерфейсом к Rust.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Твой конкурент - FreeRTOS.

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

Ну я же как бы адекват...

Скоро она обзаведется интерфейсом к Rust.

И где можно будет пользоваться этим интерфейсом? Кто напишет дрова на Rust для этой платформы?

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

shkolnick-kun ★★★ ()
Последнее исправление: shkolnick-kun (всего исправлений: 1)
Ответ на: комментарий от shkolnick-kun

И где можно будет пользоваться этим интерфейсом? Кто напишет дрова на Rust для этой платформы?

Зачем? На Rust будут писать «прикладные программы».

Но кто и зачем будет его пользовать, когда есть CubeMx, писанный индусами за еду?

Кому надо, тот и будет. Никому не надо будет - умрет за ненадобностью. // К.О.

tailgunner ★★★★★ ()
Ответ на: комментарий от shkolnick-kun

Нет-нет, не надо, не унижай себя попытками оправдываться :D Факт подгорания зафиксирован в первом комменте к новости, и ничего с этим уже не поделаешь

Manhunt ★★★★★ ()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от eao197

то в чем тогда смысл наследования

В наследовании интерфейса, ваш КО.
Кроме того, у трейтов есть ещё дефолтные методы.

WatchCat ★★★★ ()
Ответ на: комментарий от WatchCat

В наследовании интерфейса, ваш КО.

Т.е. заморочки статической типизации выдаем за один из элементов ООП.

Никто так и не ответил, зачем Rust-у нужно быть ООЯ. Так зачем?

eao197 ★★★★★ ()
Ответ на: комментарий от asaw

там и инкапсуляции нормальной нет. Это уже обсуждали.

Не припоминаю толковых аргументов на эту тему. Ссылка или нормальное объяснение будет?

DarkEld3r ★★★★★ ()
Ответ на: комментарий от eao197

Т.е. заморочки статической типизации выдаем за один из элементов ООП.

Где заморочки?

Никто так и не ответил, зачем Rust-у нужно быть ООЯ.

А кто-то спрашивал?
ООП, пусть и своеобразное, там в качестве вишенки.
Ему не надо, но он может.

WatchCat ★★★★ ()
Ответ на: комментарий от tp_for_my_bunghole

Так generics и templates это кодогенерация в виде тонн лапши.

Дык, эта лапша останется под капотом, в отличии от генерённой.

В Go встроенный тип Map:

А если захочется чего-то другого?

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

Ну у товаrища такая мулька, что если нету protected, то и нету инкапсуляции.
С++ головного мозга.

WatchCat ★★★★ ()
Ответ на: комментарий от WatchCat

Где заморочки?

В наследовании интерфейсов. В динамически-типизрованных языках этих заморочек нет. Ваш К.О.

А кто-то спрашивал?

Да тут полтемы — это обсуждение того, является ли Rust ООЯ или нет. Растоманы говорят, что является, не смотря на специфический взгляд на инкапсуляцию и отсутствие наследования.

Ему не надо, но он может.

И C может. И Go.

Объектной-ориентированности это не добавляет ни тому, ни другому.

Как, например, наличие лямбд не делает C++, Java и C# функциональными языками. Хотя, при желании, на них можно и в таком стиле писать.

eao197 ★★★★★ ()
Ответ на: комментарий от asaw

Мне ничего не помешает, например, приделать к этому же самом объекту новое поведение в другом месте.

И чем это плохо?

Опять же, в С++, до недавнего времени, тебе тоже никто не мешал (наследоваться и) приделывать крылья. Сейчас появилось ключевое слово final, но не уверен, что его стоит всем подряд библиотечным классам лепить. И уж точно нет никаких средств проконтролировать, что класс расширяют предусмотренным способом: можно выбрать или полный запрет расширения функциональности или мириться с тем, что класс будут «использовать неправильно.

Опять же, что мешает иметь делать обёртки/адаптеры/декораторы? Или экстеншн методы (а то и просто свободные функции)? К приватным данным доступа в расте точно так же не будет. В общем, ты упорно проблему из пальца высасываешь.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от eao197

В наследовании интерфейсов.

Где в наследовании интерфейсов заморочки?

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

Чем он специфичен? Если не считать твоей зацикленности на protected.

И C может. И Go.

С не может - нет инкапсуляции и наследования в каком либо виде.
Про Go не знаю ничего.

Ещё раз.
В Rust есть:
- Инкапсуляция (A language mechanism for restricting direct access to some of the object's components.)
- Наследование. Да, только интерфейсов, но тем не менее.
- Полиморфизм.
- Абстракция.
Следовательно Rust объектно-ориентированый язык.
Всё. Дальше не вижу смысла спорить.

WatchCat ★★★★ ()
Ответ на: комментарий от khrundel

Раст в этом плане недалеко ушёл, всего лишь запретили наследование данных.

Неверно. Объявляем Worker и Human со «свойством» name, для первого реализуем трейты Deref и DerefMut. Теперь мы можем у работника вызывать публичные методы, которые технически принадлежат человеку, а также передавать Worker в функцию, которая требует Human. Чем не наследование данных? Вот только из-за отсутствия сахарка реализация этих 2-ух примитивных объектов занимает 43 строки без учета функции main(). Смотреть код.

shaiZaigh ()
Ответ на: комментарий от WatchCat

Где в наследовании интерфейсов заморочки?

Хватит тупить. Само понятие «интерфейса» — это заморочки статической типизации.

Чем он специфичен?

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

Следовательно Rust объектно-ориентированый язык.

С хера ли?

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

eao197 ★★★★★ ()
Ответ на: комментарий от DarkEld3r

И чем это плохо?

Это не просто «не плохо», это офигенно классно сделано, так и должно быть!

В общем, ты упорно проблему из пальца высасываешь.

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

Manhunt ★★★★★ ()
Ответ на: комментарий от eao197

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

Осталось обосновать тезис о том, что ООП без наследования реализации не бывает :D

Manhunt ★★★★★ ()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от asaw

Ты можешь убедительно доказать, что ООП не нужно, эффективно реализовав на языке без поддержки ООП сложный качественно работающий продукт

Хочешь сказать, что тех же чисто функциональных языках ничего сложного не написали? Или опять пойдут отмазки в духе «ну браузерного движка нет» или «на джаве/шарпе/плюсах больше написано»?

DarkEld3r ★★★★★ ()
Ответ на: комментарий от eao197

Само понятие «интерфейса» — это заморочки статической типизации

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

anonymous ()
Ответ на: комментарий от eao197

Хватит тупить.

А ты перестань упарываться всякой химией

Само понятие «интерфейса» — это заморочки статической типизации.

Обоснуй.

Отсутствие наследования реализации говорит о том,

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

WatchCat ★★★★ ()
Ответ на: комментарий от Manhunt

Не менее необходимо доказать, что наследование интерфейсов — это есть то самое наследование из святой троицы ООП ;)

eao197 ★★★★★ ()
Ответ на: комментарий от WatchCat

Обоснуй.

Как все запущено. Пожалуй, сольюсь, объяснять азы столь самоуверенному эксперту нет возможности.

eao197 ★★★★★ ()
Ответ на: комментарий от anonymous

Это всё равно что саму статическую типизацию объявить заморочкой.

С точки зрения динамической типизации это так и есть.

Интерфейсы есть всегда, только в динамических языках они неявные, а в статических - явные, как и всё что касается типов.

В том-то и дело. Только в динамических языках нет такой сущности за ненадобностью. Посему там и понятия «наследования интерфейсов» нет, хотя понятие «наследование» есть.

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

eao197 ★★★★★ ()
Ответ на: комментарий от shaiZaigh

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

asaw ★★★★★ ()
Последнее исправление: asaw (всего исправлений: 1)
Ответ на: комментарий от eao197

Т.е. заморочки статической типизации выдаем за один из элементов ООП.

Как связан вызов методов через виртуальную таблицу с статической типизацией?

Никто так и не ответил, зачем Rust-у нужно быть ООЯ. Так зачем?

Я не понял, вы сейчас торгуетесь что ли? Типа «ну давайте, пусть Rust будет не ООЯ, чего вам стоит». Раст просто по факту язык, поддерживающий ОО. Ну есть в нём это.

khrundel ()
Ответ на: комментарий от eao197

А вот в статически-типизированных языках, в которых не смогли во множественное наследование, появилась такая заморочка, как интерфейсы

Нет. Это ортогональные понятия. Более того, использование множественного наследования для реализации интерфейсов - это костыль. В GNU Си++ была (в 1994 году) такая вещь, как сигнатуры - почти что трейты Rust: https://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_5.html#SEC112 Но не прижилось :/

tailgunner ★★★★★ ()
Ответ на: комментарий от khrundel

Как связан вызов методов через виртуальную таблицу с статической типизацией?

Это вы троллите или реально не понимаете?

Я не понял, вы сейчас торгуетесь что ли?

Не поняли.

Rust выглядит как язык, который предлагает несколько другие инструменты для борьбы со сложностью. В частности это абстрактные типы данных, алгебраические типы данных, обобщенное программирование. Очень нехилый набор инструментов. Особенно если сравнивать с C или Go.

Итак, язык сам по себе крут. Но вот ООП выглядит как натянутая на глобус сова. И вот не понятно, зачем утверждать «Раст просто по факту язык, поддерживающий ОО»?

Типа, это не говно, я не зря на него перешел?

eao197 ★★★★★ ()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Нет. Это ортогональные понятия.

Да. Не ортогональные.

В Eiffel-е, например, интерфейсы не нужны. Ибо там смогли во множественное наследование.

В C++ с множественным наследованием похуже, но в нем так же интерфейсы не нужны.

А вот в Java и его потомках, от множественного наследования отказались (ибо не смогли как в Eiffel), отсюда и пошло проникновение интерфейсов в мейнстрим.

eao197 ★★★★★ ()
Ответ на: комментарий от asaw

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

А что ты делаешь с тем, что в плюсах можно сделать специализации шаблонов для одного и того же типа по разному? Или с тем, что можно сделать одноимённые функции с предполагаемым одинаковым поведением, но разной логикой? Сюда же про экстеншн методы.

А ничего, потому что это не проблема.

DarkEld3r ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.