
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.30] |
![]() |
|
Страницы: (33) « Первая ... 3 4 [5] 6 7 ... 32 33 ( Перейти к последнему сообщению ) |
Сообщ.
#61
,
|
|
|
Функция принимающая любой тип, который неявно кастуется в строку:
![]() ![]() void foo(T)(T param) if(isIplicitlyConvertible!(T, string)) { ... string bar = param; ... } Ну и вторая задача: без оберток создать массив в который можно было бы засунуть объект любого типа неявно кастующегося в строку. В D, кстати, вторая задача неразрешима, в C++ насколько я понимаю тоже. Неужели Rust настолько крут, что ему это по силам? |
Сообщ.
#62
,
|
|
|
Цитата applegame @ который неявно кастуется в строку Для этого в языке должны быть неявные касты... |
Сообщ.
#63
,
|
|
|
Интересно можно ли вообще isImplicitlyConvertible считать интерфейсом в общем смысле? Или интерфейс - это нечто обязательно представленное наличием/отсутствием определенных методов, а не произвольных свойств?
Добавлено Цитата D_KEY @ В Rust нельзя 8-мибитное целое неявно скастовать к 16-битному? Или неявно скастовать наследника к предку? Для этого в языке должны быть неявные касты... |
Сообщ.
#64
,
|
|
|
В Rust есть, например:
![]() ![]() pub trait ToString { fn to_string(&self) -> String; } И его можно использовать как для ограничения дженерика(в статике, с генерацией кода, как я понял), так и как обычный аргумент. Ну да, можно хранить в массиве. Добавлено Цитата applegame @ В Rust нельзя 8-мибитное целое неявно скастовать к 16-битному? Ну встроенные(несужающие) касты есть какие-то, да. Но свои сделать нельзя, если я правильно понимаю. |
Сообщ.
#65
,
|
|
|
А если я сделаю объект с функцией to_string, но без привязки к трейту ToString, то упомянутый тобой дженерик примет это тип?
|
Сообщ.
#66
,
|
|
|
Цитата applegame @ А если я сделаю объект с функцией to_string, но без привязки к трейту ToString, то упомянутый тобой дженерик примет это тип? Нет. Я вон выше писал, что мне бы хотелось еще и утиности. Но в Rust ты можешь добавить реализацию trait'а для типа. Тип и trait'ы же отдельно описываются. |
Сообщ.
#67
,
|
|
|
Ну и? Это и есть контекст: 1. В D интерфейс - это... 2. В С++ интерфейсов есть. 3. Есть такие же как в D, только без ключевого слова. И тут внезапно я о неправильных интерфейсах говорю. Цитата MyNameIsIgor @ Вы утверждаете, что в Rust можно соорудить аналог std::map, у которого будет аналог operator[], создающий объект конструктором по-умолчанию при его отсутствии в словаре, и при этом этот аналог можно будет инстанцировать типом без конструктора по умолчанию? А в чём проблема? Разносим интерфейс мапы по нескольким трейтам, у тех, которых надо будет - требуем к типу реализацию трейта Default. Вот пример на коленке набросал. Добавлено Цитата D_KEY @ Ну в трейте для элемента у контейнера не будет этого требования, а в требованиях метода - будет. По-моему так. Почти, будут просто разные трейты. |
Сообщ.
#68
,
|
|
|
Цитата applegame @ Основное отличие ООП-ных интерфейсов и концептов как раз в статичности/динамичности. Разве отличаются они не просто некоторыми ограничениями? Ну там отсутствие данных в интерфейсе, ограничение на множественное наследование и т.д. Цитата applegame @ Основное отличие ООП-ных интерфейсов и концептов как раз в статичности/динамичности. Разницу вполне понимаю и терминологический спор не я затеял. ![]() Цитата applegame @ Главный вопрос: зачем? ООП-интерфейсы + концепты отлично себя показали, к чему изобретать велосипед? Во первых, трейты в расте похожи на классы типов в хаскеле, например. Тоже ведь можно сказать, что они себя отлично показали. Во вторых, концепты "отлично себя показали" весьма мало где. В С++ их до сих пор нет, например. Повторюсь - не я придумывал дженерики раста и поначалу тоже был сильно недоволен. Да теряется гибкость. Насколько часто она будет нужна - другой вопрос. Зато не возникнет ситуация, что автор шаблонного кода тупо поленился ограничения (в виде концептов) прописывать. Небольшой плюс. |
Сообщ.
#69
,
|
|
|
Цитата D_KEY @ Тогда это фактически ООП-интерфейс. Статически проверить что объект унаследован от ООП-интерфейса как нефиг делать:Нет. Я вон выше писал, что мне бы хотелось еще и утиности. ![]() ![]() void foo(T)(T obj) if(is(T: ToString)) { ... } Цитата D_KEY @ Вот это уже интересней. То есть можно создать массив для типа ToString, потом взять совершенно левый объект описать для него реализацию trait'a ToString и вуаля - пихай в массив. Но постой-ка. Это сильно похоже на тот самый враппер-декоратор, который я упомянул выше, нет?Но в Rust ты можешь добавить реализацию trait'а для типа. Тип и trait'ы же отдельно описываются. |
Сообщ.
#70
,
|
|
|
В расте нет "неявного приведения" вообще. ![]() А можно пример как это можно использовать? Ну и в расте, как и в С++, мутабельность на уровне объектов, а не типов. То есть, если нам хочется с обоими видами обьектов работать, то просто будет две функции - принимающая просто ссылку и мутабельную ссылку соответственно. |
Сообщ.
#71
,
|
|
|
Цитата applegame @ Статически проверить что объект унаследован от ООП-интерфейса как нефиг делать: ![]() ![]() void foo(T)(T obj) if(is(T: ToString)) { ... } Да, если не учитывать разницу между trait'ами и ОО-интерфейсами. Цитата Вот это уже интересней. То есть можно создать массив для типа ToString, потом взять совершенно левый объект описать для него реализацию trait'a ToString и вуаля - пихай в массив. Но постой-ка. Это сильно похоже на тот самый враппер, который я упомянул выше, нет? Возможно. Давай на код посмотрим. Я пока не вижу разницы, кроме той, что trait'ы и impl'ы - фичи языка, а обертки пишутся руками как захочется, да и при использовании в обертку нужно заворачивать самому. Добавлено Цитата DarkEld3r @ Встроенные примитивные типы вроде приводятся(без потери точности). |
Сообщ.
#72
,
|
|
|
Цитата DarkEld3r @ ИМХО, классы типов в Хаскеле скорее похожи как раз на концепты.Во первых, трейты в расте похожи на классы типов в хаскеле, например. Тоже ведь можно сказать, что они себя отлично показали. Цитата DarkEld3r @ Нечто подобное сделали, хоть и через жопу - BCCL Во вторых, концепты "отлично себя показали" весьма мало где. В С++ их до сих пор нет, например. Добавлено Цитата D_KEY @ А трейты-потомки к трейтам-предкам тоже явно кастовать надо? Встроенные примитивные типы вроде приводятся(без потери точности). |
Сообщ.
#73
,
|
|
|
Цитата applegame @ Цитата DarkEld3r @ ИМХО, классы типов в Хаскеле скорее похожи как раз на концепты.Во первых, трейты в расте похожи на классы типов в хаскеле, например. Тоже ведь можно сказать, что они себя отлично показали. Не, они посередине ![]() |
![]() |
Сообщ.
#74
,
|
|
Отнюдь. Концепты описывают как раз трейты. Не понимаю, о чём спор у вас. Трейты – это свойства типа, интерфейсы – это возможности типа. За разницей в терминах – в толковый словарь он-лайн.
Свойства типа в связи со строгой типизацией – не только в Плюсах, как я понимаю – объектной модели задаются в compile-time. Касты в семантике static_cast<> как раз и выполняются с целью сменить свойства объекта. Возможности же типа определяются его состоянием в первую очередь – файл может читаться, но только если он предварительно открыт – и они не обязаны оставаться неизменными в run-time. Отсюда и кажущееся деление на статичность/динимичность свойств/возможностей. Цитата applegame @ Не понял. Задача написать метафункцию isConvertible<> на Плюсах? Я это делал, задолго до знакомства с бустом. И у Александреску есть.Ну и вторая задача: без оберток создать массив в который можно было бы засунуть объект любого типа неявно кастующегося в строку. Цитата DarkEld3r @ Потому что без них, как и интерфейсов, вполне себе живётся на аналогах. Интерфейс – абстрактный класс, имеющий только чистые методы и не имеющий полей, который наследуется всегда виртуально. Трейты вообще не нуждаются в отдельном описании, любой шаблон предъявляет требования к свойствам своих аргументов посредством выполняемых над ними операций. Беда в том, что такие трейты ненаглядны и зачастую неочевидны, потому концепты в целом бы не помешали. А интерфейсы в лице отдельной сущности нафик не нужны. Они нужны там, где нет множественного наследования реализаций, чтобы не смущать компилятор. Во вторых, концепты "отлично себя показали" весьма мало где. В С++ их до сих пор нет, например. |
Сообщ.
#75
,
|
|
|
Цитата DarkEld3r @ Ну и? Это и есть контекст: 1. В D интерфейс - это... 2. В С++ интерфейсов есть. 3. Есть такие же как в D, только без ключевого слова. И тут внезапно я о неправильных интерфейсах говорю. Конечно неправильно. Потому что интерфейсы в C++ - это концепты. Что непонятного? ![]() Цитата DarkEld3r @ А в чём проблема? Разносим интерфейс мапы по нескольким трейтам, у тех, которых надо будет - требуем к типу реализацию трейта Default. Ok, понял. Добавлено Цитата Qraizer @ За разницей в терминах – в толковый словарь он-лайн. А можно ссылку на чуть более авторитетный источник? TAPL, например? Foundations for Programming Languages? |