LINUX.ORG.RU

Rust 1.26

 


5

11

Команда разработчиков языка Rust рада представить новую версию Rust 1.26.0. Rust — системный язык программирования, ориентированный на безопасность, скорость и параллельность.

Обновить Rust можно с помощью команды:

curl https://sh.rustup.rs -sSf | sh # если у вас еще не установлен rustup
rustup update stable

Основные изменения:

  • Вторая редакция книги «The Rust Programming Language» (почти) готова, и теперь рекомендована по умолчанию для ознакомления вместо первой версии. Также готовится к выходу бумажное издание книги.
  • impl Trait в заголовках функций

    Стало возможно указывать Trait в заголовке функции в качестве типа возвращаемого значения:

    fn foo() -> impl Iterator<Item = i32> {
        // ...
    }
    
    Это позволяет не указывать полный тип в заголовке функции, если с точки зрения API конкретный тип не имеет значения. Такой синтаксис подразумевает статическую диспетчеризацию, в отличие от Box<Trait>.

    Также эта возможность удобна для использования с замыканиями (closures):

    fn foo() -> impl Fn(i32) -> i32 {
        |x| x + 1
    }
    

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

    // раньше нужно было писать так:
    fn foo<T: Trait>(x: T) {
    
    // сейчас можно так:
    fn foo(x: impl Trait) {
    

  • Неявное разыменование ссылок в сопоставлении с образцом (match, if let, ...)

    Теперь следующий код больше не вызывает ошибку компиляции:

    fn hello(arg: &Option<String>) {
        match arg {
            Some(name) => println!("Hello {}!", name),
            None => println!("I don't know who you are."),
        }
    }
    
    и эквивалентен такому:
    fn hello(arg: &Option<String>) {
        match arg {
            &Some(ref name) => println!("Hello {}!", name),
            &None => println!("I don't know who you are."),
        }
    }
    
    То же работает и для &mut + ref mut.

  • Раскрытие срезов (slice) в сопоставлении с образцом
    fn foo(s: &[u8]) {
        match s {
            [a, b] => (),
            [1, _, _] => (),
            _ => (),
        }
    }
    
  • Закрытые интервалы вида 0..=4, включающие обе границы в диапазон перечисления
        for i in 0..=4 {
            println!("i: {}", i); // выведет 0, 1, 2, 3 и 4
        }
    
  • Новые целочисленные типы i128 и u128
  • Функция main() теперь может возвращать тип Result
    use std::fs::File;
    
    fn main() -> Result<(), std::io::Error> {
        let f = File::open("bar.txt")?;
    
        Ok(())
    }
    
  • Ускорения в работе компилятора
  • Стабилизирована функция std::fs::read_to_string
  • При форматировании через trait Debug теперь можно выводить целочисленные значения в шестнадцатеричном виде:
    assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]")
    
  • Номер версии Cargo, начиная с этого релиза, изменяется синхронно с номером версии Rust

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

★★★★★

Проверено: Shaman007 ()
Последнее исправление: tailgunner (всего исправлений: 22)

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

Их путают с такого хера, что сами по себе они никому не нужны и никому не интересны.

отучайся говорить за всех — в данном случае разделение на информативность и понятность уместно и полезно

ты в каком-то приличном универе отучился хотя бы 3 года (лучше 5, но хотя бы 3)?

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

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

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

Неавидеть одни ЯП и обожать другие, - это все равно, что ненавидеть, например, отвертки и обожать, например, молотки...

Но местным свидетелям швитого #nogc #memorysafety этого не объяснишь...

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

обожать, например, молотки...

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

tailgunner ★★★★★
()

Вспомнилось: «Собака лает - караван идет»

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

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

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

Понятность - это необходимое условие информативности, а не сколь-нибудь независимая от неё характеристика.

Другое дело, что под понятностью, очевидно, ты понимаешь не то, что я.

Почему здесь уже объяснялась — лишняя информация оказывается бесполезной и отвлекает на себя внимание.

В твоём примере в note просто дублируется информация, написанная выше, и дополнительно сообщается трейт, чья полезность для программиста неочевидна.

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

Видимо, я недостаточно хорошо знаю Rust

Rust тут ни при чём.

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

Попробуй:

«Картошка, Беларусь», «Брюки, хлопок», «anonymized type, i32».

«Россия, Москва», «преступник, вооружённый», «уточнение, конкретизация», «Бонд, Джеймс Бонд».

Вроде, не такая уж тонкая.

Может, если бы я увидел «anonymized type, i32» на ценнике в магазине, я бы лучше понял, что ты хотел этим сказать.

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

Ну ХЗ, как по мне, он не полезней, чем название трейта в приведённом тобой выше примере ошибки.

Насколько я понял, вам эта вся чехарда нужна чтобы отличить один impl MyCoolTrait от другого impl MyCoolTrait. Для этого тип, как я показал выше, подходит не лучшим образом. Даже присвоения каждому impl Trait'у своего хеша будет лучше, чем тип.

Хотя самый адекватный вариант - идентифицировать impl Trait по имени функции, ибо один и тот же тип impl Trait даёт только для одной и той же функции. Другое дело, я не знаю, как эту инфу ясно и однозначно в сообщение впилить.

Может, подойдёт что-то вроде

   = note: expected type `impl std::fmt::Debug` (anonymized output type of fn1)
              found type `impl std::fmt::Debug` (anonymized output type of fn2)

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

Не стоит забывать о том что серво начали писать еще до 1.0 и продолжали всё время спустя.

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

Там много легаси с тех времен когда раст еще не был растом или с его юношеских релизов, рассматривать серво как пример хорошего кода не стоит.

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

ты видишь какие-то препятствия (с точки зрения нарушения безопасности на уровне железа) к тому, чтобы дать доступ к каким-то кишкам фаерфокса плагинам, написанным на safe rust?

Точно те же, которые привели к уходу на WebExtensions: кишки браузера меняются, стабильного API, дающего полный доступ там нет и не будет.

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

Неавидеть одни ЯП и обожать другие, - это все равно, что ненавидеть, например, отвертки и обожать, например, молотки...

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

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

В твоём примере в note просто дублируется информация, написанная выше, и дополнительно сообщается трейт, чья полезность для программиста неочевидна.

Если вы вот про этот пример:

error[E0308]: mismatched types
  --> src/main.rs:22:16
   |
22 |         return my_str();
   |                ^^^^^^^^ expected anonymized type, found a different anonymized type
   |
   = note: expected type `impl std::fmt::Debug` (anonymized type)
              found type `impl std::fmt::Debug` (anonymized type)

То он не мой. Это текущий выхлоп существующего Rust-ового компилятора.

Попробуй:

Попробовал. Не понял, что хотел сказать автор.

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

Неплохой вариант, возможно есть смысл вынести на обсуждение

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

он не мой. Это текущий выхлоп существующего Rust-ового компилятора.

Я не говорил, что ты его из головы придумал. Я говорил, что ты его в пример привёл.

Не понял, что хотел сказать автор.

Автор хотел сказать, что во втором наборе словосочетаний после запятой идёт более точная характеристика предмета, о котором идёт речь перед запятой.

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

Попробуй, не знаю, запятую во всех словосочетаниях мысленно заменить на «а именно».

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

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

ты видишь какие-то препятствия (с точки зрения нарушения безопасности на уровне железа) к тому, чтобы дать доступ к каким-то кишкам фаерфокса плагинам, написанным на safe rust?

У меня плохие новости, всё ещё хуже: https://www.reddit.com/r/rust/comments/8j7y1f/i_am_lachlansneff_creator_of_ne...

https://summerofcode.withgoogle.com/projects/#5878622305386496

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

Я говорил, что ты его в пример привёл.

Вообще-то даже не я его в пример привел. Этот пример появился много раньше и тут завязался жаркий спор, в котором Rust-оманы говорили, что сообщение об ошибке понятное, а люди со стороны говорили обратное. Но, очевидно, не обе стороны не понимали, что не понятно другой стороне.

Я всего лишь попытался объяснить предмет спора на пальцах и, в ответ на просьбу tailgunner-а, привел свой вариант сообщения об ошибке, которое в конкретной ситуации было бы понятнее. Лично для меня (но, как выяснилось, не только для меня). Причем я просто добавил кусок недостающей информации к уже имеющемуся сообщению от компилятора. Ничего нового не придумывал.

Автор хотел сказать, что во втором наборе словосочетаний после запятой идёт более точная характеристика предмета, о котором идёт речь перед запятой.

На вот таком вот примере:

«Россия, Москва»

Сразу же возникает вопрос: «И что же хотел сказать автор?» Каким-таким образом «Москва» является более точной характеристикой предмета «Россия»?

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

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

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

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

Каким-таким образом «Москва» является более точной характеристикой предмета «Россия»?

Область на карте с постепенным уточнением границ.

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

https://summerofcode.withgoogle.com/projects/#5878622305386496

я хотел было лениво сказать «ниче интересного», но заметил там «Organization Mozilla»

что касается производительности — веб-ассамблея раньше тормозила емнип на 5% или около того, причина (могу соврать) из-за необходимости размещать перед каждым условным переходом проверку того, что он происходит на 16-байтовую границу, и вроде еще из-за чего-то

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

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

Точно те же, которые привели к уходу на WebExtensions: кишки браузера меняются, стабильного API, дающего полный доступ там нет и не будет.

нет стабильного API? и не надо

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

Когда в твоей руке молоток, - все проблемы кажутся гвоздями, не так ли?

Не так. Хлеба ты молотком не нарежешь.

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

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

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
module Lib where

data HList xs where
  HNil :: HList '[]
  (:::) :: a -> HList as -> HList (a ': as)

infixr 6 :::

class HLen xs where
  hlen :: xs -> Int

instance HLen (HList '[]) where
  hlen HNil = 0

instance HLen (HList xs) => HLen (HList (a ': xs)) where
  hlen (_ ::: xs) = 1 + hlen xs

class HSum xs where
  hsum :: xs -> Int

instance HSum (HList '[]) where
  hsum HNil = 0

instance HSum (HList xs) => HSum (HList (Int ': xs)) where
  hsum (h ::: tail) = h + hsum tail



пример использования

*Lib> hlen ('a':::True:::HNil)
2

[quote] hsum ((1::Int):::(2::Int):::(3::Int):::HNil)[br][/quote]6


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

Но в целом это работает как список, на сколько можно судить.

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

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

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}

Спасибо, но, боюсь, это слишком для моих хилых знаний о Хаскелле.

А что тот пример в расте, про который ты сказал что это кортеж? Он похоже вполне себе работает как список.

Там тип значения - ((({integer}, &str), std::string::String), ()). Как по мне, так это кортеж.

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

Информация - что чисто субъективная штука.

Информация может быть очень даже объективной вещью. У нее даже есть мера - биты. Возможно вы слышали об этом. Если же нет, то один бит это такой объем информации, который уменьшает неопределенность в два раза. Если у вас два шарика, черный и белый, то информация что шарик белый - это один бит. Если шариков четыре цвета, то (тоже самое) сообщение что шарик белый будет иметь размер уже в два бита. Тут нет никакого субъективизма. А вот информация, что два разных типа одинаковые (или что два одинаковых типа разные) - она абсолютно не уменьшает никакую неопределенность и поэтому содержит 0 (ноль) бит информации.

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

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

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

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

Да не спеши ты с выводами! Просто хаскелистам лениво было отвечать. Многие значения можно завернуть в Dynamic, а потом вытащить обратно, т.е. сымитировать динамическую типизацию, если очень приспичит: http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Dynamic.html

Создаешь список [Dynamic] и радуешься жизни.

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

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

Вот ты вроде умный человек, а не понимаешь очевидных вещей. Без костылей (а-ля использования динамики — WTF? серьезно? — и прочего изобретения псевдосписков) в хаскеле гетерогенные списки создать невозможно в принципе.

Создаешь список [Dynamic] и радуешься жизни.

Ага. В языке с могучей статической типизацией, чтобы решить задачу, прибегаешь к презренной динамической типизации, и радуешься. Бугагашеньки.

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

Я не говорю о том, в haskell есть аналог trait object. Я думаю, что в Rust эти trait objects даже содрали из Haskell. Как всегда, это называется заумно (не помню сейчас как), но делает почти тоже самое. Список запросто можно создать по таким объектам. Там всего-то надо определить свой тип и добавить

data МойГетерогенныйТип = forall a. КлассТиповТакойТо => МойГетерогенныйТип a

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

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

Да что такое эти ваши «гетерогенные списки»?

https://ru.wikipedia.org/wiki/Гетерогенность
В «динамике» массивы как раз обычно гетерогенны. Например, в Python тип list.

Список Box<Trait> - это гетерогенный или нет?

Да. Но узнать к какому типу относится тот или иной элемент можно лишь в рантайме.

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

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

Некоторые из них занимаются этим всерьез на конференциях, так что я всего лишь невинный агнец на их фоне.

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

Ага, и целые опусы в блогах пишут)

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

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

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

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

Попробуй написать этот дженерик.

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

Как оказалось, гетерогенные списки так в Хаскелль и не завезли.)

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

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

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

Создаешь список [Dynamic] и радуешься жизни.

не, ну это не серьёзно.

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

Да. Но узнать к какому типу относится тот или иной элемент можно лишь в рантайме.

Но тогда смысл этого? Мы ведь говорим в первую очередь о гарантиях компилятора. Иначе разговор ниочём - бери яваскрипт и фигач «гетерогенные списки» в своё удовольствие. Ну или вон как dave сказал - заверни в dynamic.

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

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

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

Берешь тип-сумму и параметризуешь ею

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

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

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

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

А чо надо? Вообще для начала сформулировать бы юзкейсы.

Сформулировать бы, да. Если я правильно понимаю, нужно 1) хранить объекты произвольного типа 2) знать тип каждого элемента на этапе трансляции 3) обрабатывать этот «список» рекурсивно (т.е. у него должны быть голова и хвост).

А то вдруг выяснится, что тупли и структурки их все покрывают.

По-моему, всё, приводимое ранее, и было кортежами.

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

Когда в твоей руке молоток, - все проблемы кажутся гвоздями, не так ли?

Не так. Хлеба ты молотком не нарежешь.

Вообще-то, хлеб отламывается руками...

Но не молотоком? А так - и целую буханку грызть можно, чо там.

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

Хлеб молотком резать это как растом вебню пилить. Но растишек почему то не везут в дурку.

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

По-моему, всё, приводимое ранее, и было кортежами.

Я так понимаю тебя смущает «уникальность» типа для каждого списка. Т.е. список 'a' ::: True ::: HNil будет иметь тип HList Char (HList Bool (HList [])), а список (1::Int) ::: HNil будет иметь тип HList Int (HList []).

Я в общем понимаю что это не совсем привычно. Но всё таки я могу привести пару интересных примеров. Первое это некоторый промежуточный тип между обычным списком и гетерогенным (в смысле представленном в коде который я привёл). Это список с известной на этапе компиляции длиной. выглидит например так Vect a n где a - тип элементов в коллекции, а n - число эл-тов в списке. При этом туда можно добавлять элементы, убирать элементы и длина остаётся известной на этапе компиляции (ну т.е. если мы убрали один эл-т, то длина уменьшилась, стал тип Vect a (n-1), если прибавили, то длина увеличилась - Vect a (n+1)). Ну при этом есть дополнительная гарантия, а именно что мы никогда не вызовем head на пустом списке (пока фильтровать не начнём, конечно.. но это детали:) ).

Если следовать твоей логике то это кортеж или не кортеж? В пользу того что это кортеж говорит что тип меняется при добавлении/удалении эл-та, т.е. как у кортежа. А в пользу того что список - то что тип эл-тов один и тот же. И можно легко определить обычные для списков операции.

Сразу скажу не встречал чтобы кто то окрестил такую конструкцию кортежем. Т.е. можно конечно наверное, но смысла мало.

Следующий пример чуть более непонятный: в языках с зависимыми типами очень многие типы уникальны в том смысле что прямо зависят от значений. Т.е. там «уникальность» типов в этом смысле гораздо более заметна чем например в хаскеле. Приведу пример: функия число аргументов (а значит и тип) которой зависят от первого аргумента:

adder 0 : Int -> Int
adder 1 : Int -> Int -> Int
adder 2 : Int -> Int -> Int -> Int
т.е. если передано значение 0 - то ф-ция ожидает один аргумент и вернёт его, если передано значение 1 - ф-ция ожидает два арг-та и вернёт их сумму. Если передано 2 - ф-ция ожидает три арг-та и вернёт их сумму.

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

Т.е. я хочу сказать что в целом аргумент «уникальный тип для каждого значения значит не список а кортеж» - выглядит не слишком убедительно. Мне кажется нужно смотреть на то как ведёт себя структура.

По моему «гетерогенный список» себя «ведёт» скорее как список нежели чем как кортеж.

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

Хлеб молотком резать это как растом вебню пилить.

А что из этого ты пробовал - резал хлеб молотком или пилил вебню на Rust?

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.