LINUX.ORG.RU

Наследование в Rust

 , ,


1

8

Здравствуйте. Потихоньку изучаю Rust. Насколько я понял, пробежавшись по документации, в Rust ООП реализовано через struct и trait. Это так? Так вот, как реализовать наследование? Например есть следующий код:

struct Shape {
    x: f64,
    y: f64,
}

trait Circle: Shape {
    
}

trait Square: Shape {
    
}

Как мне в Circle после наследования от Shape создать поле radius? То есть что то типа

trait Circle: Shape {
    radius: f64,
}

Вообще было бы здорово, если бы кто-нибудь рассказал про ООП в Rust. Заранее спасибо большое :)

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

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

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

Уже скала на этом навернулась, никому не нужна ведь.

То-то Apache Spark признан чуть ли не главным Data Science проектом 2014 года...

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

Давай конкретно чем
не тянет на полноценные исключения

Ты сам ответил

Опять же, ты можешь добавлять реализацию трейтов для сторонних типов. А «стандартное ООП» такого не позволяет.

А кто-то говорил что-то плохое про trait'ы?

Думал, что общеизвестно. В плюсах у шаблонов, по сути, «утиная типизация» (до концептов ещё дожить надо). Можно передавать что угодно и если для переданного типа есть подходящие функции/методы, то всё сработает.

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

В расте дженерики вполне «типизированные» - мы явно указываем ограничения на тип.

В C++ ты сможешь делать так же(а с помощью boost можешь делать и сейчас). Но и по-утиному можно. Никто тебе ничего н навязывает.

в расте вариант С++ можно изобразить на макросах

И это будет больший ад, чем на крестовых шаблонах

ПОКА

А пока ещё не пока, мы обсуждаем то, что есть.

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

lol

Как сам думаешь, не слишком ли часто ты говоришь о том, чего в языке ещё нет? «Пока», «уверен, что добавят», «есть предложения»?

Кстати, ты можешь привести какой-то хороший пример? На тему " теперь я использую rust и волосы стали мягкими и шелковистыми"?

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

А вот с «ужасностью» разделения реализации и данных не согласен.

А тут и нет ничего ужасного. «Ужас» в том, что нет возможности унаследовать реализацию. И какое тут к черту «открыт-закрыт»?

Кстати, а что ты подразумевавешь под наследованием в случае отказа от is-a для конкретных типов? Если мы от этого отказывается, то в rust уже все есть...

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

вываливать все отношения между объектами в отдельную иерархию

В расте того нет. Да и вообще сложно назвать иерархией требование trait'ом реализации ещё и другого trait'а.

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

Мало того, что это иерархия, так там поди ещё мультидиспатч и множественное наследование почти задаром, без всяких проблем с ромбами.

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

Я не адепт раста, даже синтаксически плохо знаю его. Просто не люблю, когда на ровном месте анон требует в ЯП запихнуть вундевафлю.

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

Кстати, ты можешь привести какой-то хороший пример? На тему " теперь я использую rust и волосы стали мягкими и шелковистыми"?

Ну пасаны сраёна хвалят. Говорят рельные пасан, если раст юзаешь. Волосы стали шелковистее и фофанов стало меньше.

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

В rust нет наследования. Множественной диспетчеризации тоже нет.

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

Ты сам ответил

Ну я думал, что ты видишь какие-то фундаментальные недостатки в том, что есть уже сейчас. Обсуждать недостатки того, чего по сути нет, не вижу смысла.

А кто-то говорил что-то плохое про trait'ы?

Когда ты (или другой анон) считал «сущности», то трейты туда вошли. Учитывая, что трейт и тип могут быть объявлены и реализованы в разных местах, то иначе не сделать. Остаётся только реализация методов для самого типа. Подозреваю, что её отдельно сделали просто для единообразия с трейтами. В любом случае, не вижу неудобства.

Иногда это то, что надо.

Вот именно - вопрос в том, что нужно чаще.

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

В C++ ты сможешь делать так же(а с помощью boost можешь делать и сейчас).

Ты-то сам смотрел, что там в бусте предлагается? Выглядит ведь ужасно. Да и я смутно помню, что в С++ концепты менее мощные.

И это будет больший ад, чем на крестовых шаблонах

Да ничего подобного.

А пока ещё не пока, мы обсуждаем то, что есть.

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

Если же хочешь чего-то более конструктивного, то я тоже считаю, что в расте отсутствуют многие удобные вещи. Вот только «есть предложения» - это значит, что вещи реально обсуждаются. И до реализации, как правило, проходит «немного» меньше времени, чем между принятием С++ стандартов.

На тему " теперь я использую rust и волосы стали мягкими и шелковистыми"?

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

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

Кстати, а что ты подразумевавешь под наследованием в случае отказа от is-a для конкретных типов?

Наверное что-то типа (на основе примера из этой темы):

impl Shape for CircleData derive ShapeData  {
То есть мы наследуем реализацию трейта, с возможностью переопределить методы.

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

Эм. Если у тебя нет наследования данных, то какой код должен сгенерировать компилятор? Ведь между CircleData и ShapeData нет никакой связи.

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

Если у тебя нет наследования данных, то какой код должен сгенерировать компилятор?

А почему бы не сделать наследование данных?

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

Вкусовщину комментировать не буду

Ну так и до того вкусовщина была=)

В общем, прежде чем всерьез обсуждать/сравнивать, нужно подождать еще какое-то время, пока язык созреет...

Вот думаю, что бы такое наваять на нем пока. Есть у меня несколько вариантов в свободное время: простейшая игрушка с физикой из box2d и простой графикой, эмулятор одной экспериментальной ВМ, компилятор некоторой системы выражений в их вычисление для llvm. Для чего из перечисленного rust подойдет лучше всего?

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

impl Shape for CircleData derive ShapeData

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

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

Когда ты (или другой анон) считал «сущности», то трейты туда вошли. Учитывая, что трейт и тип могут быть объявлены и реализованы в разных местах, то иначе не сделать.

Появление в языке классов не заставляет избавляться от trait. Посмотри на ту же scala.

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

Во-первых, мне зачем-то сначала показывают внутреннее устройство, а потом интерфейс(который, как правило, мне интереснее), причём где-то сбоку.

Во-вторых, в impl следует простынки с методами(я же не могу вынести реализацию методов за impl, оставив там лишь «прототипы»?), с которыми без IDE пользоваться не так удобно(а редакторам сносит голову из-за ').

В-третьих, impl, как я понимаю, не открыт. Т.е. два impl(без trait'а) я написать для одного типа не могу, а значит все это разделение бессмысленно. Впрочем, как и отказ от ООП.

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

Вот именно - вопрос в том, что нужно чаще.

Какая разница, если раст не умеет утиность? Нужно и то, и другое. C++ к этому идёт. Раст от этого отказался.

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

В PHP trait'ы тоже есть. Не вникал, но насколько понял, они призваны заменить множественное наследование и расширяют классы новыми возможностями.

TigranElGrande
() автор топика
Ответ на: комментарий от forCe

Для чего из перечисленного rust подойдет лучше всего?

По идее, для всего. Язык-то «общего назначения». Мешать может разве что отсутствие библиотек, но биндинги к тому же box2d, насколько я вижу, есть.

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

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

Дык, пользоваться можно уже, если имеющиеся «ограничения» не сильно мешают. Совместимость ведь ломать не будут.

Ну и если вспомнить, например, С#, то он версии 1.0 тоже не блистал фичами.

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

Эмулятор ваяй. Сам Патрик Уолтон этим не погнушался.

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

Оба варианта будут не слишком изящны с точки зрения читаемости кода.

Ну прописывать «наследование данных» не так и страшно - ведь это будет делаться может вместе с обьявлением. То есть дополнительных букв мало.

А вот наследование каждого трейта придётся прописывать, это да.

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

Во-первых, мне зачем-то сначала показывают внутреннее устройство, а потом интерфейс

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

А в документации как раз всё правильно. Например, вот. Сначала говорится, что есть вот такая структура, причём «ненужной» реализацией документацию не засоряют. Дальше методы и перечисление реализуемых трейтов. Можно делать точно так же. Благо раст из коробки умеет генерить документацию.

я же не могу вынести реализацию методов за impl, оставив там лишь «прототипы»?

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

Т.е. два impl(без trait'а) я написать для одного типа не могу

А проверить? Всё работает.

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

(а редакторам сносит голову из-за ').

Вопрос поддержки имеющимися ИДЕ/редакторами только и всего. Рано или поздно оно будет, если язык окажется нужным.

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

Какая разница, если раст не умеет утиность?

Большая разница. Если это требуется раз в сто лет, то можно и макрос написать.

Опять же, можно и нужный трейт для типа реализовать. Оно и правильнее будет.

C++ к этому идёт. Раст от этого отказался.

У раста точно так же есть и то и другое. А в С++ получилось именно так по «историческим причинам».

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

можно и макрос написать.

Где-то я уже это слышал... А, точно, это же любимая отмазка общелисперов. Зачем мне нужна поддержка в языке, лучше я напишу макрос еще раз.

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

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

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

Кстати, «типажи» - это общепринятый перевод трейтов? А то я раньше как-то не сталкивался, а при обсуждении раста периодически всплывает. Сначала думал, что это чья-то самодеятельность.

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

Зачем мне нужна поддержка в языке, лучше я напишу макрос еще раз.

Во первых, что значит «ещё раз» и «поддержка в языке»? В расте весьма многое реализовано не в самом языке, а в стандартной библиотеке. В том числе и ряд макросов.

Во вторых, давай ещё раз. Что тебе мешает реализовать нужный трейт? Оно и правильнее будет, особенно если пишешь библиотеку. Ну а если тебе «нужна утиность и всё», то да - напиши макрос вместо функции. Это не сложно, а при использовании будет отличаться одним восклицательным знаком.

Но вообще это какой-то неконструктивный спор. В разных языках вполне могут быть приняты разные подходы. Раст построен на трейтах, так что если использовать принятый подход, то никаких проблем при написании обобщённого кода просто не будет. С таким же успехом можно выступать против концептов для итераторов. Ими ведь тоже можно существующий код поломать, если переданные «итераторы» реализованы «не канонично» (без указания тегов и т.д.).

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

Кстати, «типажи» - это общепринятый перевод трейтов?

Нормальные люди называют их тайпклассами.

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

Кстати, «типажи» - это общепринятый перевод трейтов?

Да, пожалуй.

(anonymous)
Нормальные люди называют их тайпклассами.

Классы типов, если уж перевести с рунглиша.

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

Нормальные люди называют их тайпклассами.

Ну это ведь не сильно отличается от прямой кальки с английского «трейты». А предложенные «классы типов» уже достаточно громоздкий термин.

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

Всем пофиг на синтаксис, кроме анона.

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

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

Кстати, «типажи» - это общепринятый перевод трейтов? А то я раньше как-то не сталкивался, а при обсуждении раста периодически всплывает. Сначала думал, что это чья-то самодеятельность.

Это и есть самодеятельность.

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

Нормальный это термин.

Ну если мы говорим о понятии в общем, то наверное. Если же речь про конкретный язык, то я всё-таки предпочту говорить «трейты».

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

А Perl умер из-за синтаксиса? Ну окей.

А из-за чего же еще? Библиотек куча. Во всех дистрах по дефолту. Куча людей его знала. Производительность, если и меньше, то не на много по сравнению с питонами и рубями. Но тем не менее все свалили на питон.

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

Ну знаешь - в расте даже нет функций с переменным количеством аргументов. Или дефолтных значений для аргументов. В итоге проблема решается макросами (vec!) или размножением функций: new, with_capacity и т.д. Но это говорит не о том, что «всё пропало», а о том, что язык, по сути, ещё развивается. Да, нам обещали обратную совместимость после 1.0, но все эти вещи, в том числе и наследование, обсуждаются и их, почти наверняка, добавят.

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

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

Вангую

На этом мог бы и остановиться. Как раз совместимости уделяется много внимания и я не вижу как добавление обсуждаемых вещей её поломает.

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

Тем не менее, для меня, как стороннего наблюдателя, истории очень похожи.

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

Вроде раст позиционируется как системный язык. GUI подпадает под эту область вроде как. Теперь вопрос - разве GUI - это не как раз самый сильный довод и пример использования наследования классов ? Как будет раст справляться с иерархией виджетов?

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

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

/0

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