[Программирование, Scala] Scala 3 / Dotty – Факты и Мнения. Что мы ожидаем? (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Привет, Хабр. Для будущих студентов курса«Scala-разработчик» подготовили перевод материала.
Приглашаем также на открытый вебинар «Эффекты в Scala». Участники вместе с экспертом рассмотрят понятие эффекта и сложности, которые могут возникать при их наличии, а также рассмотрят понятие функционального эффекта и его свойства.
Что такое Scala 3?Scala 3 — это новая основная версия языка программирования Scala. Это результат многолетних исследований, разработок и сотрудничества между компаниями и организациями, которые координируют развитие Scala с помощью многих других людей и организаций, и которые вкладывают свое свободное время, чтобы сделать это возможным. Эти совместные усилия принесли нам наиболее заметные изменения в языке. Что мотивировало появление новой версии, которая связана с самой сутью Scala (а именно DOT-вычисления — причина, по которой Scala 3 начиналась как Dotty); в новой версии наблюдается повышение производительности и предсказуемости, что делает код более легким, интересным и безопасным; улучшение инструментария и бинарной совместимости; а также еще более дружелюбное отношение к новичкам.В этой статье мы выделим некоторые изменения, которые, по нашему мнению, имеют большую ценность для начинающих программистов Scala. Мы также поговорим о процессе миграции и бинарной совместимости. Наконец, в конце мы поделимся нашим мнением об этой новой версии.Scala 3 — новый язык?Да, это так, потому что в Scala есть много изменений в языке, включая функции, которые будут постепенно выводиться из употребления. А также потому, что процесс обучения отличается от предыдущих версий. Кроме того, там также будет обновляться база знаний. И одновременно, мы можем ответить нет на данный вопрос выше. Несмотря на изменения, о которых мы расскажем в этой статье, вдобавок ко многим другим, не упомянутым (чтобы статья не была слишком длинной), Scala 3 все еще остается Scala. Основные концепции остаются на месте, а поддержка кросс-билдинга усиливает то, что набор функций имеет большое пересечение с предыдущей версией. Почему происходит столь много изменений одновременно?В конце этой статьи вы будете задаваться вопросом, почему там сразу много меняется. Ответ в книге Scala 3. Она представляет собой сам язык. Выпуская все изменения сразу, нет необходимости каждый раз переписывать книгу, так как это делается с многими другими книгами. В основном, изменения затрагивают основы языка, упрощая жизнь его пользователей или заменяя существующие функции. Поэтому предстоящие изменения должны быть ограничены и расставлены по приоритетам в соответствии с основами, упрощениями и ограничениями. Тогда всё, что остаётся изменить в любых возможных более поздних версиях, будет больше связано с добавлением большей функциональности и выразительности, особенно для опытных пользователей, т.е. вещей, которые можно отложить и которые не оказывают резкого влияния на язык. Scala 3 — это новый Python 3?Существует необоснованное убеждение, что Scala 3 — это новый Python 3 относительно его совместимости с предыдущей версией. Однако, есть некоторые аргументы против этого мнения: а именно, что вам не нужно переносить все на Scala 3, так как есть бинарная совместимость с Scala 2.13 (подробнее об этом будет в разделе о миграции); вы можете уверенно мигрировать благодаря сильной системе типа Scala; и есть гораздо больше преимуществ при миграции с 2 на 3 в Scala, чем было бы при миграции с 2 на 3 на Python 3.Какие изменения ключевые?Мы выбрали некоторые ключевые функции, которые считаем более актуальными для начинающих программистов Scala. Мы их опишем и прокомментируем то, как они могут на нас повлиять. Мы не будем комментировать все новые возможности, потому что список слишком длинный. В любом случае, эта статья не будет учебным пособием по каждой функции. Если вы хотите увидеть список всех изменений, ссылок и других ресурсов, вы можете посмотреть это на dotty.epfl.ch.Optional Braces (опциональные или необязательные фигурные скобки)Одной из самых революционных новинок являются optional braces и использование правил отступа, как в случае с Python. Это действительно революционно, потому что визуально меняется код и это влияет на читабельность — достаточно, чтобы невнимательный читатель подумал, что это новый язык. В дополнение к тому, что это приводит к более «чистому и короткому коду». Optional braces — хорошая вещь, потому что:
- Мы зачастую пытаемся опустить фигурные скобки там, где это возможно (например, для методов/функций, которые состоят из одного выражения);
- Даже в случае со скобками почти каждый проект использует некоторые правила для отступов очень строго (это проверяется либо при просмотре кода, либо при принудительном применении scalafmt), так что скобки являются для нас лишь дополнительным токеном для регистрации во время чтения кода, и это не вводит никакой дополнительной информации.)
trait Printer:
def print(msg: String): Unit
class ConsolePrinter extends Printer:
def print(msg: String): Unit = println(msg)
class EmojiPrinter(underlying: Printer) extends Printer:
def print(msg: String): Unit =
val emoji = msg match
case ":)" => ?
case ":D" => ?
case ":|" => ?
case other => other
underlying.print(emoji)
Одним из недостатков использования правил отступов является распознавание того момента, когда заканчивается большая область отступов. Для решения этой проблемы Scala 3 предлагает end маркер.
class EmojiPrinter(underlying: Printer) extends Printer:
def print(msg: String): Unit =
if msg != null then
val emoji = msg match
case ":)" => ?
case ":D" => ?
case ":|" => ?
case other => other
underlying.print(emoji)
end if
end EmojiPrinter
Обратите внимание, что мы не ставим скобки, а также обратите внимание на then. Оба эти — и другие изменения — являются частью нового синтаксиса управления — еще одно изменение, которое визуально влияет на код.Помимо увеличения кодовой базы по сравнению с опцией работы со скобками, преимущество end маркеров по сравнению со скобками заключается в том, что вы можете маркировать замыкание. Таким образом, становится легче найти тот компонент, который замыкается.Не рекомендуется повсеместно ставить end маркер. Подсказка такая — использовать его, когда область отступов слишком длинная. Однако, определение «слишком длинный» может варьироваться от человека к человеку. Таким образом, в соответствии с официальной документацией, end маркер имеет смысл если:
- Конструктор содержит пустые строки, или
- Конструктор имеет 15 линий и более
- Конструктор имеет 4 уровня отступов и более
Согласно официальной документации, опциональные скобки являются экспериментальной функцией, т.е. их можно деактивировать. Кроме того, компилятор предупредит о любом плохо откорректированном коде. Более того, правило заключается в том, что добавление пары опциональных скобок не изменит смысла хорошо продуманной программы.EnumsПочти каждый программист Scala, работающий на Java, пропускает ключевое слово enum и концепцию, которую он воплощает. Представим, что до Scala 3 вам нужно было написать какой-нибудь шаблонный код, чтобы достичь чего-то похожего на перечисление:
sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color
В Scala 3, мы можем использовать стандартные типы enum:
enum Color:
case Red, Blue, Green
С годами все больше и больше код пишется с учетом безопасности типа. Такие концепции, как алгебраические типы данных (ADT), стали обычным явлением в системном моделировании. Поэтому было бы целесообразно предложить программистам более простой механизм реализации этих структур данных. Действительно, Scala 3 предлагает более простой способ реализации ADT через enums:
enum Option[+T]:
case Some(x: T) // extends Option[T] (omitted)
case None // extends Option[Nothing] (omitted)
Если вы хотите сделать ваш определенный Scala-enum совместимым с Java-enum, вам необходимо расширить java.lang.Enum, который импортируется по умолчанию:
enum Color extends Enum[Color]:
case Red, Blue, Green
println(Color.Green.compareTo(Color.Red)) // 2
Если вам интересен более сложный случай перечисления, например, с параметрами или обобщенными ADT, посмотрите на ссылку enums.Редизайн implicit (неявность)Несмотря на критику, implicit является одной из наиболее характерных черт Scala. Однако, она также является одной из самых противоречивых. Есть свидетельства о том, что implicit скорее является механизмом, чем реальным намерением, которое заключается в решении проблем. Более того, несмотря на то, что implicit легко сочетается с множеством конструкторов, становится не так легко, когда речь заходит о предотвращении нарушений и неправомерного использования. Поэтому Scala 3 редизайнит особенности implicit, ставя каждый случай использования на своё место. Ниже приведены изменения, которые мы считаем наиболее актуальными в отношении implicit редизайна.Implicit определения → Заданные экземплярыВ данном случае речь идет о том, как Scala 3 использует синтез контекстных параметров для определенного типа. Она заменяет предыдущее implicit использование для этой цели. В Scala 3 вы можете дополнительно указывать имя заданного экземпляра. Если вы пропустите это имя, то компилятор выведет его.
trait Ord[T]:
def compare(a: T, b: T): Int
given intOrd: Ord[Int] with // with name
def compare(a: Int, b: Int): Int = a - b
given Order[String] with // without name
def compare(a: String, b: String): Int = a.compareTo(b)
Implicit параметры → Использование clausesКонтекстные параметры (или implicit параметры) помогают избежать написания повторяющихся параметров по цепочке вызовов. В Scala 3 вы используете implicit параметры через ключевое слово using. Например, из приведенных выше примеров можно определить функцию min , которая работает с ними.
def min[T](a: T, b: T)(using ord: Ord[T]): T =
if ord.compare(a, b) < 0 then a else b
min(4, 2)min(1, 2)(using intOrd)
min("Foo", "Bar")
Когда вам нужно просто переадресовать параметры контекста, вам не нужно их называть.
def printMin[T](a: T, b: T)(using Ord[T]): Unit =
println(min(a, b))
Implicit Импорт → Заданный ИмпортБывают случаи, когда неправильный implicit импорт может стать причиной проблемы Кроме того, некоторые инструменты, такие как IDE и генераторы документации, не справляются с implicit импортом. Scala 3 предоставляет новый способ отличить заданный импорт от обычного.
object A:
class TC
given tc: TC = ???
def f(using TC) = ???
object B:
import A._
import A.given
...
В приведенном выше примере нам пришлось импортировать заданные импорты отдельно, даже после импорта с помощью wildcad (_), потому что в Scala 3 заданные импорты работают не так, как обычные. Вы можете объединить оба импорта в один.
object C:
import A.{using, _}
Вот некоторые спецификации, касающиеся заданных импортов по типам. Посмотрите на данную импортную документацию. Implicit Conversion → Заданная ConversionПредставим, что до Scala 3, если вы хотели определить Implicit Conversion, вам просто нужно было написать Implicit Conversion, которое получает экземпляр исходного типа и возвращает экземпляр целевого типа. Теперь нужно определить данный экземпляр класса scala.Conversion, который ведет себя как функция. Действительно, экземпляры scala. Conversion — это функции. Посмотрите на их определение.
abstract class Conversion[-T, +U] extends (T => U):
def apply (x: T): U
Например, здесь можно посмотреть на преобразование от Int к Double и на более короткую версию:
given int2double: Conversion[Int, Double] with
def apply(a: Int): Double = a.toDouble
given Conversion[Int, Double] = _.toDouble
Основной причиной использования Заданной Conversion является наличие специального механизма преобразования стоимости без каких-либо сомнительных конфликтов с другими конструкторами языка. Согласноданной документации по преобразованию, все другие формы implicit преобразований будут постепенно ликвидированы.Implicit классы → Методы расширенияМетоды расширения являются более интуитивным и менее шаблонным способом, чем Implicit классы для добавления методов к уже определенным типам.
case class Image(width: Int, height: Int, data: Array[Byte])
extension (img: Image)
def isSquare: Boolean = img.width == img.height
val image = Image(256, 256, readBytes("image.png"))
println(image.isSquare) // true
Методы расширения могут иметь параметры типа как в их определении, так и в их методах. Их определения также могут иметь несколько методов.
extension [T](list: List[T])
def second: T = list.tail.head
def heads: (T, T) = (list.head, second)
Как видите, методы расширения гораздо «чище», чем написание implicit классов. Обратите внимание, что в отличие от implicit классов, вам не нужно называть определения расширений.Типы пересечения и соединенияScala 3 предоставляет новые способы объединения типов, два из которых — Типы пересечения и соединения.Типы пересеченияТипы пересечения — это типы, элементы которых принадлежат к обоим типам, составляющим его. Они определяются оператором & более двух типов. & являются коммутаторами: A & B производит один и тот же тип B & A. Они также могут быть сцеплены, так как они тоже являются типами.
trait Printable[T]:
def print(x: T): Unit
trait Cleanable:
def clean(): Unit
trait Flushable:
def flush(): Unit
def f(x: Printable[String] & Cleanable & Flushable) =
x.print("working on...")
x.flush()
x.clean()
Вам может быть интересно узнать, как компилятор решает конфликты разделяемых элементов. Ответ состоит в том, что компилятор в этом не нуждается. Типы пересечений представляют собой требования к members типам (члены типов). Они работают практически так же, как и при формировании типов. В момент построения members необходимо просто убедиться, что все полученные members определены корректно.
trait A:
def parent: Option[A]
trait B:
def parent: Option[B]
class C extends A,B:
def parent: Option[A & B] = None
// or
// def parent: Option[A] & Option[B] = Nil
def work(x: A & B) =
val parent:[A & B] = x.parent
// or
// val parent: Option[A] & Option[B] = x.parent
println(parent) // None
work(new C)
Заметьте, что в in class C нам нужно решить конфликты связанные с тем, что children member появляется и в A и в B. То есть тип C — это пересечение его типа в A и его типа в B, например, Option[A] & Option[B] могут быть упрощены в вид Option[A & B], так как Option (опция) является ковариантной.Типы соединенияТип соединения A | B принимает все экземпляры типа A и все экземпляры типа B. Обратите внимание, что мы говорим об экземплярах, а не о members (членах), как это делают типы пересечения. Поэтому, если мы хотим получить доступ к его members, нам нужно сопоставить их по шаблону.
def parseFloat(value: String | Int): Float =
value match
case str: String => str.toFloat
case int: Int => int.floatValue
parseFloat("3.14") // 3.14
parseFloat(42) // 42.0
Типы соединения не выводятся автоматически. Если вы хотите, чтобы тип определения (val, var или def) был типом соединения, вам нужно сделать это явно, иначе компилятор выведет наименьший общий ancestor (предок).
val any = if (cond) 42 else "3.14" // Any
val union: String | Int = if (cond) 42 else "3.14" // String | Int
Почётные упоминанияНекоторые другие изменения довольно актуальны и также заслуживают здесь упоминания.Трейт параметры Scala 3 позволяет трейтам иметь параметры. Эти параметры оцениваются непосредственно перед инициализацией трейта. Параметры трейта являются заменой для ранних инициализаторов, которые были удалены из Scala 3.Универсальные применяемые методыКонструкторы Case class стали достаточно популярными, и многие разработчики пишут Case class просто для того, чтобы не писать new для создания объектов. Поэтому в Scala 3 больше не нужно писать new для создания экземпляров классов. Типы Opaque Opaque-типы обеспечивают абстракцию типа без каких-либо перегрузок. Модифицируя определение типа с помощью Opaque, вы ограничиваете тот факт, что определение типа является просто псевдонимом для другого типа, где оно определено. Для клиентов своей области видимости Opaque-типы ведут себя идеально как тип, а не просто как псевдоним. Таким образом, например, вы не можете предполагать существование псевдонима для создания значений псевдонима и присвоения определений Opaque-типу.Export clausesExport clauses — это простой способ передачи members (членов) от одного типа к другому без какого-либо наследования. Откладывая export от членов-класса (включая трейты и объекты) в тело другого класса (также включая трейты и объекты), вы копируете members и делаете их доступными через экземпляры целевых классов. Редизайн метапрограммированияВ Scala 2 макросы оставались экспериментальной функцией. В связи с тем, что макросы сильно зависят от компилятора Scala 2, поэтому мигрировать на Scala 3 оказалось невозможным. В метапрограммировании Scala 3 появились новые конструкции, облегчающие его использование. Взгляните на обзор метапрограммирования Scala 3.Ограничения и удаленные фитчиЧтобы упростить язык и сделать его более безопасным, Scala 3 ограничивает количество опций и снимает некоторые функции с производства. Самые важные из них:
- Ограничение проекций типов (C#P) только в отношении классов, т.е. абстрактные типы больше не поддерживают их;
- Для использования надстрочной нотации, модификатор infix должен быть помечен на желаемых методах;
- Мультиверсальное равенство - это оптический способ избегания неожиданных равнозначностей;
- Implicit преобразования и приведенные выше импорты также являются видами ограничений;
- Специальная обработка трейта DelayedInit больше не поддерживается;
- Отброшен синтаксис процедуры (опускание типа возврата и = при определении функции);
- Библиотеки XML все еще поддерживаются, но будут удалены в ближайшем будущем;
- Автоматическое приложение, когда пустой список аргументов () неявно вставляется при вызове метода без аргументов и больше не поддерживается;
- Символьные литералы больше не поддерживаются.
Полный список выпавших функций доступен в официальной документации.Нужно ли вам переходить на Scala 3?Прежде всего, есть очень хорошо сделанная документация, посвященная исключительно переходу на Scala 3. Здесь мы просто поделимся некоторыми мыслями, которые вы можете учесть, когда начнете использовать Scala 3 в своих текущих проектах.Хорошо известно, что рекомендуется быть в курсе работы со стеком технологий и зависимостями, так как они могут исправлять ошибки и улучшать удобство использования, производительность и так далее. Это также относится и к Scala. Независимо от того, насколько мало усилий прилагается для перехода, иногда необходимо согласовать это с заинтересованными сторонами. Тем не менее, миграция Scala 3 была спроектирована так, чтобы быть как можно более плавной. Это означает, что вы можете воспользоваться самыми заметными эволюциями в языке и сделать программирование более легким, интересным и безопасным. Какое время подходит для перехода на Scala 3?Мы хотели бы порекомендовать вам перейти на Scala 3 прямо сейчас, но мы знаем, что есть факторы, выходящие за рамки возможностей даже большого энтузиазма. Если следующее звучит как отличный аргумент, чтобы убедить вашего руководителя, то не забывайте, что Scala 3 сохраняет как обратную, так и прямую совместимость с Scala 2.13 (за исключением макросов), не всю совместимость, но при каждой несовместимости есть решение для кросс-компиляции.Что такое бинарная совместимость в Scala 3?Scala 3 предлагает обратную двоичную совместимость с Scala 2. Это означает, что вы все еще можете полагаться на библиотеку Scala 2. Начиная с версии Scala 2.13.4, выпущенной в ноябре 2020 года, вы можете использовать библиотеки, написанные на Scala 3. Таким образом, в Scala 3 вы получаете двойную совместимость туда и обратно. Scala 3 поддерживает обратную и прямую совместимость с помощью уникального революционного механизма в экосистеме Scala. Scala 3 выводит файлы TASTy и поддерживает Pickle из версий Scala 2.x. Scala 2.13.4 поставляется с считывателями TASTy, поэтому поддерживает как все традиционные функции, так и новые, такие как Enums, Intersection types (типы соединения) и другие. Дополнительные сведения см. в руководстве по совместимости. ЗаключениеМы очень рады новой версии нашего основного языка. Она сопровождается таким количеством интересных изменений, хорошо и тщательно продуманных миграций, что невозможно либо не вписать ее в следующий проект, либо не начать рефакторинг уже существующих.В целом, мне кажется, что Scala 3 — это отличная доработка Scala 2. Мы научились жить без многих вещей: для одних это были библиотеки, решавшие проблемы в той или иной степени с ограничениями, для других это было либо невозможно, либо выходило за пределы их зоны комфорта. Поэтому, как только Scala 3 получит широкое распространение, мы ожидаем увидеть более грамотно написанный код, в основном потому, что там это намного проще.
Узнать подробнее о курсе «Scala-разработчик».Смотреть открытый вебинар «Эффекты в Scala».
===========
Источник:
habr.com
===========
===========
Автор оригинала: EMANUEL OLIVEIRA
===========Похожие новости:
- [Системное администрирование, Программирование, DevOps, Микросервисы, Serverless] Интересное о Serverless: хабрастатьи о применении, инструментах, кейсах и инструкциях для первого свидания
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 4 (перевод)
- [Python, Django, Машинное обучение, Конференции] «Хитрый питон» Михаил Корнеев, Григорий Петров, Илья Беда и другие классные спикеры-тезисы выступлений на PyCon Weekend
- [Программирование, Разработка мобильных приложений, Разработка под Android, Kotlin] Влияние data-классов на вес приложения
- [Программирование, Git, GitHub, Лайфхаки для гиков] Продвинутые функции гита, о которых вы, возможно, не знали (перевод)
- [Программирование, Хакатоны, Управление разработкой, Учебный процесс в IT, Развитие стартапа] Фонд «Сколково» и IQпарк Уфы запускают онлайн-хакатон UFA SuperHero с призовым фондом 300 000 рублей
- [Программирование] Некоторые программистские заблуждения о времени
- [Карьера в IT-индустрии, Финансы в IT] Dice и Hired опубликовали ежегодную статистику самых высоких зарплат программистов в США
- [Python, Программирование, Машинное обучение] Как ML помогает при аудите качества клиентского сервиса
- [Разработка систем связи, Программирование микроконтроллеров] Составное устройство USB на STM32. Часть 2: USB Audio Speaker
Теги для поиска: #_programmirovanie (Программирование), #_scala, #_scala, #_dotty, #_python, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
), #_programmirovanie (
Программирование
), #_scala
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:50
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Привет, Хабр. Для будущих студентов курса«Scala-разработчик» подготовили перевод материала.
Приглашаем также на открытый вебинар «Эффекты в Scala». Участники вместе с экспертом рассмотрят понятие эффекта и сложности, которые могут возникать при их наличии, а также рассмотрят понятие функционального эффекта и его свойства. Что такое Scala 3?Scala 3 — это новая основная версия языка программирования Scala. Это результат многолетних исследований, разработок и сотрудничества между компаниями и организациями, которые координируют развитие Scala с помощью многих других людей и организаций, и которые вкладывают свое свободное время, чтобы сделать это возможным. Эти совместные усилия принесли нам наиболее заметные изменения в языке. Что мотивировало появление новой версии, которая связана с самой сутью Scala (а именно DOT-вычисления — причина, по которой Scala 3 начиналась как Dotty); в новой версии наблюдается повышение производительности и предсказуемости, что делает код более легким, интересным и безопасным; улучшение инструментария и бинарной совместимости; а также еще более дружелюбное отношение к новичкам.В этой статье мы выделим некоторые изменения, которые, по нашему мнению, имеют большую ценность для начинающих программистов Scala. Мы также поговорим о процессе миграции и бинарной совместимости. Наконец, в конце мы поделимся нашим мнением об этой новой версии.Scala 3 — новый язык?Да, это так, потому что в Scala есть много изменений в языке, включая функции, которые будут постепенно выводиться из употребления. А также потому, что процесс обучения отличается от предыдущих версий. Кроме того, там также будет обновляться база знаний. И одновременно, мы можем ответить нет на данный вопрос выше. Несмотря на изменения, о которых мы расскажем в этой статье, вдобавок ко многим другим, не упомянутым (чтобы статья не была слишком длинной), Scala 3 все еще остается Scala. Основные концепции остаются на месте, а поддержка кросс-билдинга усиливает то, что набор функций имеет большое пересечение с предыдущей версией. Почему происходит столь много изменений одновременно?В конце этой статьи вы будете задаваться вопросом, почему там сразу много меняется. Ответ в книге Scala 3. Она представляет собой сам язык. Выпуская все изменения сразу, нет необходимости каждый раз переписывать книгу, так как это делается с многими другими книгами. В основном, изменения затрагивают основы языка, упрощая жизнь его пользователей или заменяя существующие функции. Поэтому предстоящие изменения должны быть ограничены и расставлены по приоритетам в соответствии с основами, упрощениями и ограничениями. Тогда всё, что остаётся изменить в любых возможных более поздних версиях, будет больше связано с добавлением большей функциональности и выразительности, особенно для опытных пользователей, т.е. вещей, которые можно отложить и которые не оказывают резкого влияния на язык. Scala 3 — это новый Python 3?Существует необоснованное убеждение, что Scala 3 — это новый Python 3 относительно его совместимости с предыдущей версией. Однако, есть некоторые аргументы против этого мнения: а именно, что вам не нужно переносить все на Scala 3, так как есть бинарная совместимость с Scala 2.13 (подробнее об этом будет в разделе о миграции); вы можете уверенно мигрировать благодаря сильной системе типа Scala; и есть гораздо больше преимуществ при миграции с 2 на 3 в Scala, чем было бы при миграции с 2 на 3 на Python 3.Какие изменения ключевые?Мы выбрали некоторые ключевые функции, которые считаем более актуальными для начинающих программистов Scala. Мы их опишем и прокомментируем то, как они могут на нас повлиять. Мы не будем комментировать все новые возможности, потому что список слишком длинный. В любом случае, эта статья не будет учебным пособием по каждой функции. Если вы хотите увидеть список всех изменений, ссылок и других ресурсов, вы можете посмотреть это на dotty.epfl.ch.Optional Braces (опциональные или необязательные фигурные скобки)Одной из самых революционных новинок являются optional braces и использование правил отступа, как в случае с Python. Это действительно революционно, потому что визуально меняется код и это влияет на читабельность — достаточно, чтобы невнимательный читатель подумал, что это новый язык. В дополнение к тому, что это приводит к более «чистому и короткому коду». Optional braces — хорошая вещь, потому что:
trait Printer:
def print(msg: String): Unit class ConsolePrinter extends Printer: def print(msg: String): Unit = println(msg) class EmojiPrinter(underlying: Printer) extends Printer: def print(msg: String): Unit = val emoji = msg match case ":)" => ? case ":D" => ? case ":|" => ? case other => other underlying.print(emoji) class EmojiPrinter(underlying: Printer) extends Printer:
def print(msg: String): Unit = if msg != null then val emoji = msg match case ":)" => ? case ":D" => ? case ":|" => ? case other => other underlying.print(emoji) end if end EmojiPrinter
sealed trait Color
case object Red extends Color case object Green extends Color case object Blue extends Color enum Color:
case Red, Blue, Green enum Option[+T]:
case Some(x: T) // extends Option[T] (omitted) case None // extends Option[Nothing] (omitted) enum Color extends Enum[Color]:
case Red, Blue, Green println(Color.Green.compareTo(Color.Red)) // 2 trait Ord[T]:
def compare(a: T, b: T): Int given intOrd: Ord[Int] with // with name def compare(a: Int, b: Int): Int = a - b given Order[String] with // without name def compare(a: String, b: String): Int = a.compareTo(b) def min[T](a: T, b: T)(using ord: Ord[T]): T =
if ord.compare(a, b) < 0 then a else b min(4, 2)min(1, 2)(using intOrd) min("Foo", "Bar") def printMin[T](a: T, b: T)(using Ord[T]): Unit =
println(min(a, b)) object A:
class TC given tc: TC = ??? def f(using TC) = ??? object B: import A._ import A.given ... object C:
import A.{using, _} abstract class Conversion[-T, +U] extends (T => U):
def apply (x: T): U given int2double: Conversion[Int, Double] with
def apply(a: Int): Double = a.toDouble given Conversion[Int, Double] = _.toDouble case class Image(width: Int, height: Int, data: Array[Byte])
extension (img: Image) def isSquare: Boolean = img.width == img.height val image = Image(256, 256, readBytes("image.png")) println(image.isSquare) // true extension [T](list: List[T])
def second: T = list.tail.head def heads: (T, T) = (list.head, second) trait Printable[T]:
def print(x: T): Unit trait Cleanable: def clean(): Unit trait Flushable: def flush(): Unit def f(x: Printable[String] & Cleanable & Flushable) = x.print("working on...") x.flush() x.clean() trait A:
def parent: Option[A] trait B: def parent: Option[B] class C extends A,B: def parent: Option[A & B] = None // or // def parent: Option[A] & Option[B] = Nil def work(x: A & B) = val parent:[A & B] = x.parent // or // val parent: Option[A] & Option[B] = x.parent println(parent) // None work(new C) def parseFloat(value: String | Int): Float =
value match case str: String => str.toFloat case int: Int => int.floatValue parseFloat("3.14") // 3.14 parseFloat(42) // 42.0 val any = if (cond) 42 else "3.14" // Any
val union: String | Int = if (cond) 42 else "3.14" // String | Int
Узнать подробнее о курсе «Scala-разработчик».Смотреть открытый вебинар «Эффекты в Scala».
=========== Источник: habr.com =========== =========== Автор оригинала: EMANUEL OLIVEIRA ===========Похожие новости:
Блог компании OTUS. Онлайн-образование ), #_programmirovanie ( Программирование ), #_scala |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:50
Часовой пояс: UTC + 5