专题一——Swift2.2语言预览

一、引言

本系列专题是我通过阅读Swift2.2语言开发文档,翻译总结加上自己的理解整理而成。其中大部分结构和内容都来自开发文档,有疏漏和错误之处,还望更多朋友指出,共同交流进步,我的QQ:316045346。

二、从HelloWorld开始

在学习很多编程语言时,都是从HelloWorld入门,下面代码就是一个完整的HelloWorld程序:

print("Hello,World!")

分析上面代码,可以发现Swift语言的3个十分明显的特点:

1.开发者不需要引入输入输出相关的函数库。

2.在编写代码时,不需要在语句的结尾处添加分号。

3.全局的代码就是程序的入口,不需要类似C系语言的main()方法来作为程序入口。

三、常量与变量

常量和变量是编程语言中最基础的两类数据类型,常量可以理解为为某个值起一个特定的名字,常量通常提供给开发者用于某些只赋值一次但却在程序中多处使用的量值。变量也可以进行多次修改。分别使用let和var创建常量和变量。例如:

letletValue=4
varvarValue=8
varValue=16

开发者在进行常量和变量的创建时,并不需要制定类型,编译器与根据第一次赋值的类型来推断出常量或者变量的类型,然而这并不是说Swift语言不严格要求变量或常量的类型,一旦编译器推断了值的类型,之后开发者若要修改变量,则必须严格遵守既定的变量类型,否则编译器会报错。

如果开发者第一次对变量或常量进行的赋值不能够使编译器正确的推断出常量或变量的类型,开发者也可以通过冒号后跟类型的方式来强制定义变量或常量的类型,如下:

varvarValue:Float=8
varValue=16.0

在Swift语言中,不存在隐式转换的概念,这也是Swift语言更加安全的特性之一,这样的设计可以保证变量在任何时候类型都被明确的指定。在进行类型转换时,可以通过类实例化的方式进行,示例如下:

//Float值转成Int
letValue+Int(varValue)
//Int转为Float
Float(letValue)+varValue

对于在字符串中使用其他类型的变量,Swift语言提供了一种更加便捷的写法,使用\()的方式来转换,小括号内为变量的名称,例如:

varstrValue="Hello"
//Hello16.0
strValue+"\(varValue)"

四、数组与字典

数组与字典是最常用的两种数据集合,在Swift语言中,使用[]来创建数组或字典,示例如下:

vararray=[1,2,3]
vardic=[1:"one",2:"two",3:"three"]

同Int,Float类型的数据一样,数组和字典在第一次赋值时,也会根据赋值的类型来推断出变量类型,开发者同样也可以强制指定,如下:

vararray:[Int]=[1,3]
vardic:[Int:String]=[1:"one",3:"three"]

Swift允许创建或者重新赋值为空的数据或者字典,但是这有一个前提条件,被赋值为空的数据或字典必须是类型确定的,示例如下:

//这样写会报错
//varerrorArray=[]
//创建空的数据集合
//方式一
vararray:[Int]=[]
vardic:[Int:String]=[:]
//方式二
vararray2=[Int]()
vardic2=[Int:String]()
//方式三
vararray3=[1]
vardic3=[1:"1"]
array3=[]
dic3=[:]

五、optional类型的值

在理解optional类型的值之前,我们可以先来看一段C代码:

inta=1;
if(a){

}else{

}

上面这段代码对于C语言来说完全没有问题,当a为非0值时,就代表条件为真,在Swift语言中则不同,if选择语句中的条件必须为Bool类型的值,因此,对于某些可以为空的值,Swift中提供了optional类型,这种类型相当于对其他实际类型进行了包装,如果有值,则他拆包后为相应类型的值,如果没有值,则为空值nil。示例如下:

varoptionalString:String?="Hello"
ifoptionalString==nil{

}

在Swift中,当if与let共同使用时,将会构成一种更加奇特的语法方式,这种方式对于处理optional类型的值十分方便,示例如下:

/*
iflet后面赋值为optional类型的值有这样的效果
如果optional的值不为nil则会走if条件为真的语句块并且将optional变量的值赋值给let常量可以在if为真的语句块中使用
如果optional的值为nil则会走else语句块并且name常量被释放不能再else块中使用
*/
ifletname=optionalName{
greeting="Hello,\(name)"
}else{
print(greeting)
}

除了if let语法外,还有一种方式可以用来处理optional类型的值,示例如下:

vargreeting="Hello!"
greeting="Hello"+(optionalString??"")

??运算符用来为optional类型的值设置一个默认值,如果optional值为nil,则会使用后面设置的默认值来代替。

Swift语言的switch语句相比于C系的语言要强大的多,其不只可以用于判断整型,其可以处理任意类型的数据,同样,它也不只限于比较是否相等的运算,其可以支持各种负责运算,示例如下:

letvegetable="redpepper"
switchvegetable{
case"celery":
print("Addsomeraisinsandmakeantsonalog.")
case"cucumber","watercress":
print("Thatwouldmakeagoodteasandwich.")
caseletxwherex.hasSuffix("pepper"):
print("Isitaspicy\(x)?")
default:
print("Everythingtastesgoodinsoup.")
}

如果匹配上了一个case,程序会结束switch选择,各个case之间是互斥的。

六、循环语句

Swift2.2中,弃用了for i;param;param{}格式的循环语句,提供给开发者使用的循环语句主要有3种。

1.for in语句

for in语句多用于快速遍历字典,示例如下:

letinterestingNumbers=[
"Prime":[2,3,5,7,11,13],"Fibonacci":[1,1,8],"Square":[1,4,9,16,25],]
varlargest=0
for(kind,numbers)ininterestingNumbers{
fornumberinnumbers{
//找出最大值
ifnumber>largest{
largest=number
}
}
}
print(largest)

在for in循环中可以使用一个索引来指定循环次数,通过这种方式可以实现有序的遍历操作,示例如下:

foriin0..<10{
print(i)
}

2.while语句

while语句用于条件循环,直到不再满足某个条件为止,示例如下:

varn=2
whilen<100{
n=n*2
}
print(n)

3.repeat {}while语句

repeat{}while语句与C语言中的do{}while作用相同,保证至少循环一次。示例如下:

varm=2
repeat{
m=m*2
}whilem<100
print(m)

七、函数与闭包

Swift中的函数使用关键字func来标识,格式如下:

func name(param1,param2...)->returnValue{}

示例代码如下:

funcadd(param1:Int,param2:Int)->Int{
returnparam1+param2
}
//下面表达式将返回8
add(5,param2:3)

我比较了Swift语言与Objective-C、Java语言的函数特点:

Objective-C实际上并没有函数重载的概念,不同参数的函数实际上拥有不同的函数名,Objective-C的风格将参数名嵌套进函数名中,这样有一个好处,开发者可以通过函数名明确的知道此函数的用途以及每个参数的意义,当然也有其局限性,Objective-C的函数大多十分冗长,不够简洁。

Java不同参的函数采用重载的方式,这样的效果是,相同的函数名,参入不同的参数则会执行不同的操作,是不同的两个方法,这样的有点是使代码十分简洁,然而对开发者来说并不友好,开发者在开发时不能便捷的看出每个参数的意义和用法。

个人见解,Swift对函数的设计综合了上面两种语言的有事,参数列表与函数名分离,简化了函数,同时,参数列表中保留了每个参数的名称,使开发者在调用函数时更加直观。

在Objective-C中,如果需要某个函数返回一组值,开发者通常会需要使用字典或者数组,这样做有一个问题,在调用此函数时,返回值的意义十分模糊,开发者需要明确的知道其中数据的顺序与意义。Swift中可以采用返回元组的方式来处理一组返回值,示例如下:

//返回一组数据的函数
funccalculateStatistics(scores:[Int])->(min:Int,max:Int,sum:Int){
varmin=scores[0]
varmax=scores[0]
varsum=0

forscoreinscores{
ifscore>max{
max=score
}elseifscore<min{
min=score
}
sum+=score
}

return(min,max,sum)
}
//元组数据
letstatistics=calculateStatistics([5,100,9])
//通过名称取元组中的最大值
print(statistics.max)
//通过角标取元组中的最小值
print(statistics.0)

对于可变参数个数的函数,在Objective-C中,开发者大多会采用va_list指针的方式实现,示例如下:

-(void)myLog:(Nsstring*)str,...{//省略参数的写法
va_listlist;//创建一个列表指针对象
va_start(list,str);//进行列表的初始化,str为省略前的第一个参数,及...之前的那个参数
Nsstring*temStr=str;
while(temStr!=nil){//如果不是nil,则继续取值
NSLog(@"%@",temStr);
temStr=va_arg(list,Nsstring*);//返回取到的值,并且让指针指向下一个参数的地址
}
va_end(list);//关闭列表指针
}

在Swift语言中,实现这样的函数要简单的多,通过...来进行参数的省略,并且将这些省略的函数包装为数组传入函数内部,示例如下:

funcsumOf(numbers:Int...)->Int{
varsum=0
//多参被包装为数组
fornumberinnumbers{
sum+=number
}
returnsum
}
sumOf()
sumOf(42,597,12)

与java类似,Swift中的函数也支持嵌套操作,嵌套内部的函数可以使用外部的变量,示例如下:

funcreturnFifteen()->Int{
vary=10
//嵌套函数
funcadd(){
y+=5
}
//调用
add()
returny
}
returnFifteen()

由于函数也是一种特殊的数据类型,函数也可以作为返回值,示例如下:

funcmakeIncrementer()->((Int)->Int){
funcaddOne(number:Int)->Int{
return1+number
}
returnaddOne
}
varincrement:((Int)->Int)=makeIncrementer()
increment(7)

一个函数也可以作为另一个函数的参数来使用,示例如下:

//参数中有函数
funcfunc1(param1:Int,param2:(count:Int)->Void){
param2(count:param1+1)
}
functmpFunc(count:Int)->Void{
print(count)
}
//将函数作为参数传入
func1(3,param2:tmpFunc)

与Objective-C中的block对应,Swift中有闭包的概念来创建一个代码块,可以理解为闭包为没有名字的函数,使用{()in }格式来创建闭包,示例代码如下:

varf:(count:Int)->Void={(Count)inprint(132)}
f(count:0)

通过这种写法,开发者在将函数作为参数传递时,无需再创建中间函数,示例如下:

//参数中有函数
funcfunc1(param1:Int,param2:(count:Int)->Void,param3:(count:Int)->Void){
param2(count:param1+1)
}
func1(3,param2:{(count)in
print(count)
},param3:{(count)in
print(count)
})

还有一种更加简单的闭包书写方法,如果闭包类型是确定的,全完可以省略小括号中的参数名称与闭包格式in,使用角标来获取参数,示例如下:

//优化前
varf:(a:Int,b:Int)->Bool={(a,b)inreturna>b}
f(a:3,b:4)
//优化后
varf:(a:Int,b:Int)->Bool={$0>$1}
f(a:3,b:4)

八、类与属性

Swift中使用class关键字来定义类,类内部可以声明与定义一些属性与方法,类的实例对象可以通过点语法来调用类的属性和方法,示例如下:

classMyClass{
varcount=100
letname="珲少"
funcrun(){
print("run100miter")
}
}
varobj=MyClass()
letcount=obj.count
letname=obj.name
obj.run()

类名加括号用于创建类的实例对象,可以通过重写init方法来重写类的默认构造方法,如果这个类有继承的父类,则需要遵守如下3条规则:

1.必须先将子类的属性初始化完成。

2.调用父类的构造方法。

3.修改父类需要修改的属性。

在Swift中同样也有set和get方法,只是这里的set和get方法与Objective-C中的set和get方法有很大的不同,Objective-C中的get和set方法是截获了属性和存取过程,在其中加入额外的其他操作,Swift中的set和get方法原理上将属性的存取与其他逻辑操作进行了分离,抽象出了一种计算属性,示例如下:

classMyClass{
varcount:Int
//实际上并不存在privateCount属性通过pricatecount来操作count的值
varprivateCount:Int{
get{
returncount;
}
set{
count=newValue+100
}
}
letname="珲少"
funcrun(){
print("run100miter")
}
init(){
count=200
}
}

Swift采用这样的设计思路也有其一定的优化道理,我比较了一下,给大家举一个最简单的例子,在使用Objective-C进行iOS开发时,经常会遇到这样的情况,某个控件中有一个UILabel控件,开发者在不想将控件暴漏在.h文件中的情况下经常会声明一个Nsstring类型的变量,重写此变量的set方法来完成对UILabel控件的赋值,仔细想来,实际上声明的这个Nsstring变量完全是多余的,它只是为了用来做中间值得传递,Swift的set和get方法就在这里进行了优化。另外,在set方法中会自动生成一个命名为newValue的变量作为传递进来的值,开发者也可以自定义这个变量的名称,在set后加小括号即可,示例如下:

varprivateCount:Int{
get{
returncount;
}
set(myValue){
count=myValue+100
}
}

Swift中也提供了监听属性赋值过程的方法,其使用的是willSet与didSet机制,示例如下:

classMyClass{
varcount:Int{
//赋值前执行(除了第一次初始赋值)将要赋值的值以newValue传入
willSet{
print("willset\(newValue)")
}
//赋值后执行(除了第一次初始赋值)原来的值以oldValue传入
didSet{
print("didset\(oldValue)")
}
}
letname="珲少"
funcrun(){
print("run100miter")
}
init(){
count=200
}
}

九、枚举和结构体

Swift中的枚举和C与Objective-C有很大的差别,在Swift中,枚举也被作为一种数据类型来处理,其中可以添加函数方法。最基本的枚举用法如下所示:

//枚举可以多个case并列也可以写在一个case中以逗号分隔
enumMyEnum{
caSEOne
casetew
casethree
caseFir,Sec,Thr
}
varem=MyEnum.one

如果变量是类型确定的枚举,在赋值时可以省略枚举名,示例如下:

varem:MyEnum=.one

Swift中的枚举还有一个原始值的概念,要使用原始值,必须在创建枚举类型时设置原始值的类型,示例如下:

enumMyEnum:Int{
caSEOne=1
casetew
casethree
caseFir,Thr
}
varem=MyEnum.one.rawValue

如果原始值是Int类型,则默认从0开始依次递增,开发者也可以手动设置每个枚举值的原始值。同样,也支持使用原始值来创建枚举实例,如下:

varem=MyEnum(rawValue:1)

通过原始值实例的枚举对象实际上回返回一个optional类型的值,如果传入的原始值参数不能匹配到任何一个枚举case,则可以使用if let结构进行判断处理。

在枚举中封装方法示例如下:

enumMyEnum:Int{
caSEOne
casetew
casethree
caseFir,Thr
funcdes(){
switchself{
case.one:
print("one")
default:
print("else")
}
}
}
varem=MyEnum(rawValue:1)
em?.des()

Swift中的枚举也可以添加附加值,在switch语句中取到对应的枚举类型后,可以获取开发者设置的附加值进行逻辑处理,示例如下:

enumMyEnum{
//为这个类型天啊及一组附加值
caSEOne(String,Int)
casetew
casethree
caseFir,Thr
funcdes(){
switchself{
case.one:
print("one")
default:
print("else")
}
}
}
varem=MyEnum.one("第一个元素",1)
switchem{
//前面的let指定附加值为常量或者用var指定为变量,括号内为附加值参数名
caselet.one(param1,param2):
print("Oneparamis\(param1)andtwoparamis\(param2).")
default:
print("else")
}

Swift中使用struct关键字来进行结构体的创建,结构体的功能和类相似,支持属性与方法,但不同的是,结构体在传递时会被赋值,类的实例则会以引用的方式传递。

专注技术,热爱生活,交流技术,也做朋友。

——珲少 QQ群:203317592

Swift解读专题一——Swift2.2语言预览的更多相关文章

  1. ios – 声明NSDictionary并在Swift中添加键值对?

    我一直在尝试使用类类型键和值来声明一个NSDictionary,如下所示:这里,“Category”和“SubCategory”是全局类.我知道我不能将类类型用于关键字段.但是,无论如何,我应该做到这一点.有没有办法做到这一点?如何声明专门的NSDictionary或类似的东西来做到这一点?

  2. ios – 异常断点处于活动状态时,应用程序在启动时崩溃

    我刚开始继续开发一款适用于商店的传统iPad应用程序.我注意到项目中的异常断点未启用.当我启用它时,应用程序在启动时崩溃,但在输出窗口中没有给出任何信息,而在线程视图中只有相当无用的信息(见下文)我试着解决它..>将Autolayout设置为关闭.>通过编辑和重新保存故事板文件..但到目前为止没有运气.我的猜测是,故事板中的某些内容被破坏了,因为AppDelegates“确实完成了启动……”

  3. ios – Swift相当于`[NSDictionary initWithObjects:forKeys:]`

    Swift的原生字典是否与[NSDictionaryinitWithObjects:forKeys:]相当?假设我有两个带键和值的数组,并希望将它们放在字典中.在Objective-C中,我这样做:当然我可以通过两个数组迭代一个计数器,使用vardict:[String:Int]并逐步添加东西.但这似乎不是一个好的解决方案.使用zip和enumerate可能是同时迭代两者的更好方法.然而,这种方法

  4. ios – 如何使用Objective C类中的多个参数调用Swift函数?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. ios – Swift 4添加手势:覆盖vs @objc

    我想在我的视图中添加一个手势,如下所示:但是,在Swift4中,我的编译器给出了以下错误:建议添加@objc以将此实例方法公开给Objective-C.实现此目的的另一个选项将覆盖touchesBegan()函数并使用它来处理点击.我试图以“Swift”的方式做到这一点,而不必带入Obj-C.有没有纯粹的Swift方式来添加这个轻击手势而不使用@objc?

  6. ios – 将视频分享到Facebook

    我正在编写一个简单的测试应用程序,用于将视频从iOS上传到Facebook.由于FacebookSDK的所有文档都在Objective-C中,因此我发现很难在线找到有关如何使用Swift执行此操作的示例/教程.到目前为止我有这个在我的UI上放置一个共享按钮,但它看起来已禁用,从我读到的这是因为没有内容设置,但我看不出这是怎么可能的.我的getVideoURL()函数返回一个NSURL,它肯定包含视

  7. ios – Objective-C中“and”关键字的含义是什么?

    我在Xcode中输入了一条评论,但忘了领先//.我注意到了这一点并且突出显示为关键字.我做了一些谷歌搜索,但我似乎无法弄清楚它做了什么.这是什么意思?解决方法它是&&的同义词.见iso646.h.

  8. ios – 以编程方式在Swift中添加联系人

    我想在Swift中以编程方式添加联系人.我发现了一些Objective-C示例,但我没有让它们工作,甚至在Objective-C中也没有.我不希望这涉及到AddressBookUI,因为我想从我自己的UI中获取值.解决方法这是在Swift中添加联系人的快速方法.我在我的iPhone5iOS7.1上验证了它,因为我发现模拟器并不总是与我的手机对AB的东西相同.您可以添加一个按钮并指向此方法:顺便说一下–它假设你已经分配了一个地址簿var,你可以通过覆盖viewDidAppear来打开视图.它也会执行安全提示

  9. ios – 如何从变量访问属性或方法?

    是否可以使用变量作为Swift中方法或属性的名称来访问方法或属性?在PHP中,您可以使用$object->{$variable}.例如编辑:这是我正在使用的实际代码:解决方法你可以做到,但不能使用“纯粹的”Swift.Swift的重点是防止这种危险的动态属性访问.你必须使用Cocoa的Key-ValueCoding功能:非常方便,它完全穿过你要穿过的字符串到属性名称的桥,但要注意:这里是龙.

  10. ios – Objective-C中的Google用户serverAuthCode nil

    我正在尝试将GoogleSignIn框架集成到iOS应用程序中,并对服务器上的用户进行身份验证.我设法登录用户,但在–(void)signIn:(GIDSignIn*)signIndidSignInForUser:(GIDGoogleUser*)用户withError:(NSError*)错误委托方法,user.serverAuthCode为nil,我需要通过此服务器身份验证代码,嗯,验证服务器上

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部