JN0025-Starting -- Groovy 之 ABC

Groovy 字符串可以是如下形式:
'A string can be within single quotes on one line...'
'''...or within triple single quotes
over many lines, ignoring // and */ and /* comment delimiters,...'''
"...or within double quotes..."
"""...or within triple double quotes
over many lines."""

以下每一行所作的事情相同:
println 'hello, world' //the function 'println' prints a string then newline
print 'hello, world\n' //'print' doesn't print newline, but we can embed
                       //newlines ('\n' on Unix/Linux, '\r\n' on Windows)
println 'hello' + ', ' + 'world' // + joins strings together
print 'hello, '; println 'world'
                       //use semi-colons to join two statements on one line
println( 'hello, world' )
             //can put command parameter in parens(括弧), sometimes we might have to
def a= 'world'; println 'hello, ' + a
                       //'def'to define a variable and give it a value
                       // 'def' 定义一个变量并赋值给它
print 'hello, world'; println()
  //empty parens must be used for no-arg functions; here, prints a blank line
def b= 'hello', c= 'world'; println "$b, ${c}"
                       //$ in print string captures variable's value

我们也可以赋整数和小数给变量:
def g = 7, groovy = 10.2
  //we can separate more than one defined variable by a comma
print g + ', ' + groovy + '\n' //prints: 7, 10.2
assert g + ', ' + groovy == '7, 10.2' //we can use assert statement and == 
                                      //operator to understand examples

我们可以使用运算符比如+-*/和括弧以及数字,依照数学分组规则:
assert 4 * ( 2 + 3 ) - 6 == 14 //integers only
assert 2.5 + 7 == 9.5
assert 7 / 4 == 1.75 //decimal number or division converts expression to decimal

我们可以使用运算符== > < >= <= != 以及数字,true值和false值,运算符!(not) &&(and) 和 ||(or) 以及括弧,去生成布尔表达式:
assert 2 > 3 == false
assert 7 <= 9
assert 7 != 2
assert true
assert ! false
assert 2 > 3 || 7 <= 9
assert ( 2 > 3 || 4 < 5 ) && 6 != 7

变量具有可变性:
def a
assert a == null
  //variables defined but not given a value have special value null
  // 定义变量却不赋值,则默认值为null
def b = 1
assert b == 1
b = 2
assert b == 2 //variables can be re-assigned to
b = 'cat'
assert b == 'cat' //they can be re-assigned different types/classes of data
                  // 变量可以再赋值为不同类型/类的数据
b = null
assert b == null //they can be unassigned

Groovy中所有的命名,包括变量命名,可以包含任何字母或下划线,以及任何数字,但命名不能以数字开头。
def abc= 4
def a23c= 4
def ab_c= 4
def _abc= 4

def ABC= 4
assert abc == ABC //although their values are the same...
assert ! abc.is( ABC ) //...the variables 'abc' and 'ABC' are different,
                       //the names being case-sensitive

/*these each produce compile errors when uncommented...
def abc //already defined
def a%c= 4 //not a valid name because it contains a symbol other than _
def 2bc= 4 //may not contain a digit in first position
*/

Groovy中所有数据都来自类和类的实例。约定是类名以大写字母开头:
assert Byte.MAX_VALUE == 127
  //a class can have attached variables, called 'fields'
assert Byte.parseByte('34') == 34
  //a class can have attached functions, called 'methods'
def b= new Byte('34')
  //we can create an 'instance' of a class using the 'new' keyword
assert b.intValue() == 34
  //each instance can also have attached fields and methods

利用class字段,我们可以检查任何实体比如数字和字符串的类:
assert 4.class == Integer //the common types have both a short name...
assert 4.class == java.lang.Integer //...and a long name
assert 4.5.class == BigDecimal
assert 'hello, world'.class == String
def a= 7
assert a.class == Integer

Groovy中预定义了许多类,但Groovy代码只能看见最常用的类。除此以外,大多数类需要以包名修饰,例如,'java.text.DecimalFormat',
或者必须事先导入包:
import java.text.*
assert new DecimalFormat( '#,#00.0#' ).format( 5.6789 ) == '05.68'

或者
assert new java.text.DecimalFormat( '#,#00.0#' ).format( 5.6789 ) == '05.68'

如果一行代码被解释为合法的语句,它将如:
def i=
1 //because 'def i=' isn't a valid statement,
  //the '1' is appended to the previous line

//a compile error when uncommented: 'def j' is valid, so is interpreted as
//a statement. Then the invalid '= 1' causes the error...
/*
def j
= 1
*/

def k \
= 1 //a backslash ensures a line is never interpreted as a standalone statement

有时候一段代码无法编译:在示例中我们将其注释掉。其他代码可以编译但产生一个"checked exception"(已确认异常),我们可以捕捉和处理这些异常:
try{
  'moo'.toLong() //this will generate an exception
  assert false 
      //this code should never be reached, so will always fail if executed
}catch(e){ assert e instanceof NumberFormatException }
  //we can check the exception type using 'instanceof'

我们可以使用中括号来表示有序列表和键值映射:
def list= [1, 2, 3]
list= [] //empty list
list= [1, 'b', false, 4.5 ] //mixed types of values OK
assert list[0] == 1 && list[1] == 'b' && ! list[2] && list[3] == 4.5
  //we can refer to items individually by index

def map= [1:'a', 2:'b', 3:'c'] //map indicated with colon :
map= [:] //empty map
map= ['a': 1, 'b': 'c', 'groovy': 78.9, 12: true] //mixed types of values
assert map['a'] == 1 && map['b'] == 'c' && map['groovy'] == 78.9 && map[12]
  //we can refer to values individually by key

'each' tells the code following it to execute for each item in a list or map:
//for every item in list, assign to 'it' and execute the following code...
[ 2, -17, +987, 0 ].each{
  println it
}
//we can specify a different name for the argument other than the default...
[ 2, -17, +987, 0 ].each{ n -> 
  println n
}
//we can specify two or more arguments, as with this map...
[ 1: 3, 2: 6, 3: 9, 4: 12 ].each{ k, v-> 
  assert k * 3 == v
}

通过第一项和最后一项,我们可以指定一个范围'range':
( 3..7 ).each{ println it } //prints numbers 3, 4, 5, 6, and 7
( 3..<7 ).each{ println it } //prints numbers 3, 4, 5, and 6 //excludes 7

利用'as'关键字,我们可以把数据从一种类型转变成另一种类型:
assert ('100' as Integer) == 100

有时候,我们需要使用更为高效地序列类型:数组,其中每个元素的类型必须相同。语法无法直接表示数组,但是我们可以把一个序列轻易的转变为数组:
def x= ['a', 'b', 'c'] as Integer[] //convert each item in list to an Integer
assert x[0] == 97 && x[1] == 98 && x[2] == 99 //access each element individually

使用if-else语句来选择执行分支:
def a= 2
if( a < 5 ){
  println "a, being $a, is less than 5."
}else{
  assert false //this line should never execute
}


循环:
def i=0
10.times{ println i++ } //increment i by 1 after printing it

//another less declarative style of looping...
while( i > 0 ){
  println i-- //decrement i by after printing it
}

我们把代码包括在花括号之中留待以后执行。包括起来的代码就叫做"closable block" or "closure"(闭包):
def c= { def a= 5, b= 9; a * b }
assert c() == 45

[ { def a= 'ab'; a + 'bc' },
  { 'abbc' },
].each{ assert it() == 'abbc' }

我们可以从主线程生出新线程:
def i=0, j=0
def f= new File('TheOutput.txt') //create or overwrite this file
Thread.start{
  while(true){
    i++
    if(i%1000 == 0) f<< 'S' //spawned thread
  }
}
while(true){
  j++
  if(j%1000 == 0) f<< 'M' //main thread
}

比如说,5秒之后,终止该程序,并查看文件。在多数计算机上,它将显示大约均匀分布的'S'和'M'。但有些许不规则,
这表示线程调度不是完美分时的。

接下来的教程按照功能区域分组,从数字处理,再到Groovy的高级特色。

你可能感兴趣的:(groovy)