iOS开发系列--Swift语言_第1页
iOS开发系列--Swift语言_第2页
iOS开发系列--Swift语言_第3页
iOS开发系列--Swift语言_第4页
iOS开发系列--Swift语言_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、iOS开发系列-Swift语言2015-08-10 12:09 by KenshinCui, 26622 阅读, 57 评论, 收藏, 编辑概述Swift是苹果2014年推出的全新的编程语言,它继承了C语言、ObjC的特性,且克服了C语言的兼容性问题。Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在其中你可以看到C#、Java、Javascript、Python等多种语言的影子。同时在2015年的WWDC上苹果还宣布Swift的新版本Swift2.0,并宣布稍后Swift即将开源,除了支持iOS、OS X之外还将支持linux。本文将继续iOS开发系列教程

2、,假设读者已经有了其他语言基础(强烈建议初学者从本系列第一章开始阅读,如果您希望从Swift学起,那么推荐你首先阅读苹果官方电子书the swift programming language),不会从零基础一点点剖析这门语言的语法,旨在帮助大家快速从ObjC快速过度到Swift开发中。即便如此,要尽可能全面的介绍Swift的语法特点也不是一件容易的事情,因此本文将采用较长的篇幅进行介绍。创建一个命令行程序如下:import Foundation /* Swift没有main函数,默认从top level code的上方开始自上而下执行(因此不能有多个top level代码)*/println(

3、Hello, World!)从上面的代码可以看出:Swift没有main函数,从top level code的上方开始往下执行(就是第一个非声明语句开始执行表达式或者控制结构,类、结构体、枚举和方法等属于声明语句),不能存在多个top level code文件(否则编译器无法确定执行入口,事实上swift隐含一个main函数,这个main函数会设置并调用全局 “C_ARGC C_ARGV”并调用由top level code构成的top_level_code()函数);Swift通过import引入其他类库(和Java比较像);Swift语句不需要双引号结尾(尽管加上也不报错),除非一行包含多

4、条语句(和Python有点类似);数据类型Swift包含了C和ObjC语言中的所有基础类型,Int整形,Float和Double浮点型,Bool布尔型,Character字符型,String字符串类型;当然还包括enum枚举、struct结构体构造类型;Array数组、Set集合、Dictionary字典集合类型;不仅如此还增加了高阶数据类型元组(Tuple),可选类型(Optinal)。基础类型Xcode 从6.0开始加入了Playground代码测试,可以实时查看代码执行结果,下面使用Playground简单演示一下Swift的基础内容,对Swift有个简单的认识:import Found

5、ation var a:Int=1 /通过var定义一个变量 /下面变量b虽然没有声明类型,但是会自动进行类型推断,这里b推断为Int类型var b=2 var c:UInt=3let d=a+b /通过let定义一个变量 /下面通过()实现了字符串和变量相加(字符串插值),等价于println(d=+String(d)println(d=(d) /结果:d=3 /注意由于Swift是强类型语言,a是Int类型而c是UInt类型,二者不能运算,下面的语句报错;但是注意如果是类似于:let a=1+2.0是不会报错的,因为两个都是字面量,Swift会首先计算出结果再推断a的类型/let e=a+

6、c /Int.max是Int类型的最大值,类似还有Int.min、Int32.max、Int32.min等let e=Int.max /结果:9223372036854775807 var f:Float=1.0var g=2.0 /浮点型自动推断为Double类型 var h:String=hello /emoj表情也可以作为变量或者常量,事实上所有Unicode字符都是可以的var =love and apple /两个字符串相加,但是注意不同类型不能相加var i=h+ /结果:hello love and apple /布尔类型只有两个值true、false,类似于if语句中的条件只能

7、是布尔类型不能像ObjC一样非0即真var j:Bool=true /字符类型,同样使用双引号,但是只能是一个字符,如果不指定类型则c默认会推断为字符串(var k:Character=c是字符类型,但是var k=c是字符串类型)var k:Character=c var l=00100 /等于100,可以在前面添加额外的0var m=10_000_000 /等于10000000,可以使用增加额外的下划线方便阅读而不改变值的大小Swift通过var进行变量定义,通过let进行常量定义(这和其他高级语言比较类似,例如F#);Swift添加了类型推断,对于赋值的常量或者变量会自动推断其具体类型;

8、Swift是强类型语言(应该说它比C#、Java等强类型语言控制还要严格),不同的数据类型之间不能隐式转化,如果需要转化只能强制转化;在Swift中类型转换直接通过其类型构造函数即可,降低了API的学习成本;集合类型Swift提供了三种集合类型:数组Array、集合Set、字典Dictionary。和ObjC不同的是,由于Swift的强类型,集合中的元素必须是同一类型,而不能像ObjC一样可以存储任何对象类型,并且注意Swift中的集合是值类型而非引用类型(事实上包括String、结构体struct、枚举enum都是值类型)。首先看一下Swift中的数组:/声明数组的时候必须确定其类型,下面使

9、用String声明一个字符串数组(String是Array简单表达形式)/var a:Array=hello,worldvar a:String=hello,worlda0 /访问数组元素 /下面创建一个Double类型的数组,这里没有使用字面量,当前是一个空数组,当然也可以写成var b:Double=var b=Double() for i in a println(i=(i) /添加元素,Swift中可变类型不再由单独的一个类型来表示,统统使用Array,如果想声明为不可变数组只要使用let定义即可a.append(!) a+=I ,am ,Kenshin /追加元素 println(a

10、.count=(a.count) /结果:a.count=6 a3.5=I,Love,Swift /修改元素,但是注意无法用这种方式添加元素/a6=./这种方式是错误的 a.insert(New, atIndex: 5) /插入元素:hello world! I Love New Swift a.removeAtIndex(5) /删除指定元素 /使用全局enumerate函数遍历数据索引和元素for (index,element) in enumerate(a) println(index=(index),element=(element) /使用构造函数限制数组元素个数并且指定默认值,等价

11、于var c=Array(count: 3, repeatedValue: 1),自动推断类型var c=Int(count: 3, repeatedValue: 1)Set表示没有顺序的集合:/注意集合没有类似于数组的简化形式,例如不能写成var a:String=hello,worldvar a:Set=hello,worldvar b:Set=1,2 /类型推断:Set a.insert(!) /注意这个插入不保证顺序 if !a.isEmpty /判断是否为空 a.remove(!) if !a.contains(!) a.insert(!)Dictionary字典同样是没有顺序的,并

12、且在Swift中字典同样要在使用时明确具体的类型。和ObjC中一样,字典必须保证key是唯一的,而这一点就要求在Swift中key必须是可哈希的,不过幸运的是Swift中的基本类型(如Int、Float、Double、Bool、String)都是可哈希的,都可以作为key。/通过字面量进行字典初始化,注意等价于var a:Dictionary=200:success,404:not foundvar a:Int:String=200:success,404:not foundvar b=200:success,404:not found /不声明类型,根据值自动推断类型 a200 /读取字典a

13、404=can not found /修改 a500=internal server error /添加/a=: /设置为空字典,等价于:a=Int:String() for code in a.keys println(code=(code) for description in a.values println(description=(description) for (code,description) in a println(code=(code),description=(description)注意:在Swift中集合的可变性不是像ObjC一样由单独的数据类型来控制的,而是通过

14、变量和常量来控制,这一点和其他高级语言比较类似。元组(Tuple)在开发过程中有时候会希望临时组织一个数据类型,此时可以使用一个结构体或者类,但是由于这个类型并没有那么复杂,如果定义起来又比较麻烦,此时可以考虑使用元组。/* * 元组的基本用法 */var point=(x:50,y:100) /自动推断其类型:(Int,Int)point.x /可以用类似于结构体的方式直接访问元素,结果:50point.y /结果:100point.0 /也可以采用类似数组的方式使用下标访问,结果:50point.1 /结果:100 /元组也可以不指定元素名称,访问的时候只能使用下标let frame:(I

15、nt,Int,Int,Float)=(0,0,100,100.0)println(frame) /结果:(0, 0, 100, 100.0) /注意下面的语句是错误的,如果指定了元组的类型则无法指定元素名称/let frame:(Int,Int,Int,Int)=(x:0,y:0,width:100,height:100) var size=(width:100,25) /仅仅给其中一个元素命名size.width /结果:100size.1 /结果:25 var httpStatus:(Int,String)=(200,success) /元组的元素类型并不一定相同 var (status,

16、description)=httpStatus /一次性赋值给多个变量,此时status=200,description=success /接收元组的其中一个值忽略另一个值使用_(注意在Swift中很多情况下使用_忽略某个值或变量)var (sta,_)=httpStatusprintln(sta=(sta) /结果:sta=200 /* * 元组作为函数的参数或返回值,借助元组实现了函数的多个返回值 */func request()-(code:Int,description:String) return (404,not found)var result=request()result.0

17、 /结果:404result.1 /结果:not foundresult.code /结果:404result.description /结果:not found可选类型所谓可选类型就是一个变量或常量可能有值也可能没有值则设置为可选类型。在ObjC中如果一个对象类型没有赋值,则默认为nil,同时nil类型也只能作为对象类型的默认值,对于类似于Int等基本类型则对应0这样的默认值。由于Swift是强类型语言,如果在声明变量或常量时没有进行赋值,Swift并不会默认设置初值(这一点和其他高级语言不太一样,例如C#虽然也有可选类型,但是要求并没有那么严格)。/* * 可选类型基础 */var x:F

18、loat? /使用?声明成一个可选类型,如果不赋值默认为nilx=172.0 var y:Float=60.0 /var z=x+y /注意此句报错,因为Int和Int?根本就是两种不同的类型,在Swift中两种不同的类型不能运算(因为不会自动进行类型转化)var z=x!+y /使用!进行强制解包 var age=29var ageInt=age.toInt() /注意ageInt是Int可选类型而不是Int类型(因为String的toInt()方法并不能保证其一定能转化为Int类型)Swift中类似于Int和Int?并不是同一种类型,不能进行相关运算,如果要运算只能解包;可选类型其本质就是

19、此类型内部存储分为“Some”和“None”两个部分,如果有值则存储到“Some”中,没有值则为“None”(早期Playground中可以看到两个部分,如今已经取消显示Some等描述了),使用感叹号强制解包的过程就是取出“Some”部分;既然可选类型有可能有值,也可能没有值那么往往有时候就需要判断。可以使用if直接判断一个可选类型是否为nil,这样一来就可以根据情况进行强制解包(从Some部分取出值的过程);另一个选择就是在判断的同时如果有值则将值赋值给一个临时变量或常量,否则不进入此条件语句,这个过程称之为“可选绑定”。/* 可选类型判断*/var age=29var ageInt=age

20、.toInt() /注意ageInt是Int可选类型而不是Int类型(因为String的toInt()方法并不能保证其一定能转化为Int类型) if ageInt=nil println(ageInt=nil)else println(ageInt=(ageInt!) /注意这里使用感叹号!强制解析 /* * 可选类型绑定 * 如果可选类型有值则将值赋值给一个临时变量或者常量(此时此变量或者常量接受的值已经不是可选类型),如果没有值则不执行此条件 */if let newAge=ageInt /此时newAge可以定义成常量也可以定义成变量 println(newAge=(newAge) /注

21、意这里并不需要对newAge强制解包else println(ageInt=nil)通过前面的演示可以看出Swift中的可选绑定如果实际计算不得不进行强制解包,如果一个可选类型从第一次赋值之后就能保证有值那么使用时就不必进行强制解包了,这种情况下可以使用隐式可选解析类型(通过感叹号声明而不是问号)/* 隐式解析可选类型*/var age:Int!=0 /通过感叹号声明隐式解析可选类型,此后使用时虽然是可选类型但是不用强制解包age=29var newAge:Int=age /不用强制解包直接赋值给Int类型(程序会自动解包) if var tempAge=age println(tempAge

22、=(tempAge)else println(age=nil)运算符Swift中支持绝大多数C语言的运算符并改进以减少不必要的错误(例如等号赋值后不返回值),算术运算会检查溢出情况,必要时还能使用新增的溢出运算符。另外Swift中还可以对浮点数使用取余运算符,新增了区间运算符。对于基本的运算符这里不再一一介绍,简单看一下Swift中的区间运算符和溢出运算符。/* * 区间运算符,通常用于整形或者字符范围(例如a.z) */for i in 1.5 /闭区间运算符.(从1到5,包含5) println(i=(i) for i in 1.5 /半开区间运算符.c100) /* 元组匹配、值绑定、w

23、here条件匹配* 注意下面的匹配没有default,因为它包含了所有情况*/var d=(x:900,y:0)switch dcase (0,0): println(d in (0,0)case (_,0): /忽略x值匹配 println(d in y)case (0,let y):/值绑定 println(d in x,y=(y)case (-100.100,-100.100): /注意这里有可能和第一、二、三个条件重合,但是Swift允许多个case匹配同一个条件,但是只会执行第一个匹配 println(x in(0-100),y in (0-100))case let (x,y) w

24、here x=y: /where条件匹配,注意这里的写法等同于:(let x,let y) where x=y println(x=y=(x)case let (x, y): println(x=(x),y=(y) 在其他语言中通常可以使用break、continue、return(Swift中添加了fallthrough)等来终止或者跳出某个执行语句,但是对于其行为往往是具有固定性的,例如break只能终止其所在的内层循环,而return只能跳出它所在的函数。在Swift中这种控制转移功能得到了加强,那就是使用标签。利用标签你可以随意指定转移的位置,例如下面的代码演示了如何直接通过标签跳出最

25、外层循环:var a=5whileLoop:while -a0 for var i=0;iInt return num1 + num2 sum(1, 2)可以看到Swift中的函数仅仅表达形式有所区别(定义形式类似于Javascript,但是js不用书写返回值),但是本质并没有太大的区别。不过Swift中对函数参数强调两个概念就是局部参数名(又叫“形式参数”)和外部参数名,这极大的照顾到了ObjC开发者的开发体验。在上面的例子中调用sum函数并没有传递任何参数名,因为num1、num2仅仅作为局部参数名在函数内部使用,但是如果给函数指定一个外部参数名在调用时就必须指定参数名。另外前面也提到关于

26、Swift中的默认参数、可变长度的参数,包括一些高级语言中的输入输出参数,通过下面的例子大家会有一个全面的了解。/*/* 函数参数名分为局部参数名和外部参数名*/func split(string a:String,seperator b:Character)-String return split(a, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=b) /由于给split函数设置了外部参数名string和seperator,所以执行的时候必须带上外部参数名,此处可以看到一个有意义的外部参数名大大节省开发者使用成本sp

27、lit(string: hello,world,!, seperator: ,) /结果:hello, world, ! /下面通过在局部参数名前加上#来简写外部参数名(此时局部参数名和外部参数名相同)func split2(#string:String,#seperator:Character)-String return split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=seperator)split2(string: hello,world,!, seperator: ,) /上面的spli

28、t函数的最后一个参数默认设置为,注意如果使用默认参数那么此参数名将默认作为外部参数名(此时局部参数名和外部参数名相同)func split3(#string:String,seperator:Character=,)-String return split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=seperator)split3(string: hello,world,!, seperator: ,) /结果:hello, world, !split3(string: hello world !,

29、seperator: ) /结果:hello, world, ! /但是如果有默认值,又不想指定局部参数名可以使用“_”取消外部参数名func split4(string:String,_ seperator:Character=,)-String return split(string, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=seperator)split4(hello,world,!, ,) /结果:hello, world, ! /* * 可变参数,一个函数最多有一个可变参数并且作为最后一个参数 * 下面s

30、trings参数在内部是一个String,对于外部是不定个数的String参数 */func joinStr(seperator:Character=,strings:String.)-String var result:String= for var i=0;iInt num1 = num1 + num2 return num1 sum2(1, 2) /结果:3 /* * 输入输出参数 * 通过输入输出参数可以在函数内部修改函数外部的变量(注意调用时不能是常量或字面量) * 注意:下面的swap仅仅为了演示,实际使用时请用Swift的全局函数swap */func swap(inout a:

31、Int ,inout b:Int) a=a+b b=a-b a=a-b var a=1,b=2swap(&a, &b) /调用时参数加上“&”符号println(a=(a),b=(b) /结果:a=2,b=1 和很多语言一样,Swift中的函数本身也可以看做一种类型,既可以作为参数又可以作为返回值。/* * 函数类型 */var sum3=sum /自动推断sum3的类型:(Int,Int)-Int,注意不同的函数类型之间不能直接赋值sum3(1,2) /结果:3 /函数作为返回值func fn()-(Int,Int)-Int /下面的函数是一个嵌套函数,作用于是在fn函数内部 func mi

32、nus(a:Int,b:Int)-Int return a-b return minus;var minus=fn() /函数作为参数func caculate(num1:Int,num2:Int,fn:(Int,Int)-Int)-Int return fn(num1,num2) caculate(1, 2, sum) /结果:3caculate(1,2, minus) /结果:-1闭包Swift中的闭包其实就是一个函数代码块,它和ObjC中的Block及C#、Java中的lambda是类似的。闭包的特点就是可以捕获和存储上下文中的常量或者变量的引用,即使这些常量或者变量在原作用域已经被销毁

33、了在代码块中仍然可以使用。事实上前面的全局函数和嵌套函数也是一种闭包,对于全局函数它不会捕获任何常量或者变量,而对于嵌套函数则可以捕获其所在函数的常量或者变量。通常我们说的闭包更多的指的是闭包表达式,也就是没有函数名称的代码块,因此也称为匿名闭包。在Swift中闭包表达式的定义形式如下: ( parameters ) - returnType in statements下面通过一个例子看一下如何通过闭包表达式来简化一个函数类型的参数,在下面的例子中闭包的形式也是一而再再而三的被简化,充分说明了Swift语法的简洁性:func sum(num1:Int,num2:Int)-Int return

34、num1 + num2 func minus(num1:Int,num2:Int)-Int return num1 - num2 func caculate(num1:Int,num2:Int,fn:(Int,Int)-Int)-Int return fn(num1,num2) var (a,b)=(1,2) caculate(a, b, sum) /结果:3caculate(a, b, minus) /结果:-1 /利用闭包表达式简化闭包函数caculate(a, b, (num1:Int,num2:Int)-Int in return num1 - num2) /结果:-1 /简化形式,根

35、据上下文推断类型并且对于单表达式闭包(只有一个语句)可以隐藏return关键字caculate(a, b, num1,num2 in num1 - num2) /结果:-1 /再次简化,使用参数名缩写,使用$0.$n代表第n个参数,并且此in关键字也省略了caculate(a, b, $0 - $1) /结果:-1考虑到闭包表达式的可读取性,Swift中如果一个函数的最后一个参数是一个函数类型的参数(或者说是闭包表达式),则可以将此参数写在函数括号之后,这种闭包称之为“尾随闭包”。func sum(num1:Int,num2:Int)-Int return num1 + num2 func m

36、inus(num1:Int,num2:Int)-Int return num1-num2 func caculate(num1:Int,num2:Int,fn:(Int,Int)-Int)-Int return fn(num1,num2) var (a,b)=(1,2) /尾随闭包,最后一个参数是闭包表达式时可以卸载括号之后,同时注意如果这个函数只有一个闭包表达式参数时可以连通括号一块省略/请注意和函数定义进行区分caculate(a, b) $0 - $1 /结果:-1前面说过闭包之所以称之为“闭包”就是因为其可以捕获一定作用域内的常量或者变量进而闭合并包裹着。func add()-()-I

37、nt var total=0 var step=1 func fn()-Int total+=step return total return fn /fn捕获了total和step,尽管下面的add()执行完后total和step被释放,但是由于fn捕获了二者的副本,所以fn会随着两个变量的副本一起被存储var a=add()a() /结果:1a() /结果:2,说明a中保存了total的副本(否则结果会是1) var b=add()b() /结果:1 ,说明a和b单独保存了total的副本(否则结果会是3) var c=bc() /结果:2,说明闭包是引用类型,换句话说函数是引用类型(否则

38、结果会是1)Swift会自动决定捕获变量或者常量副本的拷贝类型(值拷贝或者引用拷贝)而不需要开发者关心,另外被捕获的变量或者常量的内存管理同样是由Swift来管理,例如当上面的函数a不再使用了那么fn捕获的两个变量也就释放了。类作为一门面向对象语言,类当然是Swift中的一等类型。首先通过下面的例子让大家对Swift的class有一个简单的印象,在下面的例子中可以看到Swift中的属性、方法(包括构造方法和析构方法):/Swift中一个类可以不继承于任何其他基类,那么此类本身就是一个基类class Person /定义属性 var name:String var height=0.0 /构造器

39、方法,注意如果不编写构造方法默认会自动创建一个无参构造方法 init(name:String) =name /定义方法 func showMessage() println(name=(name),height=(height) /析构方法,在对象被释放时调用,类似于ObjC的dealloc,注意此函数没有括号,没有参数,无法直接调用 deinit println(deinit.) var p=Person(name: Kenhin)p.height=172.0p.showMessage() /结果:name=Kenhin,height=172.0 /类是引用类型var p2

40、 = = Kaoruprintln() /结果:Kaoruif p = p2 /“=”表示等价于,这里不能使用等于“=”(等于用于比较值相等,p和p2是不同的值,只是指向的对象相同) println(p=p2) /p等价于p2,二者指向同一个对象 从上面的例子不难看出:Swift中的类不必须继承一个基类(但是ObjC通常必须继承于NSObject),如果一个类没有继承于任何其他类则这个类也称为“基类”;Swift中的属性定义形式类似于其他语句中的成员变量(或称之为“实例变量”),尽管它有着成员变量没有的特性;Swift中如果开发者没有自己编写构造方法那么默认会提供

41、一个无参数构造方法(否则不会自动生成构造方法);Swift中的析构方法没有括号和参数,并且不支持自行调用;属性Swift中的属性分为两种:存储属性(用于类、结构体)和计算属性(用于类、结构体、枚举),并且在Swift中并不强调成员变量的概念。 无论从概念上还是定义方式上来看存储属性更像其他语言中的成员变量,但是不同的是可以控制读写操作、通过属性监视器来属性的变化以及快速实现懒加载功能。 class Account var balance:Double=0.0 class Person /firstName、lastName、age是存储属性 var firstName:String var l

42、astName:String let age:Int /fullName是一个计算属性,并且由于只定义了get方法,所以是一个只读属性 var fullName:String get return firstName + . + lastName set let array=split(newValue, maxSplit: Int.max, allowEmptySlices: false, isSeparator: $0=.) if array.count = 2 firstName=array0 lastName=array1 /set方法中的newValue表示即将赋的新值,可以自己设置

43、set中的newValue变量,如下:/ set(myValue)/ /如果fullName只有get则是一个只读属性,只读属性可以简写如下:/ var fullName:String/ return firstName + . + lastName/ /属性的懒加载,第一次访问才会计算初始值,在Swift中懒加载的属性不一定就是对象类型,也可以是基本类型 lazy var account = Account() /构造器方法,注意如果不编写构造方法默认会自动创建一个无参构造方法 init(firstName:String,lastName:String,age:Int) self.first

44、Name=firstName self.lastName=lastName self.age=age /定义方法 func showMessage() println(name=(self.fullName) var p=Person(firstName: Kenshin, lastName: Cui,age:29)p.fullName=Kaoru.Sunp.account.balance=10p.showMessage() 需要提醒大家的是:计算属性并不直接存储一个值,而是提供getter来获取一个值,或者利用setter来间接设置其他属性; lazy属性必须有初始值,必须是变量不能是常量(

45、因为常量在构造完成之前就已经确定了值);在构造方法之前存储属性必须有值,无论是变量属性(var修饰)还是常量属性(let修饰)这个值既可以在属性创建时指定也可以在构造方法内指定;从上面的例子中不难区分存储属性和计算属性,计算属性通常会有一个setter、getter方法,如果要监视一个计算属性的变化在setter方法中即可办到(因为在setter方法中可以newValue或者自定义参数名),但是如果是存储属性就无法通过监视属性的变化过程了,因为在存储属性中是无法定义setter方法的。不过Swift为我们提供了另外两个方法来监视属性的变化那就是willSet和didSet,通常称之为“属性监视器”或“属性观察器”。class Account /注意设置默认值0.0时监视器不会被调用 var balance:Double=0.0 willSet self.balance=2.0 /注意newValue可以使用自定义值,并且在属性监视器内部调用属性不会引起监视器循环调用,注意此时修改balance的值没有用 println(Account.balance

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论