Groovy Logo | |
Paradigm | Объектно-ориентированный, императив, скриптинг |
---|---|
Разработано | Джеймсом Страчаном |
разработчиком | Гийомом Лафоржем (председатель PMC). Йохен Теодору (технический руководитель). Пол Кинг. Седрик Шампо |
Впервые появился | 2003; 17 лет назад (2003 г.) |
Стабильный выпуск | 3.0.6 (26 сентября 2020 г.; 28 дней назад (2020-09-26)) |
Дисциплина набора текста | Динамический, static, strong, duck |
Платформа | Java SE |
Лицензия | Лицензия Apache 2.0 |
Расширения имен файлов | .groovy,.gvy,.gy,.gsh |
Веб-сайт | groovy-lang.org |
Основные реализации | |
Gradle, Grails | |
Под влиянием | |
Java, Python, Ruby, Smalltalk | |
Influenced | |
Kotlin |
Apache Groovy - это Java -синтаксис -совместимый объектно-ориентированный язык программирования для платформы Java. Это как статический, так и динамический язык с функциями, аналогичными функциям Python, Ruby и Smalltalk. Он может использоваться как язык программирования, так и язык сценариев для платформы Java, скомпилирован в виртуальную машину Java (JVM) байт-код и без проблем взаимодействует с другим кодом Java и библиотеками. Groovy использует синтаксис фигурных скобок , аналогичный синтаксису Java. Groovy поддерживает замыкания, многострочные строки и выражения, встроенные в строки. Большая часть возможностей Groovy заключается в его преобразованиях AST, запускаемых с помощью аннотаций.
Groovy 1.0 был выпущен 2 января 2007 г., а Groovy 2.0 - в июле 2012 г. Начиная с версии 2, Groovy можно скомпилировать статически, предлагая вывод типов и производительность близка к Java. Groovy 2.4 был последним крупным выпуском под спонсорством Pivotal Software, который закончился в марте 2015 года. С тех пор Groovy изменил свою структуру управления на Комитет по управлению проектами в Apache Software Foundation.
Джеймс Стрэчэн впервые рассказал о разработке Groovy в своем блоге в августе 2003 года. В марте 2004 года Groovy был представлен в JCP как JSR 241 и принят голосованием. В период с 2004 по 2006 год было выпущено несколько версий. После начала усилий по стандартизации Java Community Process (JCP) нумерация версий изменилась, и 2 января 2007 года была выпущена версия под названием «1.0». После нескольких бета-версий и выпуски кандидатов под номером 1.1, 7 декабря 2007 г. был выпущен Groovy 1.1 Final и сразу же переименован в Groovy 1.5, чтобы отразить многие внесенные изменения.
В 2007 году Groovy выиграл первый приз на конкурсе JAX 2007 за инновации. В 2008 году Grails, веб-фреймворк на Groovy , получил вторую премию на конкурсе инноваций JAX 2008.
В ноябре 2008 года SpringSource приобрел компания Groovy и Grails (G2One). В августе 2009 года VMware приобрела SpringSource.
В апреле 2012 года, после восьми лет бездействия, специалист по спецификации изменил статус JSR 241 на бездействующий.
Страчан ушел за год до выпуска Groovy 1.0 в 2007 году. В октябре 2016 года Страчан заявил: «Я все еще люблю Groovy (конвейеры jenkins такие классные!), java, go, машинописный текст и котлин».
В июле 2, 2012 был выпущен Groovy 2.0, который, среди других новых функций, добавил статическую компиляцию и статическую проверку типов.
. Когда Pivotal Software выделила совместное предприятие EMC Корпорация (EMC) и VMware в апреле 2013 года Groovy и Grails вошли в ее портфель продуктов. Pivotal прекратил спонсирование Groovy и Grails с апреля 2015 года. В том же месяце Groovy изменил свою структуру управления с репозитория Codehaus на Комитет по управлению проектами (PMC) в Apache Software Foundation через свой инкубатор. Groovy закончил инкубатор Apache и стал проектом верхнего уровня в ноябре 2015 года.
Наиболее допустимые файлы Java также являются допустимыми файлами Groovy. Хотя эти два языка похожи, код Groovy может быть более компактным, поскольку ему не нужны все элементы, необходимые Java. Это позволяет программистам на Java постепенно изучать Groovy, начиная со знакомого синтаксиса Java, прежде чем приобретать больше идиом программирования Groovy .
Функции Groovy, недоступные в Java, включают как статическую, так и динамическую типизацию (с ключевое слово def
), перегрузка оператора, собственный синтаксис для списков и ассоциативных массивов (карты), встроенная поддержка регулярных выражений, полиморфная итерация, строковая интерполяция, добавлены вспомогательные методы и оператор безопасной навигации ?.
для автоматической проверки нулевых указателей (например, переменная?.Method ()
или переменная?.Field
).
Начиная с версии 2 Groovy также поддерживает модульность (возможность отправлять только необходимые jar-файлы в соответствии с потребностями проекта, уменьшая таким образом размер библиотеки Groovy), проверку типов, статичность компиляция, усовершенствования синтаксиса Project Coin, блоки многократной выборки и постоянное повышение производительности с использованием инструмента invokedynamic
Функция, представленная в Java 7.
Groovy обеспечивает встроенную поддержку различных языков разметки, таких как XML и HTML, с помощью встроенного Синтаксис объектной модели документа (DOM). Эта функция позволяет определять и управлять многими типами разнородных активов данных с помощью единообразного и краткого синтаксиса и методологии программирования.
В отличие от Java, файл исходного кода Groovy может быть выполнен как (некомпилированный) скрипт, если он содержит код вне определения класса, если это класс с основным методом, или если это Runnable или GroovyTestCase. Сценарий Groovy полностью анализируется, компилируется и генерируется перед выполнением (аналогично Python и Ruby). Это происходит под капотом, и скомпилированная версия не сохраняется как артефакт процесса.
GroovyBeans - это Groovy-версия JavaBeans. Groovy неявно генерирует геттеры и сеттеры. В следующем коде неявно генерируются setColor (String color)
и getColor ()
. Последние две строки, которые, похоже, обращаются к цвету напрямую, на самом деле вызывают неявно сгенерированные методы.
class AGroovyBean {String color} def myGroovyBean = new AGroovyBean () myGroovyBean.setColor ('baby blue') assert myGroovyBean.getColor () == 'голубой' myGroovyBean.color = 'pewter' assert myGroovyBean.color == 'pewter'
Groovy предлагает простой и последовательный синтаксис для обработки списков и карт, напоминающий синтаксис массивов Java.
def movieList = ['Dersu Uzala', 'Ran', 'Seven Samurai'] // Выглядит как массив, но представляет собой список assert movieList [2] == 'Seven Samurai' movieList [3] = 'Casablanca' // Добавляет элемент в список assert movieList.size () == 4 def monthMap = ['Январь': 31, 'Февраль': 28, 'Март': 31] // Объявляет карту assert monthMap ['Март'] == 31 / / Доступ к записи monthMap ['April'] = 30 // Добавляет запись на карту assert monthMap.size () == 4
Groovy предлагает поддержку расширения прототипа - ExpandoMet aClass
, модули расширения (только в Groovy 2), Objective-C-like Categories и DelegatingMetaClass
.
ExpandoMetaClass
предлагает предметно-ориентированный язык (DSL), чтобы легко выразить изменения в классе, аналогично концепции открытого класса Ruby :
Number.metaClass {sqrt = {Math.sqrt (delegate)}} assert 9.sqrt () = = 3 assert 4.sqrt () == 2
Изменения кода Groovy в результате создания прототипов не видны в Java, поскольку каждый вызов атрибута / метода в Groovy проходит через реестр метакласса. Доступ к измененному коду можно получить только из Java, перейдя в реестр метакласса.
Groovy также позволяет переопределять методы, такие как getProperty ()
, propertyMissing ()
среди других, что позволяет разработчику перехватывать вызовы объекта и указывать для них действие, упрощенным способом аспектно-ориентированным. Следующий код позволяет классу java.lang.String
отвечать на свойство hex
:
enum Color {BLACK ('# 000000'), WHITE ('# FFFFFF'), КРАСНЫЙ ('# FF0000'), СИНИЙ ('# 0000FF') Шестнадцатеричная строка Цвет (Шестнадцатеричная строка) {this.hex = hex}} String.metaClass.getProperty = {Свойство строки ->def stringColor = делегировать if (свойство == 'hex') {Color.values (). find {it.name (). equalsIgnoreCase stringColor} ?. hex}} assert "WHITE".hex == "#FFFFFF" assert "BLUE".hex == " # 0000FF "assert" BLACK ".hex ==" # 000000 "assert" GREEN ".hex == null
Платформа Grails широко использует метапрограммирование для включения динамических средств поиска GORM, например User.findByName ('Josh')
и другие.
Синтаксис Groovy позволяет в некоторых ситуациях опускать круглые скобки и точки. Следующий отличный код
take (кофе).with (сахар, молоко).and (ликер)
может быть записан как
взять кофе с сахаром, молоком и ликером
, что позволяет развивать предметно-ориентированные языки (DSL), которые выглядят как простой английский.
Хотя Groovy в основном является объектно-ориентированным языком, он также предлагает функции функционального программирования.
Согласно документации Groovy: «Замыкания в Groovy работают аналогично« указателю на метод », позволяя писать и запускать код в более поздний момент времени». Замыкания Groovy поддерживают свободные переменные, т. Е. Переменные, которые не были явно переданы ему в качестве параметра, но существуют в контексте его объявления, частичное приложение (которое называется «каррирование »), делегирование, неявные, типизированные и нетипизированные параметры.
При работе с коллекциями определенного типа можно сделать вывод о замыкании, переданном операции над коллекцией:
list = [1, 2, 3, 4, 5, 6, 7, 8, 9] / * * Ненулевые числа приводятся к истине, поэтому, когда% 2 == 0 (даже), это ложь. * Тип неявного параметра "it" может быть определен средой IDE как целое число. * Его можно также записать как: * list.findAll {Integer i ->i% 2} * list.findAll {i ->i% 2} * / def odds = list.findAll {it% 2} assert odds == [1, 3, 5, 7, 9]
Группа выражений может быть записана в закрывающем блоке без ссылки на реализацию, а отвечающий объект может быть назначен позже с помощью делегирования:
// Это блок кода содержит выражения без ссылки на реализацию def operations = {declare 5 sum 4 div 3 print}
/ * * Этот класс будет обрабатывать операции, которые можно использовать в приведенном выше закрытии. Другой класс * может быть объявлен с теми же методами, но с использованием, например, операций веб-сервиса * в вычислениях. * / class Expression {BigDecimal value / * * Хотя целое число передается в качестве параметра, оно преобразуется в BigDecimal, как * было определено. Если бы у класса был метод declare (Integer value), он бы использовался вместо него. * / def declare (BigDecimal value) {this.value = value} def sum (BigDecimal valueToAdd) {this.value + = valueToAdd} def div (BigDecimal divisor) {this.value / = divisor} def propertyMissing (String property) { if (property == "print") println value}}
// Здесь определяется, кто будет отвечать на выражения в блоке кода выше. operations.delegate = new Expression () operations ()
Эта функция Groovy, обычно называемая частичным приложением, позволяет задавать параметрам замыканий значение по умолчанию в любом из их аргументы, создавая новое замыкание со связанным значением. Передача одного аргумента методу curry ()
исправит первый аргумент. Подача N аргументов исправит аргументы 1.. N.
def joinTwoWordsWithSymbol = {symbol, first, second ->first + symbol + second} assert joinTwoWordsWithSymbol ('#', 'Hello', 'World') == 'Hello #World 'def concatWords = joinTwoWordsWithSymbol.curry (' ') assert concatWords (' Hello ',' World ') ==' Hello World 'def prependHello = concatWords.curry (' Hello ') // def prependHello = joinTwoWordsWithSymbol.curry ( '', 'Hello') assert prependHello ('World') == 'Hello World'
Карри также можно использовать в обратном направлении (фиксация аргументов N в N - 1) с помощью rcurry ()
.
def power = {BigDecimal value, BigDecimal power ->value ** power} def square = power.rcurry (2) def cube = power.rcurry (3) assert power (2, 2) == 4 assert square (4) == 16 assert cube (3) == 27
Groovy также поддерживает ленивое вычисление, сокращение / свертывание, бесконечные структуры и неизменяемость и др.
В нотации объектов JavaScript (JSON ) и При обработке XML Groovy использует шаблон Builder, что упрощает создание структуры данных. Например, следующий XML:
Java объектно-ориентированный статический Ruby функциональный, объектно-ориентированный утиная типизация, динамический Groovy функциональный, объектно-ориентированный утиная типизация, динамический, статический
может быть сгенерирован с помощью следующего кода Groovy:
def writer = new StringWriter () def builder = новый groovy.xml.MarkupBuilder (писатель) builder.languages {язык (год: 1995) {название "парадигмы Java" "объектно-ориентированный" типизирующий "статический"} язык (год: 1995) {название "парадигмы" Ruby "" функциональный, объектно-ориентированная "типизация" утиная типизация, динамический "} язык (год: 2003) {название" Groovy "парадигма" функциональная, объектно-ориентированная "типизация" утиная типизация, динамическая, статическая "}}
и также может обрабатываться в потоковый путь через StreamingMarkupBuilder
. Чтобы изменить реализацию на JSON, MarkupBuilder
можно заменить на JsonBuilder
.
. Для его анализа и поиска функционального языка может служить метод Groovy findAll
:
def languages = new XmlSlurper (). parseText writer.toString () // Здесь используется синтаксис Groovy regex для сопоставления (= ~), который будет приведен к // логическому значению: либо true, если значение содержит нашу строку или false в противном случае. def function = languages.language.findAll {it.paradigm = ~ "function"} assert financial.collect {it.name} == ["Groovy", "Ruby"]
В Отлично, строки могут быть интерполированы с помощью переменных и выражений с помощью GStrings:
BigDecimal account = 10.0 def text = "В аккаунте отображается текущий баланс $ account" assert text == "В аккаунте отображается текущий баланс 10.0"
Строки GString, содержащие переменные и выражения, должны быть объявлены с использованием двойных кавычек.
Сложное выражение должно быть заключено в фигурные скобки. Это предотвращает интерпретацию его частей как принадлежащих к окружающей строке, а не к выражению:
BigDecimal minus = 4.0 text = "В аккаунте отображается текущий баланс $ {account - minus}" assert text == " аккаунт показывает текущий баланс 6.0 "// Без скобок для выделения выражения это привело бы к следующему: text =" В аккаунте в настоящее время отображается баланс $ account - минус "assert text ==" В аккаунте в настоящее время отображается баланс 10.0 - minus "
Оценка выражения может быть отложена с помощью синтаксиса стрелки:
BigDecimal tax = 0.15 text =" В аккаунте отображается текущий баланс $ {->account - account * tax} "tax = 0.10 // значение налога было изменено ПОСЛЕ декларирования GString. Выражение // переменные связываются только тогда, когда выражение должно быть фактически вычислено: assert text == "В аккаунте в настоящее время отображается баланс 9.000"
Согласно собственной документации Groovy, " Когда компилятор Groovy компилирует скрипты и классы Groovy, в какой-то момент процесса исходный код будет представлен в памяти в виде конкретного синтаксического дерева, а затем преобразован в абстрактное синтаксическое дерево. Цель преобразований AST - чтобы позволить разработчикам подключиться к процессу компиляции, чтобы иметь возможность изменять AST до того, как он будет преобразован в байт-код, который будет запускаться JVM. AST Transformations предоставляет Groovy улучшенные возможности метапрограммирования во время компиляции, обеспечивающие высокую гибкость на уровне языка, без снижение производительности во время выполнения. "
Примеры AST в Groovy:
среди других.
Согласно документации Groovy, «Traits - это структурная конструкция языка, которая позволяет: составление поведений, реализацию интерфейсов во время выполнения, переопределение поведения и совместимость. с проверкой / компиляцией статического типа ".
Признаки можно рассматривать как интерфейсы, несущие как реализации по умолчанию, так и состояние. Признак определяется с помощью ключевого слова признака:
признак FlyingAbility {/ * объявление признака * / String fly () {"Я летаю!" } / * объявление метода внутри признака * /}
Затем его можно использовать как обычный интерфейс, используя ключевое слово реализует
:
класс Bird реализует FlyingAbility {} / * Добавляет трейт FlyingAbility к Возможности класса Bird * / def bird = new Bird () / * создать экземпляр новой Bird * / assert bird.fly () == "Я лечу!" / * класс Bird автоматически получает поведение черты FlyingAbility * /
Черты позволяют использовать широкий спектр возможностей, от простой композиции до тестирования.
Примечательные примеры внедрения Groovy включают:
Многие интегрированные среды разработки (IDE) и поддерживают Groovy:
Существует одна альтернативная реализация Groovy: