电子说
闭包在我们groovy
中起着很大比重,如果想要学好groovy
,闭包一定得掌握好,
在我们build.gradle
其实就有很多闭包使用:
如:
android{
sourceSets {
main{
jniLibs.srcDirs = ['libs']
}
}
}
这里面的
android {}
其实就是一个闭包结构,其内部的sourceSets{}
又是闭包中的闭包,可以看到闭包在我们的gradle
中无处不在.
学好闭包真的很关键
常用闭包方式:
{'abc'}
{ -> 'abc'}
{ -> "abc"+$it}
{ String name -> 'abc'}
{ name -> "abc${name}"}
{ name,age -> "abc${name}"+age}
闭包概念
:其实就是一段代码段,你把闭包想象为java中的回调Callback
即可,
闭包在Groovy
中是groovy.lang.Closure
的实例,可以直接赋值给其他变量.
闭包的调用
:
def closer = {1234}
closer()
closer.call()
闭包参数
:带参数的闭包 使用 -> 如果是一个参数可以直接使用it代替和kotlin中的lambda类型类似def closerParam = { name,age ->
println "hello groovy:${name}:${age}"
'return hei'
}
def result = closerParam("lily",123)
闭包返回值
:闭包返回值 如果没有定义return则直接返回最后一句话的返回值println result //打印结果:return hei
基本类型
结合使用://upto:实现阶乘
int x= fab_upTo(5)
println(x)
int fab_upTo(int number){
int result = 1
1.upto(number,{result*=it})
return result
}
//downto:实现阶乘
int x1= fab_downTo(5)
println(x1)
int fab_downTo(int number){
int result = 1
number.downto(1){result*=it}
return result
}
//times:实现累加
int x2 = cal(101)
println(x2)
int cal(int number){
def result = 0;
number.times {
result+=it
}
return result
}
String
结合使用String str = "the 2 and 3 is 5"
//each:遍历查找,返回值是str自己
println str.each {temp ->
print temp.multiply(2)
}
//find查找一个符合条件的
println str.find {
it.isNumber()
}
//findAll查找所有符合条件的,返回的是一个集合
println str.findAll {
it.isNumber()
}
//any表示查找只要存在一个符合的就是true
println str.any { s ->
s.isNumber()
}
//every表示全部元素都要符合的就是true
println str.every {
it.isNumber()
}
//将所有字符进行转化后,放到一个List中返回
def list = str.collect {
it.toUpperCase()
}
println(list)
5.2.3:与数据结构
结合使用:
这部分操作和与String结合使用类似,不再讲解
5.2.4:与文件
结合使用
这部分在讲解到文件操作的时候,再进行具体讲解
this,owner,delegate
情况1
:一般情况:
def scriptCloser = {
println "scriptCloser:this:${this}"
println "scriptCloser:owner:${owner}"
println "scriptCloser:delegate:${delegate}"
}
调用:scriptCloser()
结果:
scriptCloser:this:variable.Closer@58a63629
scriptCloser:owner:variable.Closer@58a63629
scriptCloser:delegate:variable.Closer@58a63629
可以看到一般情况下:三种都是相等的:都代表当前闭包对象
情况2
:我们来看下面的情况:闭包中有闭包
def nestClosure = {
def innerClosure = {
println "innerClosure:this:"+this.getClass()
println "innerClosure:owner:${owner.getClass()}"
println "innerClosure:delegate:${delegate.getClass()}"
}
innerClosure()
}
nestClosure()
结果:
innerClosure:this:class variable.Closer
innerClosure:owner:class variable.Closer$_run_closure10
innerClosure:delegate:class variable.Closer$_run_closure10
看到在闭包中调用闭包:
this还是执行外部的Closer对象,而
owner
和delegate
变为了Closer
的内部闭包对象
情况3
:最后来看一种情况:使用delegate委托
class Student{
def name
def pretty = {println "my name is ${name}"}
void showName(){
pretty.call()
}
}
class Teacher{
def name
}
Student stu1 = new Student(name: 'yuhb')
Teacher tea1 = new Teacher(name: 'lily')
//改变委托delegate
stu1.pretty.delegate = tea1
stu1.showName()
//设置委托策略
stu1.pretty.resolveStrategy = Closure.DELEGATE_FIRST
stu1.showName()
结果:
my name is yuhb
my name is lily
通过上面三种情况:
总结出:
this
:指向最外部的Closer对象owner
:执行当前闭包的Closer对象,特指当前,所以对闭包中的闭包,指向内部的闭包delegate
:这个是闭包的代理对象,如果有单独配置这个delegate,且设置了委托策略 =DELEGATE_FIRST
, 则闭包中的所有内部属性都会优先使用delegate中的对象
下面我们就来讲解闭包的委托策略
委托策略
闭包中给我提供了以下策略:
//优先使用ower中的属性
public static final int OWNER_FIRST = 0;
//优先使用delegate中的属性
public static final int DELEGATE_FIRST = 1;
//只是有owner中的属性
public static final int OWNER_ONLY = 2;
//只是有delegate中的属性
public static final int DELEGATE_ONLY = 3;
//使用this中的属性
public static final int TO_SELF = 4;
通过5.3.1中的例子,我们也可以看出Groovy默认使用的是OWNER_FIRST的委托策略
groovy文件操作完全兼容java的文件操作,但groovy集成了自己的高阶使用方式
withReader
def file = new File('../../hello_groovy.iml')
def buf1 = file.withReader {reader ->
char[] buf = new char[100]
reader.read(buf)
buf
}
println buf1
withWriter
//写文件:withWriter:实现文件拷贝操作
def result = copy('../../hello_groovy1.iml','../../hello_groovy.iml')
println result
def copy(String desFilePath,String srcFilePath){
try {
File desFile = new File(desFilePath)
if(!desFile.exists()){
desFile.createNewFile()
}
File srcFile = new File(srcFilePath)
if(!srcFile.exists()){
return false
}else{
srcFile.withReader {reader ->
def lines = reader.readLines()
desFile.withWriter {writer ->
lines.each {line ->
writer.write(line+'\\r\\n')
}
}
return true
}
}
}catch(Exception e){
return false
}
}
withObjectInputStream readObject
Groovy不仅可以写文件,还可以写入和读取对象操作
//读对象
def ob1 = readObject('../../person.bin')
println ob1
def readObject(String srcFilePath){
try {
File desFile = new File(srcFilePath)
if(!desFile.exists()){
return false
}
desFile.withObjectInputStream {
def person = it.readObject()
println person.name
}
return true
}catch(Exception e){
return false
}
}
withObjectOutputStream writeObject
//写对象:
Person person = new Person(name: 'uihb',age: 32)
saveObject(person,'../../person.bin')
def saveObject(Object obj,String desFilePath){
try {
File desFile = new File(desFilePath)
if(!desFile.exists()){
desFile.createNewFile()
}
if(obj != null){
desFile.withObjectOutputStream {
it.writeObject(obj)
}
}
}catch(Exception e){
return false
}
}
//1.Object 转JSon
def personList = [
new Person(name: 'lily',age: 12),
new Person(name: 'lucy',age: 14),
new Person(name: 'kare',age: 18)
]
def jsonPerson = JsonOutput.toJson(personList)
println JsonOutput.prettyPrint(jsonPerson)
//2.JSon转Object
def jsonSlurper = new JsonSlurper()
def obj = jsonSlurper.parseText(jsonPerson)
println(obj[0].name)
从网络获取Json数据操作:
这里引入OkHttp
def getNetWork(String url){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get()
.build();
Call call = client.newCall(request)
call.enqueue(new Callback() {
@Override
void onFailure(Request _request, IOException e) {
}
@Override
void onResponse(Response response) throws IOException {
def res = new String(response.body().bytes())
println res
JsonSlurper jsonSlurper1 = new JsonSlurper()
Version objetres = (Version)jsonSlurper1.parseText(res)
println objetres.ecode
}
})
sleep(10000)
}
class Version{
int ecode
String emsg
CurrentVersion data
}
class CurrentVersion{
String currentVersion
}
全部0条评论
快来发表一下你的评论吧 !