热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

第二节Scala基本类型及操作、程序控制结构

本节主要内容Scala基本类型基本类型操作Scala程序控制结构Scala基本类型Scala中的基本数据类型如下图:(来源:Progra

本节主要内容


  1. Scala基本类型
  2. 基本类型操作
  3. Scala程序控制结构

Scala基本类型

Scala中的基本数据类型如下图: 
这里写图片描述 
(来源:Programming in Scala)

从上表中可以看出,Scala的基本数据类型与Java中的基本数据类型是一一对应的,不同的是Scala的基本数据类型头字母必须大写,本节以Int、Long、String、Char、Double及Float类型为例介绍Scala的基本类型定义

整数类型变量定义:

//16进制定义法
scala> val x=0x29
x: Int = 41

  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

//十进制定义法
scala> val x=41
x: Int = 41

  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

//八进制定义法
scala> 051
res0: Int
= 41

  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

浮点类型变量定义:

//Double类型定义,直接输入浮点数,编译器会将其自动推断为Double类型
scala> val doubleNumber=3.141529
doubleNumber: Double = 3.141529

  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

//要定义Float类型浮点数,需要在浮点数后面加F或f
scala> val floatNumber=3.141529F
floatNumber: Float = 3.141529scala> val floatNumber=3.141529f
floatNumber: Float = 3.141529

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

浮点类型的变量还可以采用指数表示法,如

//浮点数指数表示法,e也可以是大写E,0.314529e1与0.314529*10等同
scala> val floatNumber=0.314529e1
floatNumber: Double = 3.14529

  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

字符变量定义:

//字符定义,用''将字符包裹
scala> var charLiteral='A'
charLiteral: Char = A

  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

常用特殊字符包括 
\n 换行符,其Unicode编码为 (\u000A) 
\b 回退符,其Unicode编码为 (\u0008) 
\t tab制表符 ,其Unicode编码(\u0009) 
\” 双引号,其Unicode编码为 (\u0022) 
\’ 单引号,其Unicode编码为 (\u0027) 
\ 反斜杆,其Unicode编码为(\u005C)

字符串变量定义:

//字符串变量用""包裹
scala> val helloWorld="Hello World"
helloWorld: String = Hello World//要定义"Hello World",可以加入转义符\
scala> val helloWorldDoubleQuote="\"Hello World\""
helloWorldDoubleQuote: String = "Hello World"//如果希望能够原样输出字符串中的内容,则用三个引号"""将字符串包裹起来,如
scala> println(""" hello cruel world, \n \\\\ \b \\, I am " experienced" programmer""")hello cruel world, \n \\\\ \b \\, I am " experienced" programmer

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

布尔类型定义:

scala> var x=true
x: Boolean = true

  • 1
  • 2
  • 1
  • 2

Scala基本类型操作

在Scala中一切操作皆方法,这意味着Scala中的一切皆为对象

算术操作:

//整数求和,编译器会将其转换为(1).+(2)执行
scala> var sumVlaue=1+2
sumVlaue: Int = 3//前一语句等同于下列语句
scala> var sumVlaue=(1).+(2)
sumVlaue: Int = 3//操作符重载,编译器会将其转换为(1).+(2L)执行
scala> val longSum = 1 + 2L
longSum: Long = 3//减法
scala> 1-3
res5: Int = -2//除法
scala> 1/3
res6: Int = 0//取模
scala> 1%3
res7: Int = 1//乘法
scala> 1L*3L
res8: Long = 3//scala中可以用+ -符号来表示正负数,例如-3 +3,并且可以加入到运算符当中
scala> var y=1+ -3
y: Int = -2

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

关系运算:

//>运算符
scala> 3 > -3
res12: Boolean = true
//<运算符
scala> 3 <-3
res13: Boolean &#61; false
//<&#61;运算符
scala> 3 <&#61; -3
res14: Boolean &#61; false
//<&#61;运算符
scala> 3 <&#61;3
res15: Boolean &#61; true
//<&#61;运算符
scala> !(3<&#61; -3)
res16: Boolean &#61; true

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

逻辑运算&#xff1a;

//逻辑与&#xff1a;&&
scala> val bool&#61;true
bool: Boolean &#61; truescala> bool && bool
res17: Boolean &#61; true
//逻辑或&#xff1a;||
scala> bool || bool
res18: Boolean &#61; truescala> bool || !bool
res20: Boolean &#61; true

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

位运算&#xff1a;

// 00000001
// 00000010
// 00000000
scala> 1 & 2
res24: Int &#61; 0// 00000001
// 00000010
// 00000011
scala> 1 | 2
res24: Int &#61; 3// 00000001
// 00000011
// 00000010
scala> 1 ^ 3
res24: Int &#61;2//00000001
//11111110
scala> ~1
res24: Int &#61;-2//左移位&#xff08;shift left&#xff09;
//00000110
//00001100
scala> 6 <<1
res29: Int &#61; 12//右移位&#xff08;shift left&#xff09;
//00000110
//00000011
scala> 6 >> 1
res28: Int &#61; 3//无符号右移&#xff08;shift left&#xff09;
//11111111111111111111111111111111
//00000000000000000000000000000001
scala> -1 >>> 31
res32: Int &#61; 1

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

对象比较&#xff1a;

scala> 1&#61;&#61;1
res34: Boolean &#61; truescala> 1&#61;&#61;1.0
res35: Boolean &#61; truescala> val x&#61;"Hello"
x: String &#61; Helloscala> val y&#61;"Hello"
y: String &#61; Hello//Scala中的对象比较不同于Java中的对象比较
//Scala基于内容比较&#xff0c;而java中比较的是引用&#xff0c;进行内容比较时须定义比较方法
scala> x&#61;&#61;y
res36: Boolean &#61; true

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

运算符的优先级&#xff1a; 
运算符优先级如下图所示&#xff0c;* / %优先级最高&#xff0c;依次类推 
这里写图片描述 
图片来源&#xff1a;Programming in Scala


Scala程序控制结构

if 的使用&#xff1a;

val x&#61; if("hello"&#61;&#61;"hell") 1 else 0

  • 1
  • 1

while 的使用&#xff1a;

def gcdLoop(x: Long, y: Long): Long &#61; {var a &#61; xvar b &#61; ywhile (a !&#61; 0) {val temp &#61; aa &#61; b % ab &#61; temp} b
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

do while的使用

var line &#61; ""
do {line &#61; readLine()println("Read: "&#43; line)
} while (line !&#61; "")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

注意&#xff1a;与if不同的是&#xff0c;while与do while不能用作表达式&#xff0c;也即其返回值为Unit&#xff0c;在某些函数式编程语言中&#xff0c;删除了while与do while程序控制结构&#xff0c;但scala仍然保留了while与do while&#xff0c;可见Scala并不是纯函数式编程语言&#xff08;另外一个重要原因是&#xff0c;scala函数定义时仍然可以用var指定参数&#xff09;。

//利用if替代while控制结构
//这些做可以减少var变量的使用&#xff0c;程序结构也更简单&#xff0c;表达能力更强
def gcd(x: Long, y: Long): Long &#61;
if (y &#61;&#61; 0) x else gcd(y, x % y)

  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

var line &#61; ""
while ((line &#61; readLine()) !&#61; "") // 在Scala中不能这么用&#xff0c;因为Scala中的赋值操作返回的值是Unit&#xff0c;而""是String类型&#xff0c;不能进行比较&#xff0c;这是函数式编程语言特有的特点
println("Read: "&#43; line)

  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

for循环的使用

scala> val filesHere &#61; (new java.io.File(".")).listFiles
//集合操作方式

scala> for (file <- filesHere)| println(file)

//间接调用方式(不常用&#xff09;

for (i <- 0 to filesHere.length - 1)
println(filesHere(i))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

//程序中的<-被称生成器&#xff08;generator&#xff09;&#xff0c;在执行过程中&#xff0c;集合filesHere中&#xff08;Array[File])的元素将依次赋给file&#xff0c;file类型为File&#xff0c;打印时调用其toString方法将文件名称打印出来。

scala> val filesHere &#61; (new java.io.File(".")).listFiles
filesHere: Array[java.io.File] &#61; Array(.\.android, .\.idea-build, .\.IdeaIC14, .
\.ivy2, .\.m2, .\.sbt, .\.scala_history, .\AppData, .\Application Data, .\Contac
ts, .\COOKIEs, .\Desktop, .\Documents, .\Downloads, .\Favorites, .\hello, .\Link
s, .\Local Settings, .\Music, .\My Documents, .\NetHood, .\NTUSER.DAT, .\ntuser.
dat.LOG1, .\ntuser.dat.LOG2, .\NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.
TM.blf, .\NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMContainer0000000000
0000000001.regtrans-ms, .\NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMCon
tainer00000000000000000002.regtrans-ms, .\ntuser.ini, .\Pictures, .\PrintHood, .
\Recent, .\Roaming, .\Saved Games, .\Searches, .\SendTo, .\target, .\Templates,
.\Videos, .\「开始」菜单)scala> for (file <- filesHere)| println(file)
.\.android
.\.idea-build
.\.IdeaIC14
.\.ivy2
.\.m2
.\.sbt
.\.scala_history
.\AppData
.\Application Data
.\Contacts
.\COOKIEs
.\Desktop
.\Documents
.\Downloads
.\Favorites
.\hello
.\Links
.\Local Settings
.\Music
.\My Documents
.\NetHood
.\NTUSER.DAT
.\ntuser.dat.LOG1
.\ntuser.dat.LOG2
.\NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TM.blf
.\NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMContainer000000000000000000
01.regtrans-ms
.\NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMContainer000000000000000000
02.regtrans-ms
.\ntuser.ini
.\Pictures
.\PrintHood
.\Recent
.\Roaming
.\Saved Games
.\Searches
.\SendTo
.\target
.\Templates
.\Videos
.\「开始」菜单

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

<-生成器对其它类型的集合也适用&#xff0c;

scala> 1 to 5
res39: scala.collection.immutable.Range.Inclusive &#61; Range(1, 2, 3, 4, 5)scala> for(i <- res39) println("Iteration"&#43;i)
Iteration1
Iteration2
Iteration3
Iteration4
Iteration5也可直接简写成
scala> for(i <- 1 to 5) println("Iteration"&#43;i)
Iteration1
Iteration2
Iteration3
Iteration4
Iteration5//如果不需要5出现&#xff0c;则用
scala> for(i <- 1 until 5) println("Iteration"&#43;i)
Iteration1
Iteration2
Iteration3
Iteration4

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在for循环结构中还可以加入if进行过滤操作

val filesHere &#61; (new java.io.File(".")).listFiles
for (file <- filesHere if file.getName.endsWith(".scala"))
println(file)
//还可以加入多个过滤条件&#xff0c;用;隔开
for (
file <- filesHere
if file.isFile;
if file.getName.endsWith(".scala")
) println(file)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

//多重循环的实现&#xff1a;

def fileLines(file: java.io.File) &#61;
scala.io.Source.fromFile(file).getLines.toList
def grep(pattern: String) &#61;
for (
file <- filesHere
if file.getName.endsWith(".scala");
line <- fileLines(file)
if line.trim.matches(pattern)
) println(file &#43;": "&#43; line.trim)
grep(".*gcd.*")//前一个for相当于下列语句
def grep(pattern: String) &#61;
for (
file <- filesHere
if file.getName.endsWith(".scala")
)
for(
line <- fileLines(file)
if line.trim.matches(pattern)
)
println(file &#43;": "&#43; line.trim)
grep(".*gcd.*")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

生成返回结果

//每次循环将结果保留&#xff0c;当整个循环执行完毕&#xff0c;所有保留的值将会生成一个集合并返回
scala> def scalaFiles &#61;| for {| file <- filesHere| if file.getName.endsWith(".scala")| } yield file
scalaFiles: Array[java.io.File]//Array[File]到Array[Int]的转换
scala> val forLineLengths &#61;| for {| file <- filesHere| if file.getName.endsWith(".scala")| line <- fileLines(file)| trimmed &#61; line.trim| if trimmed.matches(".*for.*")| } yield trimmed.length
forLineLengths: Array[Int] &#61; Array()

推荐阅读
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 摘要: 在测试数据中,生成中文姓名是一个常见的需求。本文介绍了使用C#编写的随机生成中文姓名的方法,并分享了相关代码。作者欢迎读者提出意见和建议。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
author-avatar
张嫱的小屋_133
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有