Groovy: различия между версиями
Содержимое удалено Содержимое добавлено
Kalendar (обсуждение | вклад) орфография |
DannyS712 (обсуждение | вклад) м <source> -> <syntaxhighlight> (phab:T237267) |
||
Строка 4:
Откройте редактор и напишите программу. По традиции, первая программа должна просто выводить приветствие миру:
<
Сохраните её в файл <code>helloworld.groovy</code> и запустите.
Строка 23:
Также комментарий можно расположить между <code>[[w:Косая_черта|/]]*</code> и <code>*[[w:Косая_черта|/]]</code>. Пример:
<
println "Привет!" /* это тоже комментарий */
/* А это - многострочный
комментарий */</
Результат иллюстрируемого кода будет располагаться после последовательности <code>//=></code>. Пример:
<
println "Привет" //=> Привет</
= Переменные =
Переменная в Groovy определяется ключевым словом <code>def</code> (это аналогично типу Object в Java):
<
def a = 1 // объявление "безтиповой" переменной, присвоение ей значения типа int
a = "String" /* так как мы не указали тип при объявлении этой переменной,
Строка 43:
b = "String for type int?" // так как тип переменной указан,
// то когда мы пытаемся присвоить String, получаем ошибку (GroovyCastException)
</syntaxhighlight>
= Строки =
Строка 51:
* Groovy Strings, известны как GStrings — в двойных кавычках; используя <code>${имя_переменной}</code> можно "вставить" внутрь строки значение переменной
<
javaString = 'java' // Java String
groovyString = "Hello ${javaString}!" // GString
Строка 69:
println a * 3 // умножение
</syntaxhighlight>
= Списки =
Строка 75:
Groovy содержит встроенную поддержку списков. Списки объявляются путем перечисления элементов в квадратных скобках:
<
def emptyList = [] // Создание пустого списка</
Обращение к элементам списка осуществляется по индексу, как к массиву в Java:
<
Новые элементы могут быть добавлены в список различными способами:
<
someList << 7 << 8 // Добавление элементов в конец списка
someList += [ 9, 10 ] // "Приклеивание" списка</
Теперь, совместное использование списков и ranges:
<
someList[2..4] = [ 12, 13, 14 ] // Изменение подсписка</
Также, для индексирования можно использовать и списки:
<
Также, Groovy предоставляет встроенный цикл, для перебора элементов списка, или элементов любого объекта, реализующего интерфейс java.lang.Iterable:
<
println e // Распечатываем все элементы списка someList
}</
= Maps (Отображения) =
Строка 108:
Аналогично спискам, Groovy поддерживает прозрачный синтаксис для работы с maps (ассоциативными массивами). Объявление выглядит следующим образом:
<
Также, существует специальный синтаксис для объявления пустых отображений:
<
// Объявление пустого отображения
def emptyMap = [:]
def otherEmptyMap = [:] as HashMap
</syntaxhighlight>
Доступ к элементам осуществляется по ключу, с использованием оператора [], или же с ключом как полем:
<
someMap.a // Доступ к элементу как к полю</
Аналогично производится и изменение элементов:
<
someMap.a = 2 // Изменение элемента, как поля</
Для хранения объектов в качестве ключа можно использовать скобки ():
<
def map = [(new String("username")):"james", nickname:"jcameron", (new Integer(22)):1234]
println map.get(new Integer(22))
</syntaxhighlight>
= Условное исполнение =
Строка 139:
Одним из наиболее важных особенностей любого языка программирования является возможность выполнять различные коды в разных условиях.Простейший способ сделать это состоит в использовании '''IF''' конструкции. Например:
<
def amPM = Calendar.getInstance().get(Calendar.AM_PM)
if (amPM == Calendar.AM){
Строка 146:
println("Good evening")
}
</syntaxhighlight>
Не беспокойтесь о длинной первой строке, это просто какой-то код, чтобы определить, сейчас утро или вечер. Остальная часть кода выполняется следующим образом: сначала оценивается выражение в круглых скобках и в зависимости от результата '''true''' (истинно) или '''false''' (ложно) выполняется первый или второй блок кода. Смотрите ниже раздел логические выражения.
Строка 152:
Обратите внимание, что блок '''else''' не требуется, в отличии от первого блока:
<
amPM = Calendar.getInstance().get(Calendar.AM_PM)
if (amPM == Calendar.AM){
println("Have another cup of coffee.")
}
</syntaxhighlight>
= Логические выражения =
Существует специальный тип данных в большинстве языков программирования, который используется для представления значений истинности,'''true''' (истина) и '''false''' (ложь). Простейшие логические выражения - это просто слова. Логические значения могут быть сохранены в переменных, как и любой другой тип данных:
<
def myBooleanVariable = true
</syntaxhighlight>
Более сложные логические выражения использует один из булевых операторов:
Строка 180:
Некоторые примеры:
<
def titanicBoxOffice = 1234600000
def titanicDirector = "James Cameron"
Строка 203:
titanicDirector >= "James Cameron" // вычисляется как истина
titanicDirector == "James Cameron" // вычисляется как истина
</syntaxhighlight>
Логические выражения особенно полезны при использовании совместно с '''if'''-конструкциями. Например:
<
if (titanicBoxOffice + trueLiesBoxOffice > returnOfTheKingBoxOffice + theTwoTowersBoxOffice){
println(titanicDirector + " is a better director than " + returnOfTheKingDirector)
}
</syntaxhighlight>
Особенно полезна проверка на наличие значения. К примеру, определён ли данный ключ в карте:
<
def suvMap = ["Acura MDX":"\$36,700", "Ford Explorer":"\$26,845"]
if (suvMap["Hummer H3"] != null){
println("A Hummer H3 will set you back "+suvMap["Hummer H3"]);
}
</syntaxhighlight>
Вообще '''null''' используется для указания на отсутствие значения выражения или переменной.
Строка 228:
Функции и методы всегда возвращают, как результат, последнее выражение.
<
//класс пользователя
class Person{
Строка 267:
println hw
</syntaxhighlight>
= Closures =
Строка 275:
Синтаксис замыкания : { [closureArguments->] statements }
<
def closureFunction = {a, b ->
println a
Строка 282:
closureFunction(1, 2)
</syntaxhighlight>
В замыканиях по умолчанию присутствует переменная '''it''' и ссылается на первый параметр в замыкании:
<
def closureA = { it }
assert closureA() == null
assert closureA(1) == 1
</syntaxhighlight>
Вызов замыкания:
<
def c = { it, arg-> println "${it} ${arg}" }
c.call("A", "B") // первый тип вызова
c("C", "D") // второй тип вызова
</syntaxhighlight>
Определение замыкания в классе и его вызов:
<
public class ClassWithClosure {
private int member = 20;
Строка 325:
def closureVar = sample.publicMethodWithClosure("Xavier");
closureVar();
</syntaxhighlight>
Специальный класс [http://groovy.codehaus.org/gapi/groovy/util/Expando.html Expando] для создания динамических объектов и методов (как замыкания) которые можно вызывать:
<
def player = new Expando()
player.name = "Alec"
Строка 338:
println player.greeting()
</syntaxhighlight>
= Работа с файлами =
<
def out= new File('File1.txt')
Строка 375:
def dir2= new File('Directory2/SubDir1')
dir2.mkdirs()
</syntaxhighlight>
= Работа со строками =
<
lst = /This is my new string./
println lst
Строка 389:
println "reverse me".reverse()
println "This is the end, my only friend!".tokenize(' ').reverse().join(' ')
</syntaxhighlight>
= Classes and Objects =
Строка 395:
Описание и создание класса(по умолчанию класс имеет тип доступа public, а переменные класса имеют тип доступа private, но компилятор groovy сам сделает для этих полей геттеры и сеттеры с доступом public):
<
class Human {
String name
Строка 406:
def woman = new Human(name: "Eva", age: 22 )
</syntaxhighlight>
Для обновления поля или полей можно использовать такой подход:
<
man.with{
name = "Adam"
age = 34
}
</syntaxhighlight>
Классы:
<
// Классы могут не иметь конструктора
class ClassWithoutConstructor { }
Строка 458:
println catty.age
println catty.startDate
</syntaxhighlight>
Интерфейсы:
<
// Объявление интерфейса
interface Voice{
Строка 511:
new Thread(mainRunnable).start()
</syntaxhighlight>
Наследование:
<
class PersonA implements Comparable {
def firstname, initial, surname
Строка 552:
println g.grandChildName // => Rachel
</syntaxhighlight>
Абстрактные классы:
<
abstract class Shape {
final name
Строка 588:
shapes = [new Circle(4.2), new Rectangle(5, 7)]
shapes.each { shape -> shape.printName() }
</syntaxhighlight>
Статические внутренние классы:
<
class OuterClass {
static class StaticInnerClass {
Строка 604:
println myInstance.getAge()
</syntaxhighlight>
Анонимные внутренние классы:
<
new Thread([run: {
Строка 621:
}
}] as Runnable).start();
</syntaxhighlight>
Enum:
<
enum Color{
RED, GREEN, BLUE
Строка 633:
Color blueColor = "BLUE"
println blueColor
</syntaxhighlight>
= Расширенные возможности =
Строка 652:
Можно импортировать пакеты в статическом контексте, а также назначать алиасы/псевдонимы:
<
import static java.awt.Color.BLUE
import static Boolean.FALSE as F // назначаем алиас с именем F
Строка 668:
println a
// напечатает 123
</syntaxhighlight>
<
// представление списка как интерфейса Set
def contacts = ['a', 'b', 'c'] as Set
Строка 679:
println contacts['a'] // напечатает 10
</syntaxhighlight>
== Работа с данными ==
<
// множественное присвоение
def (a, b, c) = [1,2,5]
Строка 706:
(10..1).each {println it}
[ 'a' : 1, 'b' : 2 ].each {key, value -> println key}
</syntaxhighlight>
== Дата и время ==
<
import java.util.GregorianCalendar as D
import static java.util.Calendar.getInstance as now
Строка 722:
println 'Date was '+date.format("MM/dd/yyyy")
</syntaxhighlight>
== Аннотации ==
<
// Эта аннотация которая генерирует из данного класса синглетон
@Singleton(lazy=true)
Строка 765:
}
</syntaxhighlight>
== Regular Expressions ==
Строка 772:
Оператор pattern (~) обеспечивает простой способ создать java.util.regex.Pattern.<br />
Пример:
<
def p = ~/foo/
assert p instanceof Pattern
</syntaxhighlight>
В основном оператор pattern используется со слеш-строками (строки обрамлённых слешами), тем не менее этот оператор может использоваться с любыми видами строк Groovy:
<
p = ~'foo' /*1*/
p = ~"foo" /*2*/
p = ~$/dollar/slashy $ string/$ /*3*/
p = ~"${pattern}" /*4*/
</syntaxhighlight>
# использование строк в одинарных кавычках
# использование строк в двойных кавычках
Строка 790:
=== Find operator ===
Alternatively to building a pattern, you can directly use the find operator =~ to build a java.util.regex.Matcher instance:
<
def text = "some text to match"
def m = text =~ /match/ /*1*/
Строка 797:
throw new RuntimeException("Oops, text not found!")
}
</syntaxhighlight>
# =~ creates a matcher against the text variable, using the pattern on the right hand side
# the return type of =~ is a Matcher
Строка 805:
=== Match operator ===
The match operator (==~) is a slight variation of the find operator, that does not return a Matcher but a boolean and requires a strict match of the input string:
<
m = text ==~ /match/ /*1*/
assert m instanceof Boolean /*2*/
Строка 811:
throw new RuntimeException("Should not reach that point!")
}
</syntaxhighlight>
# ==~ matches the subject with the regular expression, but match must be strict
# the return type of ==~ is therefore a boolean
Строка 823:
= Groovy SQL =
Подключение к базе данных и запрос SELECT(необходимо подключить драйвер JDBC для MySQL или другой базы):
<
import groovy.sql.Sql
Строка 834:
)''')
</syntaxhighlight>
== Выполнение простого sql-запроса ==
Вставка новой записи:
<
def age = 25
def name = "Adam"
Строка 845:
// or
sql.executeInsert("insert into users (username, age) values (${name}, ${age})")
</syntaxhighlight>
Выборка первой записи из результата запроса:
<
def rowFirst = sql.firstRow('select username, age from users')
println "Row: Name = ${rowFirst.username} and Age = ${rowFirst.age}"
</syntaxhighlight>
Выборка всех записей:
<
sql.eachRow("select * from users"){ row -> println row.username }
</syntaxhighlight>
Удаление записи:
<
int id = 2
sql.execute('delete from users where id = ?' , [id])
</syntaxhighlight>
Обновление записи:
<
def newUsername = 'New Name'
int rowsAffected = sql.executeUpdate('update users set username = ? where id=2', [newUsername])
println "updated: ${rowsAffected}";
</syntaxhighlight>
== Выполнение более сложных запросов ==
<
import groovy.sql.Sql
import groovy.sql.DataSet
Строка 883:
DataSet findedUsers = users.findAll() // получение всех записей и их вывод
findedUsers.each{ println it.username}
</syntaxhighlight>
Добавление записей в транзакции:
<
import groovy.sql.Sql
Строка 899:
users.add(username: "Alec 2", age: 25)
}
</syntaxhighlight>
Блочное добавление записей:
<
import groovy.sql.Sql
Строка 912:
ps.addBatch(["New Name", 31])
}
</syntaxhighlight>
== Call Procedure ==
Вызов процедур:
<
import groovy.sql.Sql
Строка 928:
assert name == 'Adam'
}
</syntaxhighlight>
= Прочие советы =
== Работа с JSON ==
<
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
Строка 956:
println doc.person.username // вывод имени
doc.person.pets.each {println it} // вывод животных
</syntaxhighlight>
== Работа с XML ==
Строка 962:
Создание XML документа из объекта:
<
import groovy.xml.MarkupBuilder
Строка 978:
}
println writer.toString()
</syntaxhighlight>
Работа с HTML:
<
import groovy.xml.MarkupBuilder
Строка 1000:
println writer.toString()
</syntaxhighlight>
Парсинг XML документа
<
def xmlString = """
<person>
Строка 1019:
println person.username
person.pets.pet.each {println "pet's name:"+it}
</syntaxhighlight>
== Потоки и асинхронная работа ==
<
//эта аннотация скачивает и устанавливает библиотеку в classpath
@Grab(group='org.codehaus.gpars', module='gpars', version='0.12')
Строка 1044:
}
}
</syntaxhighlight>
= Ссылки =
|