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.

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

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

★★★★★

Проверено: Falcon-peregrinus ()
Последнее исправление: Falcon-peregrinus (всего исправлений: 10)
Ответ на: комментарий от mersinvald

Это раст в таком виде не нужен

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

именно с move через swap всё в порядке.

То, что moved-out объект может спокойно и безошибочно использоваться - это тоже «в порядке»?

То есть в целом нет

/0

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

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

И всё равно проблема тут не в swap, а в отсутствии статического контроля.

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

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

Ты просто не понял о чем я пишу. Кроме того, ты ещё и фанбой. Инкапсуляция - это в первую очередь связь состояния с поведением, данных с функциями, которые ими манипулируют. В твоём же любимом расте «структура» - отдельно, интерфейсы (трейты) - отдельно, реализация трейтов и главное - ИХ СВЯЗЬ С ОБЪЕКТОМ - тоже отдельно! Пока весь код не перелопатишь, так и не поймешь что объект из себя представляет. Это практически ничем не отличается от голого Си. Марш читать про ООП, потом иди писать код. Когда напишешь на своём расте что-то посложнее Hello World - расскажешь.

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

В твоём же любимом расте «структура» - отдельно, интерфейсы (трейты) - отдельно, реализация трейтов и главное - ИХ СВЯЗЬ С ОБЪЕКТОМ - тоже отдельно!

И это прекрасно.

Марш читать про ООП

Марш читать про low coupling.

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

Что-то по ссылке код на го не сильно короче: k-nucleotide на Go 229 строк, на расте 122

Я особо не вчитывался, но похоже там разные алгоритмы. Например сразу видно что в коде на Go есть дополнительная оптимизация, в каких-то случаях расчеты идут в int32 а в каких-то в int64. А в коде на Rust используется только i64.

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

Марш читать про low coupling.

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

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

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

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

Конечно же да, в определении инкапсуляции ничего не сказано сколько там должно быть обьектов. Это просто все привыкли что в C++/Java инкапсуляция реализована в виде классов, потому не могут понять языки Rust и Go в которых классов нет, и никакой инкапсуляции на уровне ниже модулей тоже нет.
Если тебе очень нужно инкапсулировать свой обьект, то для этого используют вложенные модули

mod a {
    mod b {
       struct B
    }

    mod c {
       struct C
    }
}

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

Это просто все привыкли что в C++/Java инкапсуляция реализована в виде классов, потому не могут понять языки Rust и Go в которых классов нет, и никакой инкапсуляции на уровне ниже модулей тоже нет.

... «не могут понять Си, где нет никакой инкапсуляции». И на уровне модулей это тоже не инкапсуляция.

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

Да хоть сто вложенных модулей. Мне ничего не помешает, например, приделать к этому же самом объекту новое поведение в другом месте. То есть все думали, что объект типа «улитка» умеет только ползать, а она вдруг раз - и полетела, потому что какой-то шутник прилепил к ней трейт Wings. С другой стороны, поскольку инкапсуляции нет, то нет и наследования поведения когда это нужно. Потому что невозможно сделать наследование сферического поведения в вакууме. Поведение в общем случае связано с состоянием, то есть с данными.

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

О чем ты ведешь речь - догадываюсь, но здесь речь идет не про это.

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

А теперь расскажи, что у rust не так с поддержкой ООП.

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

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

binary-trees
rust: 76 go: 85

pidigits
rust: 177 go: 99

regex-dna
rust: 60 go: 166

fasta:
rust: 214 go:198

fannkuch-redux
rust:150 go: 150

mandelbrot
rust:98 go: 134

spectral-norm
rust: 101 go: 85

n-body
rust: 199 go: 143

reverse-complement
rust:192 go: 165

Вcё равно в среднем получается примерно одинаково. Если бы код на го был прям короче, то это было бы видно.

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

Трейт Wings который ты прикрутишь сбоку не будет иметь доступа к данным, так что инкапсуляция не нарушится.

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

А теперь расскажи, что у rust не так с поддержкой ООП.

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

А где можно?

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

Трейт Wings который ты прикрутишь сбоку не будет иметь доступа к данным, так что инкапсуляция не нарушится.

Ёпрст. Да прочитай уже вот это: «инкапсуляция (encapsulation) - это механизм, который объединяет данные и код, манипулирующий зтими данными». Этого в расте нет, точка. Модули, позволяющие поместить набор языковых конструкций в изолированную единицу, - не про это.

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

Да прочитай уже вот это: «инкапсуляция (encapsulation) - это механизм

«In programming languages, encapsulation is used to refer to one of two related but distinct notions, and sometimes to the combination[1][2] thereof:

A language mechanism for restricting direct access to some of the object's components
A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.»

В Rust есть и то, и другое. А ты просто странный.

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

Rust provides a powerful module system that can be used to hierarchically split code in logical units (modules), and manage visibility (public/private) between them.

A module is a collection of items: functions, structs, traits, impl blocks, and even other modules.

Structs have an extra level of visibility with their fields. The visibility defaults to private, and can be overridden with the pub modifier. This visibility only matters when a struct is accessed from outside the module where it is defined, and has the goal of hiding information (encapsulation).

mod my {
    // A public struct with a public field of generic type `T`
    pub struct WhiteBox<T> {
        pub contents: T,
    }

    // A public struct with a private field of generic type `T`
    #[allow(dead_code)]
    pub struct BlackBox<T> {
        contents: T,
    }

    impl<T> BlackBox<T> {
        // A public constructor method
        pub fn new(contents: T) -> BlackBox<T> {
            BlackBox {
                contents: contents,
            }
        }
    }
}
impowski
()
Ответ на: комментарий от asaw

Это в расте есть. Если объект реализует какой-то еще трейт, которого нету в области видимости, то это тоже самое что объект его не реализует. Какая вообще разница что улитка может еще и летать, если в данном модуле она этого точно не сделает?

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

Если в расте есть и то, и другое, то расскажи мне по какой причине, кроме как по причине отсутствия инкапсуляции, в расте нету наследования поведения.

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

Это в расте есть. Если объект реализует какой-то еще трейт, которого нету в области видимости, то это тоже самое что объект его не реализует. Какая вообще разница что улитка может еще и летать, если в данном модуле она этого точно не сделает?

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

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

Если в расте есть и то, и другое

«Если»? Оно просто есть.

расскажи мне по какой причине, кроме как по причине отсутствия инкапсуляции,

Видишь ли, я не могу рассказать, что происходит из-за отсутствия инкапсуляции в Rust, потому что там есть инкапсуляция.

в расте нету наследования поведения.

Давай сначала ты расскажешь, почему оно необходимо.

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

«Если»? Оно просто есть.

Оно есть с натяжкой в той размытой формулировке, которую ты процитировал из википедии (очевидно, её поправл какой-нибудь фанбой раста). Обычно формулировка более конкретная: «encapsulation is an Object Oriented Programming concept that binds together the data and functions that manipulate the data». И вот этого в расте нет.

Давай сначала ты расскажешь, почему оно необходимо.

Потому что это идин из основных принципов ООП.

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

Обычно формулировка более конкретная: «encapsulation is an Object Oriented Programming concept that binds together the data and functions that manipulate the data»

«Обычно»? Я такой формулировки не встречал даже в восторженных мурзилках 25-летней давности, когда ООП казалось сре\\еребряной пулей.

Давай сначала ты расскажешь, почему оно необходимо.

Потому что это идин из основных принципов ООП.

Во-первых, нет; во-вторых, это всего лишь влечет вопрос «расскажи, почему ООП необходимо».

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

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

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

«Обычно»? Я такой формулировки не встречал даже в восторженных мурзилках 25-летней давности, когда ООП казалось сре\\еребряной пулей.

Это совершенно стандартная формулировка. Погугли хоть на русском, хоть на английском и убедись.

Во-первых, нет; во-вторых, это всего лишь влечет вопрос «расскажи, почему ООП необходимо».

Вот и приплыли. Да не необходимо ООП, просто опыт, в том числе опыт раста, показывает, что ничего более эффективного для борьбы со сложностью в программировании пока не придумали. Ты можешь убедительно доказать, что ООП не нужно, эффективно реализовав на языке без поддержки ООП сложный качественно работающий продукт вроде веб-браузерного движка. Раст на примере Servo с этой задачей пока что справляется не многим лучше Си, чего и следовало ожидать от языка без полноценной поддержки ООП.

asaw ★★★★★
()

Современное преподавание SE — зло :/ Обколются своими тремя китами, и бесполезно им потом рассказывать про Солнечную систему.

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

в расте нету наследования поведения.

Давай сначала ты расскажешь, почему оно необходимо.

Ну в рамках ООП наследование решает как минимум две конкретные проблемы: реализация абстракцый (когда мы через наследование реализуем абстрактный интерфейс/класс). Code reuse - когда мы выделеям общее поведение для некоторых классов в базовай класс, потом используем этот базовый код при наследовании в классах верхнеге уровня (например в BaseSocket могут быть рализованы методы close/bind/read/write и далее этот код можно использовать как в UDP так и в TCP сокетах по средствам наследования).

С абстакциями в расту все болие / мение понятно там есть трейты (хотя не совсем ясно можно ли к базовой абстракции прицепить некоторые данные как например файловый дескриптор к BaseSocket). А вот как реализован code-reuse в RUST без наследования ?

PS. Я ничего никому не пытаюсь доказать. На RUST не писал (пока нет времени) но к языку присматриваюсь и интерисуюсь. Если ответите с примерами буду благодарен.

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

Опять же, там все висит в RFC, вероятно в будущих релизах сделают.

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

Погугли хоть на русском, хоть на английском и убедись.

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

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

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

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

А как насчет мелочей вроде срока разработки и затрат на нее - ты их посчитал? Если да, то как?

Раст на примере Servo с этой задачей пока что справляется не многим лучше Си

Потому что 15 лет назад KHTML правильно отображал русские буквы, а какая-то бета Servo - нет. Ну окей.

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

Ну в рамках ООП наследование решает как минимум две конкретные проблемы: реализация абстракцый (когда мы через наследование реализуем абстрактный интерфейс/класс)

Это не в ООП - это следствие (убогого) дизайна Си++ (в котором нет понятия интерфейса или сигнатуры). В Rust интерфейсы реализуются без наследования.

Code reuse - когда мы выделеям общее поведение для некоторых классов в базовай класс, потом используем этот базовый код при наследовании в классах верхнеге уровня

Code reuse вполне реализуется без наследования реализации (composition over inheritance). да и вообще привязывание наследования и reuse неестественно.

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

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

Детский сад...

А как насчет мелочей вроде срока разработки и затрат на нее - ты их посчитал? Если да, то как?

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

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

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

Детский сад...

Веско.

А как насчет мелочей вроде срока разработки и затрат на нее - ты их посчитал? Если да, то как?

По опыту они в ОО-яыках значительно меньше

То есть ты не считал.

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

То есть все думали, что объект типа «улитка» умеет только ползать, а она вдруг раз - и полетела, потому что какой-то шутник прилепил к ней трейт Wings.

А все не должны думать об улитках. Все должны думать о чём-то что умеет ползать, а умеет ли это летать или нет им должно быть всё равно.

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

Когда ты уже начнёшь думать в терминах интерфейса, а не реализации?

loyd
()
Ответ на: комментарий от tailgunner
Code reuse вполне реализуется без наследования реализации (composition over inheritance). да и вообще привязывание наследования и reuse неестественно.

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

Socket (implement read/write/close/bind)
UDPSocket inherit Socket + implement connect/sendto/recfrom
TCPSocket ingerit Socket + implement connect/listen/accept

Для меня важно что для UDP и TCP сокетов методы read/write/bind/close имеют одинаковую реализацию и соотвецтвенно я их реализую только один раз в базовом классе, а UDP/TCP сокеты просто унаследовал от базавого.

Как принято решать такие проблемы в Rust ? Имеет ли смысл делать трейт UDPSocket и TCPSocket ? Или нужно на подобие С создать модуль Net в нем объявить структуру Soсket и методы read/write/bind/close + udp_connect/sendto/recfrom + tcp_connect/listen/accept + create_udp_socket + create_tcp_socket ? Или все смешать (общий функционал как функции модуля а конкретные сокеты как трейты) ? Можно пример (без реализаций просто набор деклараций) ? буду признателен.

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

А все не должны думать об улитках. Все должны думать о чём-то что умеет ползать, а умеет ли это летать или нет им должно быть всё равно.

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

Когда ты уже начнёшь думать в терминах интерфейса, а не реализации?

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

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

Как принято решать такие проблемы в Rust ?

Статью по линку, которую тебе уже дали, прочитал?

Для меня важно что для UDP и TCP сокетов методы read/write/bind/close имеют одинаковую реализацию и соотвецтвенно я их реализую только один раз в базовом классе, а UDP/TCP сокеты просто унаследовал от базавого.

read/write/bind/close реализуешь вообще не ты. Они - часть некоего трейта, называемого Unix syscall API.

Имеет ли смысл делать трейт UDPSocket и TCPSocket ?

Почему тебе не посмотреть реализацию stdlib? https://doc.rust-lang.org/std/net/

Но они спроектированы совсем не так, как ты думаешь.

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

ты не понимаешь, что ООП и есть метод декомпозиции

А ты правда считаешь, что иерархической декомпозиции не было до ООП?

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

И вот этого в расте нет.

А это что:

struct A { u: u32 }

impl A {
  fn bar(&self) -> u32 { self.u + 3 }
}

impl Lol for A {
  fn foo(&self) -> u32 { self.u + 4 }
}

Данные и функции вместе? Вместе. А то, что этот Lol можно было определить в месте определения (на основе только публичного интерфейса) это доп. фича и никак твоё определение не опровергает.

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

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

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

В том-то и проблема, что в расте у типа (структуры) нет интерфейса: тип сам по себе, а интерфейс сам по себе.

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

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

Так а интерфейс то у А какой? Чтобы это понять я должен пройтись по всем его impl не так ли? А impl означает implementation, то есть реализацию. Отсюда возвращаем тебе твой же вопрос:

Когда ты уже начнёшь думать в терминах интерфейса, а не реализации?

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