MyTetra Share
Делитесь знаниями!
Материал из Викиучебника
Время создания: 07.06.2019 17:14
Раздел: INFO - Development - GROOVY
Запись: wwwlir/Tetra/master/base/1559484227mm649ry5x9/text.html на raw.githubusercontent.com

Groovy

Материал из Викиучебника — открытых книг для открытого мира

П ерейти к навигации Перейти к поиску

В Википедии имеется статья по теме «Groovy »

Содержание

  • 1 Первая программа
  • 2 Комментарии и демонстрация результата
  • 3 Переменные
  • 4 Строки
  • 5 Списки
  • 6 Maps (Отображения)
  • 7 Условное исполнение
  • 8 Логические выражения
  • 9 Функции
  • 10 Closures
  • 11 Работа с файлами
  • 12 Работа со строками
  • 13 Classes and Objects
  • 14 Расширенные возможности
    • 14.1 Импорт и переопределение
    • 14.2 Работа с данными
    • 14.3 Дата и время
    • 14.4 Аннотации
    • 14.5 Regular Expressions
      • 14.5.1 Оператор Pattern
      • 14.5.2 Find operator
      • 14.5.3 Match operator
    • 14.6 The operators
    • 14.7 Capture groups
    • 14.8 Non-matching Groups
    • 14.9 Replacement
    • 14.10 Reluctant Operators
  • 15 Groovy SQL
    • 15.1 Выполнение простого sql-запроса
    • 15.2 Выполнение более сложных запросов
    • 15.3 Call Procedure
  • 16 Прочие советы
    • 16.1 Работа с JSON
    • 16.2 Работа с XML
    • 16.3 Потоки и асинхронная работа
  • 17 Ссылки

Первая программа

Откройте редактор и напишите программу. По традиции, первая программа должна просто выводить приветствие миру:

println "Hello World!"

Сохраните её в файл helloworld.groovy и запустите.

groovy helloworld.groovy

На экране появится надпись:

Hello World!

На этом традиционную часть можно считать выполненной.

Комментарии и демонстрация результата

Комментарием называется часть программного кода, пропускаемая при обработке (интерпретации или компиляции).

В Groovy знаком начала комментария служит // . Всё, что между ним и концом строки пропускается. Также комментарий можно расположить между / * и */ . Пример:

println 2 + 2 // это комментарий

println "Привет!" /* это тоже комментарий */

/* А это - многострочный

комментарий */

Результат иллюстрируемого кода будет располагаться после последовательности //=>. Пример:

println 2 + 2 //=> 4

println "Привет" //=> Привет

Переменные

Переменная в Groovy определяется ключевым словом def (это аналогично типу Object в Java):

def a = 1 // объявление "безтиповой" переменной, присвоение ей значения типа int

a = "String" /* так как мы не указали тип при объявлении этой переменной,

то можно присваивать этой переменной значение другого типа */


int b = 2 // объявление переменной типа int

b = "String for type int?" // так как тип переменной указан,

// то когда мы пытаемся присвоить String, получаем ошибку (GroovyCastException)

Строки

В Groovy есть 2 типа строк:

  • Java Strings — строки в одинарных кавычках
  • Groovy Strings, известны как GStrings — в двойных кавычках; используя ${имя_переменной} можно "вставить" внутрь строки значение переменной

javaString = 'java' // Java String

groovyString = "Hello ${javaString}!" // GString


println javaString // => java

println groovyString // => Hello java!


bigGroovyString = """

long

long

string

""" // Длинная строка с отступами


def a = "a"

println a

println a + "12" // конкатенация

println a * 3 // умножение

Списки

Groovy содержит встроенную поддержку списков. Списки объявляются путем перечисления элементов в квадратных скобках:

def someList = [1,2,3,4] // Создание списка

def emptyList = [] // Создание пустого списка

Обращение к элементам списка осуществляется по индексу, как к массиву в Java:

someList[0] // Обращение к элементу по индексу

Новые элементы могут быть добавлены в список различными способами:

someList[5] = 6 // Добавление элемента в список

someList << 7 << 8 // Добавление элементов в конец списка

someList += [ 9, 10 ] // "Приклеивание" списка

Теперь, совместное использование списков и ranges:

someList[1..3] // "Срезка" списка - получение подсписка

someList[2..4] = [ 12, 13, 14 ] // Изменение подсписка

Также, для индексирования можно использовать и списки:

someList[1,3,5..7,9] // Получение подсписка

Также, Groovy предоставляет встроенный цикл, для перебора элементов списка, или элементов любого объекта, реализующего интерфейс java.lang.Iterable:

for ( e in someList ) {

println e // Распечатываем все элементы списка someList

}

Maps (Отображения)

Аналогично спискам, Groovy поддерживает прозрачный синтаксис для работы с maps (ассоциативными массивами). Объявление выглядит следующим образом:

def someMap = [ 'a' : 1, 'b' : 2 ] // Объявление

Также, существует специальный синтаксис для объявления пустых отображений:

// Объявление пустого отображения

def emptyMap = [:]

def otherEmptyMap = [:] as HashMap

Доступ к элементам осуществляется по ключу, с использованием оператора [], или же с ключом как полем:

someMap['a'] // Доступ к элементу

someMap.a // Доступ к элементу как к полю

Аналогично производится и изменение элементов:

someMap['a'] = 2 // Изменение элемент

someMap.a = 2 // Изменение элемента, как поля

Для хранения объектов в качестве ключа можно использовать скобки ():

def map = [(new String("username")):"james", nickname:"jcameron", (new Integer(22)):1234]

println map.get(new Integer(22))

Условное исполнение

Одним из наиболее важных особенностей любого языка программирования является возможность выполнять различные коды в разных условиях.Простейший способ сделать это состоит в использовании IF конструкции. Например:

def amPM = Calendar.getInstance().get(Calendar.AM_PM)

if (amPM == Calendar.AM){

println("Good morning")

} else {

println("Good evening")

}

Не беспокойтесь о длинной первой строке, это просто какой-то код, чтобы определить, сейчас утро или вечер. Остальная часть кода выполняется следующим образом: сначала оценивается выражение в круглых скобках и в зависимости от результата true (истинно) или false (ложно) выполняется первый или второй блок кода. Смотрите ниже раздел логические выражения.

Обратите внимание, что ​​блок else не требуется, в отличии от первого блока:

amPM = Calendar.getInstance().get(Calendar.AM_PM)

if (amPM == Calendar.AM){

println("Have another cup of coffee.")

}

Логические выражения

Существует специальный тип данных в большинстве языков программирования, который используется для представления значений истинности,true (истина) и false (ложь). Простейшие логические выражения - это просто слова. Логические значения могут быть сохранены в переменных, как и любой другой тип данных:

def myBooleanVariable = true

Более сложные логические выражения использует один из булевых операторов:

  • ==
  •  !=
  • >
  • >=
  • <
  • <=

Большинство из них, довольно интуитивны. Оператор равенства ==, не путайте с оператором присваивания =. Оператор не равенство !=, то есть "не равно".

Некоторые примеры:

def titanicBoxOffice = 1234600000

def titanicDirector = "James Cameron"


def trueLiesBoxOffice = 219000000

def trueLiesDirector = "James Cameron"


def returnOfTheKingBoxOffice = 752200000

def returnOfTheKingDirector = "Peter Jackson"


def theTwoTowersBoxOffice = 581200000

def theTwoTowersDirector = "PeterJackson"


titanicBoxOffice > returnOfTheKingBoxOffice // вычисляется как истина

titanicBoxOffice >= returnOfTheKingBoxOffice // вычисляется как истина

titanicBoxOffice >= titanicBoxOffice // вычисляется как истина

titanicBoxOffice > titanicBoxOffice // оценивается как ложное

titanicBoxOffice + trueLiesBoxOffice < returnOfTheKingBoxOffice + theTwoTowersBoxOffice // оценивается как ложное


titanicDirector > returnOfTheKingDirector // оценивается как ложное, потому что "J" находится перед "Р"

titanicDirector < returnOfTheKingDirector // вычисляется как истина

titanicDirector >= "James Cameron" // вычисляется как истина

titanicDirector == "James Cameron" // вычисляется как истина

Логические выражения особенно полезны при использовании совместно с if-конструкциями. Например:

if (titanicBoxOffice + trueLiesBoxOffice > returnOfTheKingBoxOffice + theTwoTowersBoxOffice){

println(titanicDirector + " is a better director than " + returnOfTheKingDirector)

}

Особенно полезна проверка на наличие значения. К примеру, определён ли данный ключ в карте:

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"]);

}

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

Функции

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

//класс пользователя

class Person{

String first, last

}

//функции без типизированных параметров

def printInfo(first, second){

println "first name: $first, second name: $second"

}

def printFirstName(user){

println "user: $user.first"

}

//создаем объект класса Person с параметрами

def tempPerson = new Person(first: 'Adam', last: 'Smith')

// вызов функции разными способами

printInfo tempPerson.first, tempPerson.last

printFirstName(tempPerson)


printFirstName tempPerson


//типизированный параметр


def functionA(String str){

println str

}

functionA 'String'// все ок

functionA 1 // вернётся исключение


int functionB(int argB) {

argB + 2

}

String functionC() {

"Hello World"

}


println functionB(1)

def hw = functionC()

println hw

Closures

Closure - это замыкание и представляет собой некую анонимную функцию со свойствами объекта.

Синтаксис замыкания : { [closureArguments->] statements }

def closureFunction = {a, b ->

println a

println b

}

closureFunction(1, 2)

В замыканиях по умолчанию присутствует переменная it и ссылается на первый параметр в замыкании:

def closureA = { it }

assert closureA() == null

assert closureA(1) == 1

Вызов замыкания:

def c = { it, arg-> println "${it} ${arg}" }

c.call("A", "B") // первый тип вызова

c("C", "D") // второй тип вызова

Определение замыкания в классе и его вызов:

public class ClassWithClosure {

private int member = 20;


private String method()

{

return "hello";

}


def publicMethodWithClosure(String name_)

{

def localVar = member + 5;

def localVar2 = "Parameter: ${name_}";

return {

println "${member} ${name_} ${localVar} ${localVar2} ${method()}"

}

}

}


ClassWithClosure sample = new ClassWithClosure();

def closureVar = sample.publicMethodWithClosure("Xavier");

closureVar();

Специальный класс Expando для создания динамических объектов и методов (как замыкания) которые можно вызывать:

def player = new Expando()

player.name = "Alec"

player.greeting = { "Hello, my name is $name" }


println player.greeting()

player.name = "Max"

println player.greeting()

Работа с файлами

def out= new File('File1.txt')

// если файл не существует, то создаем файл

if(!out.exists()) {

out.createNewFile()

out << 'aaa\nbbb\nccc' // пишем текст в файл

}


list= [] // создаем список для строк

out.eachLine { list<< it } // и заполняем его

println list.size() // выводим размер списка строк

println out.text // выводим весь текст

out.write('\nnew string') // пишем текст в файл

out.eachLine { println it}

out.append('\nappend string') // добавляем текст в файл


//выводим информацию о файле

println out.name

println out.isAbsolute()

println out.path

println out.parent

println out.absolutePath

println out.absoluteFile.toString()

println out.canonicalPath

println out.canonicalFile.toString()

println out.toURI().toString()


// Создаем директории

def dir= new File('Directory1')

dir.mkdir() //make directory, if it doesn't already exist

def dir2= new File('Directory2/SubDir1')

dir2.mkdirs()

Работа со строками

lst = /This is my new string./

println lst


def b = "abcde" // также строка представляет собой и список символов

println b[2] // напечатает c

println b[1..3] // напечатает bcd


println "reverse me".reverse()

println "This is the end, my only friend!".tokenize(' ').reverse().join(' ')

Classes and Objects

Описание и создание класса(по умолчанию класс имеет тип доступа public, а переменные класса имеют тип доступа private, но компилятор groovy сам сделает для этих полей геттеры и сеттеры с доступом public):

class Human {

String name

int age

}


def man = new Human();

man.name = "Adam"

man.age = 25;


def woman = new Human(name: "Eva", age: 22 )

Для обновления поля или полей можно использовать такой подход:

man.with{

name = "Adam"

age = 34

}

Классы:

// Классы могут не иметь конструктора

class ClassWithoutConstructor { }


class Bird {


static startDate = new Date()


private name


def getName() { name }


def setName(name) { this.name = name }


static getStartDate() {

startDate

}

}


println Bird.startDate

def myBird = new Bird()

myBird.name = "Chack"

println myBird.name

// и иметь разные правила для генерации методов для полей

class Cat {


def startDate = new Date() // getter и setter

final String name = "Empty"

final age // только getter


Cat(date, name) {

startDate = date

this.name = name

this.age = 1

}

}

Cat catty = new Cat(new Date(), "Pussy Cat")

println catty.name

println catty.age

println catty.startDate

Интерфейсы:

// Объявление интерфейса

interface Voice{

void voice();

String getAnimalName();

}

// его реализация

class Dog implements Voice{


@Override

void voice() {

println "Gav"

}


@Override

String getAnimalName() {

return Dog.class.getSimpleName()

}


void goMethod(){


}

}

// и использование

def dog = new Dog() as Voice


// или можно привести к интерфейсу таким способом:

def dog = new Dog().asType(Voice.class)


dog.voice()

println "my name is: " + dog.getAnimalName()


// Реализация интерфейса как замыкания

def mainRunnable = {

run:{

try {

int i = 5

while (i>0) {

sleep(1000)

println "${i--}"

}

} catch (InterruptedException ex) {

// error

}

}

} as Runnable


new Thread(mainRunnable).start()

Наследование:

class PersonA implements Comparable {

def firstname, initial, surname

PersonA(f,i,s) { firstname = f; initial = i; surname = s }

int compareTo(other) { firstname <=> other.firstname }

}

def a = new PersonA('James', 'T', 'Kirk')

def b = new PersonA('Samuel', 'L', 'Jackson')

println a <=> b

// => -1


class PersonB extends PersonA {

PersonB(f,i,s) { super(f,i,s) }

int compareTo(other) { initial <=> other.initial }

}


a = new PersonB('James', 'T', 'Kirk')

b = new PersonB('Samuel', 'L', 'Jackson')

println a <=> b

// => 1


class Parent {

private name // my child's name

def setChildName(value) { name = value }

def getChildName() { name }

}

class GrandParent extends Parent {

private name // my grandchild's name

def setgrandChildName(value) { name = value }

def getGrandChildName() { name }

}

g = new GrandParent()

g.childName = 'Jason'

g.grandChildName = 'Rachel'

println g.childName // => Jason

println g.grandChildName // => Rachel

Абстрактные классы:

abstract class Shape {

final name

Shape(name) { this.name = name }

abstract printName()

}


class Circle extends Shape {

final radius

Circle(radius) {

super('circle')

this.radius = radius

}

def area() { Math.PI * radius * radius }

def printName() {

println "I am a $name."

}

}


class Rectangle extends Shape {

final length, breadth

def Rectangle(length, breadth) {

super("rectangle")

this.length = length

this.breadth = breadth

}

def printName() {

println "I am a $name."

}

}

shapes = [new Circle(4.2), new Rectangle(5, 7)]

shapes.each { shape -> shape.printName() }

Статические внутренние классы:

class OuterClass {

static class StaticInnerClass {

public int getAge(){

int a = 35

}

}

}


OuterClass.StaticInnerClass myInstance = new OuterClass.StaticInnerClass()


println myInstance.getAge()

Анонимные внутренние классы:

new Thread([run: {

try {

int i = 5

while (i>0) {

sleep(1000)

println "${i--}"

}

} catch (InterruptedException ex) {

// error

}

}] as Runnable).start();

Enum:

enum Color{

RED, GREEN, BLUE

}

def redColor = "RED" as Color

Color blueColor = "BLUE"

println blueColor

Расширенные возможности

Импорт и переопределение

Импортируемые пакеты по умолчанию которые добавляются компилятором в каждый сценарий:

  • java.io.*
  • java.lang.*
  • java.math.BigDecimal
  • java.math.BigInteger
  • java.net.*
  • java.util.*
  • groovy.lang.*
  • groovy.util.*

Можно импортировать пакеты в статическом контексте, а также назначать алиасы/псевдонимы:

import static java.awt.Color.BLUE

import static Boolean.FALSE as F // назначаем алиас с именем F

import static Calendar.getInstance as now // назначаем алиас с именем now

import static java.lang.Integer.*


println BLUE

// напечатает java.awt.Color[r=0,g=0,b=255]

println !F

// напечатает true


println now().time

// напечатает Fri Jun 08 06:37:20 EEST 2011

def a = parseInt("123")

println a

// напечатает 123

// представление списка как интерфейса Set

def contacts = ['a', 'b', 'c'] as Set

println contacts.size() // напечатает 3


// представление списка как интерфейса Map

def contacts = ['a':10, 'b':20, 'c':30] as Map

println contacts['a'] // напечатает 10

Работа с данными

// множественное присвоение

def (a, b, c) = [1,2,5]

println c


def (int myint, String mystring) = [5, "hello"]

println mystring


//диапазоны значений

def list = [3, 'Some string' , new Date()]


println list[0]

println list[1]


def letters = 'a'..'z'

def numbers = 0..<10


println numbers.size()


// работа с замыканиями

3.times { println 'Hi'}

[1,2,3].each {it -> println it}

(10..1).each {println it}

[ 'a' : 1, 'b' : 2 ].each {key, value -> println key}

Дата и время

import java.util.GregorianCalendar as D

import static java.util.Calendar.getInstance as now


println new D(2011, 11, 25).time

println now().time

println new Date() + 1


dateStr = "2011-06-03"

date = Date.parse("yyyy-MM-dd", dateStr)

println 'Date was '+date.format("MM/dd/yyyy")

Аннотации

// Эта аннотация которая генерирует из данного класса синглетон

@Singleton(lazy=true)

class MySingleton {

def getHello(){

"hello world"

}

}


println MySingleton.instance.hello


// Эта аннотация позволяет внедрить в класс Manager поведение метода из класса Employee

class Employee {

def doWork() { 'my work' }

}


class Manager {

@Delegate

Employee slave = new Employee()

}


def worker = new Manager()

println worker.doWork()


// либо можно сделать то же самое с помощью mixin

class Employee2 { def doWork() { 'my work' } }

class Manager2 {}


Manager2.mixin Employee2


println new Manager2().doWork()


// Аннотация @Immutable делает объект этого класса неизменяемым

// свойства объекта становятся readonly

@Immutable

class Person{

String first, last

}

Regular Expressions

Оператор Pattern

Оператор pattern (~) обеспечивает простой способ создать java.util.regex.Pattern.
Пример:

def p = ~/foo/

assert p instanceof Pattern

В основном оператор pattern используется со слеш-строками (строки обрамлённых слешами), тем не менее этот оператор может использоваться с любыми видами строк Groovy:

p = ~'foo' /*1*/

p = ~"foo" /*2*/

p = ~$/dollar/slashy $ string/$ /*3*/

p = ~"${pattern}" /*4*/

  1. использование строк в одинарных кавычках
  2. использование строк в двойных кавычках
  3. использование строки обрамлённой доллар-слешем, позволяет использовать слеш и доллар без их экранирования
  4. использование GString

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*/

assert m instanceof Matcher /*2*/

if (!m) { /*3*/

throw new RuntimeException("Oops, text not found!")

}

  1. =~ creates a matcher against the text variable, using the pattern on the right hand side
  2. the return type of =~ is a Matcher
  3. equivalent to calling if (!m.find())

Since a Matcher coerces to a boolean by calling its find method, the =~ operator is consistent with the simple use of Perl’s =~ operator, when it appears as a predicate (in if, while, etc.).

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*/

if (!m) { /*3*/

throw new RuntimeException("Should not reach that point!")

}

  1. ==~ matches the subject with the regular expression, but match must be strict
  2. the return type of ==~ is therefore a boolean
  3. equivalent to calling if (text ==~ /match/)

The operators

Capture groups

Non-matching Groups

Replacement

Reluctant Operators

Groovy SQL

Подключение к базе данных и запрос SELECT(необходимо подключить драйвер JDBC для MySQL или другой базы):

import groovy.sql.Sql


Sql sql = Sql.newInstance("jdbc:mysql://localhost:3306/testdatabase", "user", "password", "com.mysql.jdbc.Driver")

// создаем таблицу

sql.execute('''create table users (

id int(11) not null primary key auto_increment,

username varchar(255),

age int(11)

)''')

Выполнение простого sql-запроса

Вставка новой записи:

def age = 25

def name = "Adam"

sql.execute("insert into users (username, age) values (${name}, ${age})")

// or

sql.executeInsert("insert into users (username, age) values (${name}, ${age})")

Выборка первой записи из результата запроса:

def rowFirst = sql.firstRow('select username, age from users')

println "Row: Name = ${rowFirst.username} and Age = ${rowFirst.age}"

Выборка всех записей:

sql.eachRow("select * from users"){ row -> println row.username }

Удаление записи:

int id = 2

sql.execute('delete from users where id = ?' , [id])

Обновление записи:

def newUsername = 'New Name'

int rowsAffected = sql.executeUpdate('update users set username = ? where id=2', [newUsername])

println "updated: ${rowsAffected}";

Выполнение более сложных запросов

import groovy.sql.Sql

import groovy.sql.DataSet


DataSet users

Sql sql = Sql.newInstance("jdbc:mysql://localhost:3306/testdatabase", "user", "password", "com.mysql.jdbc.Driver")

// таблица users должна быть создана

users = sql.dataSet("USERS")

users.add(username: "James", age: 55) //вставка новой записи в таблицу


DataSet findedUsers = users.findAll() // получение всех записей и их вывод

findedUsers.each{ println it.username}

Добавление записей в транзакции:

import groovy.sql.Sql


DataSet users

Sql sql = Sql.newInstance("jdbc:mysql://localhost:3306/testdatabase", "user", "password", "com.mysql.jdbc.Driver")


// таблица users должна быть создана

users = sql.dataSet("USERS")


sql.withTransaction {

users.add(username: "Alec", age: 25)

users.add(username: "Alec 2", age: 25)

}

Блочное добавление записей:

import groovy.sql.Sql


Sql sql = Sql.newInstance("jdbc:mysql://localhost:3306/testdatabase", "user", "password", "com.mysql.jdbc.Driver")

def updateCounts = sql.withBatch('insert into users(username, age) values (?, ?)') { ps ->

ps.addBatch("New Name", 22) // varargs style

ps.addBatch(["New Name", 18]) // list

ps.addBatch(["New Name", 31])

}

Call Procedure

Вызов процедур:

import groovy.sql.Sql


Sql sql = Sql.newInstance("jdbc:mysql://localhost:3306/testdatabase", "user", "password", "com.mysql.jdbc.Driver")

sql.call("{? = call MyProcedure(?)}", [Sql.VARCHAR, 'Sam']) { name ->

assert name == 'Adam'

}

// or with GString

def first = 'Sam'

sql.call("{$Sql.VARCHAR = call MyProcedure($first)}") { name ->

assert name == 'Adam'

}

Прочие советы

Работа с JSON

import groovy.json.JsonBuilder

import groovy.json.JsonSlurper

import groovy.json.JsonOutput

// Создание JSON объекта

def json = new JsonBuilder()

json.person {

username "Guillaume"

age 33

pets "Hector", "Felix"

}


println json.toString() // вывод в строку полученного объекта


// Парсинг строки в JSON формате

def someJSONString = '{"person":{"username":"Guillaume","age":33,"pets":["Hector","Felix"]}}'

println JsonOutput.prettyPrint(someJSONString) // форматированный вывод объекта


def slurper = new JsonSlurper()

def doc = slurper.parseText(someJSONString)


println doc.person.username // вывод имени

doc.person.pets.each {println it} // вывод животных

Работа с XML

Создание XML документа из объекта:

import groovy.xml.MarkupBuilder


writer = new StringWriter()

builder = new MarkupBuilder(writer)

petsList = [ "Hector", "Felix"]

builder.person() {

username("Guillaume")

age("33")

gender("female")

pets(){

for (e in petsList){pet(e)}

}


}

println writer.toString()

Работа с HTML:

import groovy.xml.MarkupBuilder

def writer = new StringWriter()

def builder = new MarkupBuilder(writer)

builder.html() {

head() {

title("This is the title")

}


body() {

div("class" : "main") {

p("this is the body")

}

}

}


println writer.toString()

Парсинг XML документа

def xmlString = """

<person>

<username>Guillaume</username>

<age>33</age>

<gender>female</gender>

<pets>

<pet>Hector</pet>

<pet>Felix</pet>

</pets>

</person>

"""


def person = new XmlSlurper().parseText(xmlString)

println person.username

person.pets.pet.each {println "pet's name:"+it}

Потоки и асинхронная работа

//эта аннотация скачивает и устанавливает библиотеку в classpath

@Grab(group='org.codehaus.gpars', module='gpars', version='0.12')

import static groovyx.gpars.GParsExecutorsPool.withPool


//запуск в новом потоке

Thread.start {

println Thread.currentThread().getId()

}

//50 раз сделать асинхронную загрузку страницы(и распечатать ответ)

//по url в отдельных потоках

int count = 50

withPool(count) {

count.times {

Closure callUrl = {"http://google.com".toURL().withReader {

reader -> println reader.readLines()

}}

callUrl.callAsync();

}

}

Ссылки

  • Установка Groovy
  • Groovy Language Documentation

К атегории:

  • Языки программирования
  • Java (язык программирования)
  • Объектно-ориентированное программирование

Навигация

  • Вы не представились системе
  • О бсуждение
  • В клад
  • С оздать учётную запись
  • В ойти
  • У чебник
  • О бсуждение
  • Ч итать
  • П равить
  • И стория

Поиск

  • З аглавная страница
  • К аталог учебников
  • К улинарная книга
  • С лучайная статья

Участие

  • С правка
  • Ф орум
  • С вежие правки
  • Н овые страницы
  • П ожертвовать

Инструменты

  • С сылки сюда
  • С вязанные правки
  • С лужебные страницы
  • П остоянная ссылка
  • С ведения о странице
  • Э лемент Викиданных
  • Ц итировать страницу

В других проектах

  • Википедия

Печать/экспорт

  • С оздать книгу
  • С качать как PDF
  • В ерсия для печати

На других языках

  • Deutsch
  • עברית

Править ссылки

  • Эта страница в последний раз была отредактирована 19 апреля 2019 в 06:51.
  • Текст доступен по лицензии Creative Commons Attribution-ShareAlike , в отдельных случаях могут действовать дополнительные условия. Подробнее см. Условия использования .
  • П олитика конфиденциальности
  • О писание Викиучебника
  • О тказ от ответственности
  • Р азработчики
  • С оглашение о cookie
  • М обильная версия


 
MyTetra Share v.0.59
Яндекс индекс цитирования