标签: Groovy

Groovy基本语法(三)

Groovy中的循环
可以说,Groovy把Java循环结构折腾的面目全非,似乎主流脚本语音能用到的循环方式Groovy都给加了进去,实际上不同的循环语法和功能差异很小,这类玩意儿多了意义并不明显,例如我就比较喜欢for循环而不太爱用while循环,但并不是说while循环没有用处,虽然for循环完全可以涵盖while循环的所有功能。
Groovy的开发者目标很明确,让Groovy的语法甜的腻死你们!

package plswg.edu.groovy.basic

// groovy中可以使用传统的while循环或for循环

n = 0
while (n < 10) {
print n + ” ”
n++
}
println “”

for (i = 0; i < 10; i++) {
print i + ” ”
}
println “\r\n”

// groovy引入新风格的for循环

for (i in 0 .. 9) { // (i in 0 .. 9)表示循环从i=0开始,到i<=9时结束
print i + ” ”
}
println “”

// 利用数值类型可以也可以进行循环

// 利用整数的upto方法进行循环
i = 0
i.upto(9) { // 整数的upto方法可以启动一个循环, 循环体在一个闭包内执行
print it + ” ” // 在闭包内部,it关键字表示循环过程的整数值
}
println “; at the end of loop, the var i is ” + i // 循环结束后i的值仍是0,不会增加到9

// upto方法可以用在常量上
10.upto(19) { // 10.upto(20)表示从10开始循环到19结束
print it + ” ”
}
println “”

// upto方法中的整数是循环的起始点,time方法可以将整数作为循环的终止点
10.times { // 10.times表示从0开始循环到9结束
print it + ” ”
}
println “”

// step方法可以设置循环的步长值
0.step(11, 2) { // 0.step(11, 2)表示从0循环到11,每次循环值增加2
print it + ” ”
}
println “\r\n”

// 例子,利用groovy新语法输出一个99乘法表
// 方法1
for (i in 1 .. 9) {
for (j in 1 .. 9) {
z = i * j
print ((z < 10 ? ” ” + z : z) + ” “)
}
println “”
}
// 方法2
1.upto(9) {
x = it
1.upto(9) {
z = x * it
print ((z < 10 ? ” ” + z : z) + ” “)
}
println “”
}
// 方法3
9.times {
x = it + 1
9.times {
z = x * (it + 1)
print ((z < 10 ? ” ” + z : z) + ” “)
}
println “”
}
可以看到,Groovy对Java循环结构作了如下的修整:
对于for循环:除了传统三表达式的for循环和用于迭代的for each循环外,Groovy允许for循环遍历一个范围(Range),例如 for (i in 1..10),表示循环10次,i在1至10之间取值;
对于整数,Groovy增加了如下几个方法来进行循环:
upto:n.upto(m) 函数,表示循环 m- n 次,并且会有一个循环变量it,从n开始,每次循环增加1,直到m。循环体写在upto方法之后大括号中,表示一个闭包,在闭包中,it作为循环变量,值从a增长到n;
times:n.times 函数,表示循环n次,循环变量it从0开始到n结束。
step:n.step(x, y) 函数,表示循环变量从n开始到x结束,每次循环后循环变量增加y,所以整个循环次数为 (x – n) / y 次;
6、字符串

Groovy对字符串增加了一些新的特性,让字符串操作更加简单了:

package plswg.edu.groovy.basic

// groovy中对字符串的使用做了大量的简化

// 获取字符串中的字符
s = “Hello”
println s[0] // 输出’H’

// 遍历字符串中的所有字符
s.each {
print it + “, ” // 遍历字符串中的所有字符
}
println “”

// 截取字符串
s1 = s[1..3] // 截取s字符串标号从1到3的3个字符,组成新的字符串赋予s1
// 该语法是String类的substring方法的简化
println s1

// 模板式字符串

n = 100
s1 = “The number n is ${n}” // ${n}表示将变量n的值放在字符串该位置
println s1

// 带格式的长字符串
// “””和”””之间的所有字符都会被算做字符串内容,包括// /*以及回车,制表符等
s = “””
大家好
欢迎大家学习Groovy编程
Groovy is a better Java
“””
println s

// groovy中单引号的作用

// 在不定义类型时,单引号也表示字符串
c1 = ‘A’
println c1.getClass().getName()

// 要明确的定义字符类型,需要给变量增加定义
char c2 = ‘A’
println c2.getClass().getName()

// 取消转义字符
s = ‘c:\\windows\\system’
println s
s = /c:\windows\system/ // 利用/字符串/定义的字符串
println s

// 字符串运算
s = “hello”
s = s + ” world” // +运算符用于连接字符串
println s

s -= “world” // -可以从字符串中去掉一部分
println s

s = s * 2 // *可以让字符串重复n次
println s

// 字符串比较
s1 = “Abc”
s2 = “abc”

println s1 == s2 ? “Same” : “Different” // 执行s1.equals(s2)
println s1 != s2 ? “Different” : “Same” // 执行!s1.equals(s2)
println s1 > s2 ? “Great” : “Less” // 执行s1.compareTo(s2) > 0
println s1 < s2 ? “Less” : “Great” // 执行s1.compareTo(s2) < 0
// s1 >= s2, s1 <= s2
println s1 <=> s2 == 1 ? “Same” : “Different” // 执行s1.compareTo(s2)
Groovy增加了对字符串的如下操作:
集合操作,Groovy将字符串看为字符的集合,可以通过 [n] 运算符直接访问字符串内的字符,也可以通过each循环遍历字符串的每一个字符;
截取子字符串的substring方法被简化为使用数值范围来进行截取,”hello”[1..3]表示截取字符串”hello”从下标为1到下标为3的部分,结果为 “ell”;
Groovy增加了一个新的字符串类型 GString,这种字符串可以进行格式化,在GString字符串中使用 ${变量},可以将该变量的值放入字符串的相应位置;
带格式的字符串,使用 “””字符串内容”””(连续的三个引号),这种字符串中可以包含直接输入的回车,TAB键,//或/*等字符,而这些在Java原本的字符串里,都必须通过转义字符来表示,例如只能用\n表示回车;
单引号问题,和Javascript和PHP类似,Groovy中无论是单引号还是双引号都表示是字符串类型,例如 ‘a’ 和”a”都是字符串类型,所以如果要确定存储一个 char 类型变量,就必须使用 char 类型定义强类型变量;实际上Groovy认为char类型并不是必须的,大部分时候字符串类型更方便一些;
用 / 包围的字符串,即 /字符串内容/,可以避免在字符串中使用转义字符,但 \n 字符不包含在内;
Java中对字符串的运算只有+运算,在Groovy中,字符串还可以使用 -运算 和 *运算,减法运算可以从一个字符串中删除一部分,乘法运算可以将一个字符串重复n次;
Groovy还为字符串加入了所有关系运算符,包括 ==, !=, >, <, >=, <=,这要归功于Groovy允许运算符重载,对于 == 和 !=,将调用String类的equals 方法,对于 >, >=, <, <=,将调用String类的compareTo方法;Groovy还增加了一个特殊的运算符<=>,这个运算符也会调用 compareTo 方法,返回 compareTo 方法的返回值;
Groovy对字符串增强了很多,使其更加方便使用,也更加符合主流动态语言的语法设定,当然这里面很多内容并不是简单的针对字符串的,例如Groovy的闭包,运算符重载等特性,都侧面的让Groovy字符串更加强大

Groovy基本语法(二)

静态import

我是*早在.net framework 3.5上使用类似import static这种语法的,用起来相当方便的说,但JDK一直没有引入这玩意儿,按道理说加上这么个小功能是很容易实现的。不过Groovy倒是带来来功能更强大的import static语法,用起来也很方便:

package plswg.edu.groovy.basic

// 将Integer类的MAX_VALUE静态成员变量引入
import static Integer.MAX_VALUE

// 将Double类的parseDoubl静态成员方法引入
import static Double.parseDouble

// 给静态引入赋予别名
import static Boolean.TRUE as T // 将Boolean.TRUE取名为T
import static Boolean.FALSE as F // 将Boolean.FALSE取名为F

// 给静态引入的方法赋予别名
import static Calendar.getInstance as now

// 代码中凡是用到MAX_VALUE, 指的都是Integer.MAX_VALUE
println MAX_VALUE

// 代码中凡是用到parseDouble, 指的都是Double.parseDouble
s = “123.123”
println parseDouble(s);

// 代码中凡是使用T的地方表示true,使用F的地方表示false
println T
println !T
println F

// 代码中凡是使用now的地方表示Calendar.getInstance
println now().get(Calendar.HOUR)
这玩意儿的主要作用就是避免重复书写哪些又臭又长的类名,随着JDK类库的不断增加,类名字是越来越长,像造句一样,import static恰好解决了这一问题,还是很贴心的。
5、分支结构语句

Groovy的结构化语句仍旧是三种:顺序结构、分支结构和循环结构,其中分支结构和循环结构增加了很多意想不到的功能,先看分支结构:
package plswg.edu.groovy.basic

// groovy中if条件分支的新规定

// groovy中,非0的数值可以表示true
int num = 0
if (num) {
println “True”
} else {
println “False”
}

println (++num ? “True” : “False”)

if (!!num) { // !!运算符可以将num转化为boolean类型
println “num=${num}为${!!num}”
}
println “”

// 引用为null时,表示false
Object o = null
if (o) {
println “True”
} else {
println “False”
}
o = new Date()
if (o) {
println “True”
} else {
println “False”
}
println “”

// 字符串为””时,表示false
String s = “”
if (s) {
println “True”
} else {
println “False”
}
s += “hello”
if (s) {
println “True”
} else {
println “False”
}
println “”

// 集合为空时,表示False
ArrayList array = new ArrayList()
if (array) {
println “True”
} else {
println “False”
}
array.add(100)
if (array) {
println “True”
} else {
println “False”
}
println “”

// groovy中switch选择分支的新规定

// switch对字符串类型的支持

print “Please input your words: ”
s = new BufferedReader(new InputStreamReader(System.in)).readLine()

switch (s) {
case “how are you”:
println “fine, thank you”
break;
case “how do you do”:
println “how do you do too”
break;
default:
println “nice to meet you”
}

// switch对集合和范围的支持
n = new Random().nextInt(101)
print “you got ${n} point, ”
switch (n) {
case [98, 99, 100]: // n为98, 99, 100这三个数字时
println “very good!!”
break;
case 90 .. 97: // n为90-97之间时
println “nice job!!”
break;
case 70 .. 89: // n为70-89之间时
println “good”
break;
case 60 .. 79: // n为60-79之间时
println “can be better”
break;
case {it > 0 && it < 60}: // n比0大且比60小时
println “too bad”
break;
case 0: // n为0时
println “nothing to say”
break;
}
首先,Groovy对boolean类型放宽了限制:
常量true和false分别表示“真”和“假”;
null表示false,非null表示true;
空字符串””表示false,非空字符串表示true;
0表示false,非0表示true;
空集合表示false,非空集合表示true;
好了,从这一角度上,Groovy确实和Javascript或者PHP非常相似了,用起来非常方便。
Groovy中对于switch语句的修改也是非常夸张的,这让我甚至有些怀疑Groovy中的switch是否还能达到O1的执行效率,因为Groovy的swtich表现的太像嵌套的if…else if了,在例子中,switch的case后面可以跟随如下几种玩意儿:

常量,在Groovy中,case后的常量包括数值型常量或字符串类型常量,方便很多了,JDK7中新增加了使用字符串常量的case语句,而在.net framework 1.1中早就有了,诸如Basic,PHP,Python,Javascript等脚本,更是一开始就支持字符串常量的case语句;
Range:即范围,语法 n1 .. n2 表示n1和n2之间的所有数值n(n1 <= n <= n2);
Collection:集合,语法 [a1, a2, a3, … , an],表示由中括号中的n个元素构成的集合,其中各个元素类型不必统一;
闭包:由 { 语句 } 构成的匿名函数体,这个后面会重点讲述,这里只要知道,一旦case之后的闭包返回true,则冒号之后的代码将会执行;
总之Groovy对分支语句的改造,让其更符合主流动态语言的特点,目前大家都在玩动态语言,就算强类型语言例如C#也在向动态语言方向靠拢,C++有泛型可以一直淡定,Java也有泛型,但那就不是个玩意儿。Groovy这下改的彻底,该有的全都有了!

Groovy基本语法(一)

Starting Groovy

相比于一个传统的Java类,一个包含main方法的Groovy类可以如下书写:

代码1:具有main函数的Groovy类
package plswg.edu.groovy.basic

// 利用class关键字创建一个groovy类
class G01_HelloWorldClass {

// 静态的main方法作为程序入口
static main(args) {

// 使用println命令输出
println “HelloWorld in class”
}

}
和Java一样,程序会从这个类的main方法开始执行,和Java的区别是:

class前省略public修饰;
main方法前省略public修饰;
main方法省略返回值类型void;
main方法形参列表省略类型String[];
当然,这只是Groovy代码的一种写法,实际上执行Groovy代码完全可以不必需要一个类或main方法,所以更简单的写法如下:
package plswg.edu.groovy.basic

// 对于groovy程序来说,可以没有类和main方法,直接书写的代码就可以作为脚本运行
println “HelloWorld in script”
这段代码仍可以直接运行。

实际上,*终编译器仍会为这段代码生成一个类,类名和文件名相同,只不过从源码的角度上,确实不用写类或者main方法了,这一点很像Javascript等其它脚本语言。

可以注意到,Groovy将Java中繁琐的System.out.println简化为了println,甚至可以不为形参列表加括号,这都是允许的,Groovy非常简洁,甚至不要求语句末尾的分号(当然,写上分号也无伤大雅)

3、Groovy变量

既然是脚本语言,Groovy的变量也被设计成为了类似的弱类型,实际上Groovy同时支持强类型变量和“弱”类型变量,强类型变量拥有自己的类型,而“弱”类型变量则全部会被编译为Object类型,从代码的角度上,Groovy的变量无需声明类型了:

package plswg.edu.groovy.basic

// groovy可以使用类型确定的变量或常量

String s1 = “Hello ”
print s1

final String s2 = “World”
println s2

// 利用def关键字可以定义可变类型的变量或常量

def s3 = “Welcome ”
print s3

// 对于可变类型,即随时可以改变其类型,赋予不同的量

s3 = 123 // 此时str3被赋予了整型量,所以其类型变为Integer类型
println s3

s3 += 100 // 整型的str3和整型相加,结果是整型223
println s3

s3 = true // str3目前是boolean类型
println (“Ok ” + s3)

// 对于局部变量,甚至可以不使用def关键字来定义
s4 = “Good job”
println s4

// 对于数值类型,有如下规则

int n1 = 10
n2 = n1 / 3
println n2 // 对于n1为整数时, 10 / 3的结果并不是整数,这说明常量n2并不是整数

int n3 = n1 / 3 // 明确定义n3为整数后,相除的结果为整数
println n3

n2 = n1.intdiv(3)
println n2 // intdiv用于进行整除

n2 = n1.power(2) // 求平方 groovy方法
println n2

n2 = n1 ** 2 // 求平方的groovy语法
println n2

n1 = Math.sqrt(n2) // 求开方 java方法
println n1
从上面的代码可以看到,Groovy支持有类型的变量,例如 String s;也支持无类型的变量,例如 def s,相当于Java中的Object s;对于无类型的变量,甚至可以不写 def关键字。
final关键字依然作为常量标识,这一点和Java相同。

*后注意一点,Groovy中没有Java中的值类型简单对象,所有的对象都是引用类型对象,例如定义def n = 10,n的类型应该是Integer类型而不是int类型;即便定义了int n = 100,n的类型依然是Integer类型;如果定义了def n = 12.34,则注意,n的类型是BigDecimal类型而不是Double类型,只有显式定义double n = 12.34,n的类型才明确为Double类型(依旧不是double类型)

对于基本算术运算符,Groovy增加了**运算符,表示求幂,x ** y表示求x的y次方

如何使用Groovy操作文件

1. 读文件

读文件内容

在groovy中输出文件的内容:

println new File("tmp.csv").text

上面代码非常简单,没有流的出现,没有资源关闭的出现,也没有异常控制的出现,所有的这些groovy已经搞定了。

读取每一行内容:

  1. File file = new File(‘tmp.csv’)
  2. assert file.name == ‘tmp.csv’
  3. assert ! file.isAbsolute()
  4. assert file.path == ‘tmp.csv’
  5. assert file.parent == null
  6. //使用系统默认的编码处理文件流
  7. file.eachLine {println it }
  8. //指定处理流的编码
  9. file.eachLine(“UTF-8”) { println it }
  10. file.eachLine(“UTF-8”,10) {str,no->
  11. println str
  12. println no }

对文件中每一行的内容做处理:

  1. file.splitEachLine(“\t”) { println it }
  2. //以大写行式输出文件内容
  3. lineList = file.readLines();
  4. liineList.each {
  5. println it.toUpperCase();
  6. }
  7. file.filterLine {String str->
  8. if (str.contains(‘code’))
  9. println str
  10. }.writeTo(new PrintWriter(System.out))

解析 xml 文件

  1. <?xml version=”1.0″ encoding=”UTF-8″?>
  2. <customers>
  3. <corporate>
  4. <customer name=“bill gates” company=“microsoft”></customer>
  5. <customer name=“steve jobs” company=“apple”></customer>
  6. <customer name=“bill dyh” company=“sun”></customer>
  7. </corporate>
  8. <consumer>
  9. <customer name=“jone Doe”></customer>
  10. <customer name=“jane Doe”></customer>
  11. </consumer>
  12. </customers>

 

  1. def customers = new XmlSlurper().parse(new File(“customers.xml”))
  2. /*对文件进行解析*/
  3. for(customer in customers.corporate.customer){
  4. println “${customer.@name} works for${customer.@company}”;
  5. }

解析 propeties 文件

参考 groovy: How to access to properties file?,代码如下:

  1. def props = new Properties()
  2. new File(“message.properties”).withInputStream {
  3. stream -> props.load(stream)
  4. }
  5. // accessing the property from Properties object using Groovy’s map notation
  6. println “capacity.created=” + props[“capacity.created”]
  7. def config = new ConfigSlurper().parse(props)
  8. // accessing the property from ConfigSlurper object using GPath expression
  9. println “capacity.created=” + config.capacity.created

另外一种方式:

  1. def config = new ConfigSlurper().parse(new File(“message.groovy”).text)
  2. message.groovy 内容如下:
  3. capacity {
  4. created=“x”
  5. modified=“y”
  6. }

 

2. 操作目录

列出目录所有文件(包含子文件夹,子文件夹内文件) :

  1. def dir = new File(dirName)
  2. if (dir.isDirectory()) {
  3. dir.eachFileRecurse { file ->
  4. println file
  5. }
  6. }
  7. dir.eachFileMatch(~/.*\.txt/) {File it-> println it.name } //使正则表达式匹配文件名
  8. dir.eachFileMatch(FILES, ~/.*\.txt/) { File it-> println it.name }

 

3. 写文件

  1. import java.io.File
  2. def writeFile(fileName) {
  3. def file = new File(fileName)
  4. if (file.exists())
  5. file.delete()
  6. def printWriter = file.newPrintWriter() //
  7. printWriter.write(‘The first content of file’)
  8. printWriter.write(‘\n’)
  9. printWriter.write(‘The first content of file’)
  10. printWriter.flush()
  11. printWriter.close()

除了  file.newPrintWriter()  可以得到一个 PrintWriter,类似方法还有  file.newInputStream() 、 file.newObjectInputStream() 等。

更简洁写法:

  1. new File(fileName).withPrintWriter { printWriter ->
  2. printWriter.println(‘The first content of file’)
  3. }

 

配置Groovy开发运行环境

      虽然一直在做C和C++,但只要涉及到能用Java或者.net开发的部分,还是很愿意用这两者进行开发的。虽然相比于C/C++,Java或.net的灵活性小了一些,但后者开发的效率真的是相当高,而且写起来也不会像C/C++那样让人郁闷。

      这两年C#的发展可谓是精彩,Microsoft真不愧是*牛X的拿来主义公司,C#结合了多种语言的优点,写代码相当流畅,特别是C#描述中间件和API时可选的表现方法更多,对于类库使用者的要求更低,真的很不错。

      当然,相比Phyton、Ruby或者Javascript这类脚本,任何强类型语言都显得不那么灵活,就好比PHP能提供比C语言更多的语言特性,包括闭包这样强大的功能。C#能以一种强类型语言做到相当多的动态语言特性,真是很了不起。对应Java,这两年发展的真的很慢,*新版本的JDK 7,也不过是增加了.net framework 2.0中几个常用功能,和.net framework 4相比依然相差很远。Java上有Spring等如此强大的API,语言本身却简单的近乎粗陋,真是不好说。

      有人说Java就应该是这样的,就应该用getter/setter而不用=运算符,就应该不停的throws,就应该用一大票的interface,就应该不能自定义值类型……但我总觉得,开发人员喜欢什么样的设计模式都不能成为语言本身不提供该功能的理由。

      否则,Groovy为什么会出现呢?

      不吐槽了,既然Java上诞生了Groovy,这门语法甜的发腻的语言就肯定会让很多人喜欢它!虽然Groovy目前还存在效率方面的问题,它甚至比Javascript更慢,但Groovy毕竟是依赖于Java的,毕竟是和Java无缝挂接的,毕竟具备Java, Javascript, Phython, Ruby等等语言的优点,所以我估计谁也不能阻止Groovy的前进了!

 1、配置Groovy开发环境

      由于Groovy是基于JDK的,所以安装Groovy之前肯定要安装JDK了,从http://www.oracle.com/technetwork/java/javase/downloads/index.html可以下载到*新的JDK,写这篇文章时,JDK已经更新到JDK 7u2了,下载安装包安装即可。

      Groovy的安装挺简单的,基本上和JDK的安装差不多,从http://groovy.codehaus.org/Download下载Groovy的GDK环境的安装包Windows-Installer(应该是1.8版本了),直接安装就可以了;如果下载的是zip版本,则按照如下步骤设置即可:

将zip包解压到随便那个目录中,如d:\devtools\groovy1.8.4
设置环境变量GROOVY_HOME,值为放置解压文件的目录,如d:\devtools\groovy1.8.4
增加环境变量path,指向%GROOVY_HOME%\bin
接下来就可以在Groovy控制台中编写脚本了,在Windows控制台(cmd)下输入groovyconsole命令进入groovy控制台,在里面输入代码 println “HelloWorld”回车,按组合键CTRL+R就可以看到运行结果了。
当然,这是Groovy自带的*基本的开发工具,很不实用,对于Groovy,NetBeans,IntelliJ IDEA等开发环境都提供了完善的支持,eclipse也提供了对应的插件。这里主要说一下eclipse中安装插件的办法。

到http://www.eclipse.org/downloads/上下载*新版本的eclipse,目前是3.7.1版本,下载后解压到任意目录即可运行;
打开eclipse,选择菜单项“Help->Install New Software”,再打开的对话框中按下Add按钮,在其中输入网址 http://dist.springsource.org/release/GRECLIPSE/e3.7/后确定;

%title插图%num
图1

%title插图%num
图2

                    等上一会儿,直到eclipse从网上找到找到要安装的包,此时把要安装的包前面的复选框选中(全选即可),点击Finish按钮即可开始安装

%title插图%num
图3

            其实我试了几次在线安装,都是安装到一半的时候由于神奇的未知网络原因,安装中断,所以*终我使用的是离线安装的办法:
从http://dist.springsource.org/release/GRECLIPSE/e3.7/archive-2.6.0.xx-20111212-0900-e37-RELEASE.zip下载离线安装包,注意,直接下载速度不会超过1kbps,请各位同学自行寻找访问伟大祖国以外神奇网站的具体方法,我使用GoAgent,可以在10Mbps的带宽上达到200多bps的下载;
注意下载的这个安装包不能使用eclipse传统的插件安装方式(内含Groovy编译器),无论覆盖方式、Link文件方式还是dropins目录方式都玩不转,还得使用eclipse的”Help->nstall New Software“方式安装;
当打开上述图2的对话框后,不要填写网址,按下Achieve按钮,在出现的对话框中填写下载文件的路径和文件名

%title插图%num

图4

            点击OK,继续安装即可
插件安装后重启eclipse,在新建项目中应该包含了Groovy Project和Groovy Class,这就表示Groovy插件安装成功,可以利用eclipse开发Groovy应用程序了!

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速