swift 初学

Swift是强类型语言,但也允许开发者通过is、as?和as!这三种操作来对类型进行判断和强制转换。其中is用作类型判断,而as?和as!则分别是类型转换的可选形式和强制形式。在这里强调一下,swift中比较常用的向下转换(downcast)是没有as操作符的。

is操作符

is操作用来判断某一个对象是否是某一个特定的类,它会返回一个bool类型的值。is操作的逻辑很简单,某一个类的对象肯定是自己这个类,也一定是自己的超类,但超类的对象不是子类。如果两个类没有继承关系,那is操作一定返回false.

as!操作符

as!操作符是类型转换的强制格式,优点在于代码简单,如果可以转换,则会返回转换了格式的对象,如果无法转换就会抛出运行时错误。因此除非百分之百确定可以转换,否则不应该使用as!来进行强制类型转换。

as?和as!操作符的转换规则完全一样,但是as?会返回一个被转换类型的可选类型,需要我们解封。因此写法会略有不同,

Swift—使用try?和try!区别
**1.使用try? **
try?会将错误转换为可选值,当调用try?+函数或方法语句时候,如果函数或方法抛出错误,程序不会发崩溃,而返回一个nil,如果没有抛出错误则返回可选值。

2.使用****try!
使用try!可以打破错误传播链条。错误抛出后传播给它的调用者,这样就形成了一个传播链条,但有的时候确实不想让错误传播下去,可以使用try!语句。

AnyObject是一定不能为空,包括初始化的时候
AnyObject!表示类型是一个optional类型,初始化的时候可以为空,但是加!表示知道用它时它是一定不为空的

Swift 语言中 类型后面的 ?和 ! 有什么作用?
! 并不代表一定有值. 在定义一个属性的时候使用 ! , 那么你在取值或赋值的时候就不需要手动强制解包了.但是如果定义的时候写?, 在赋值/取值的时候就需要自己解包

Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,
也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化
。如果在使用变量之前不进行初始化就会报错:

var stringValue : String   
//error: variable 'stringValue' used before being initialized  
//let hashValue = stringValue.hashValue  
//                            ^  
let hashValue = stringValue.hashValue 

出错的原因就是在使用stringValue这个变量之前,没有初始化这个变量,也就是这个变量根本就没有得到内存,
这时就会出错。
那么我们可以使用optional类型,后面跟一个?就是了。

// 这就是optional, strValue自动得到默认值:nil   
// 这个nil跟Objective-C中的nil不同,不是指针,而是表示值不存在。  
var strValue: String?   
  
// 判断optional是否有值  
if strValue {  
 // do what you need to do here  
}  

文档中有提到说,在使用Optional值的时候需要在具体的操作,比如调用方法、属性、下标索引等前面需要加上一个?,如果是nil值(不存在值),也就是Optional.None,会跳过后面的操作不执行,如果有值,就是Optional.Some可能就会拆包(unwrap),然后对拆包后的值执行后面的操作,来保证执行这个操作的安全性,比如Optional binding:

// optional binding  
// 如果strValue == nil, 那么结果就是nil,不会调用String的hasValue  
// 如果strValue != nil, 就返回strValue对应的hashValue值并赋值给常量hashValue  
if let hashValue = strValue?.hashValue {  
  // do something if neccessary  
} 

在写协议(protocol)时,对于可选代理方法,也需要在调用时在函数名后跟着?,如:

// @objc 是用于处理Swift与OC之间的转换的,由于@optional是OC中的关键字,  
// 所以在protocol之前需要添加上@objc。  
@objc protocol HttpRequestDelegate {  
  // @optional 说明这个代理方法是可选方法,  
  // 那么在调用的时候,需要这样调用:delegate?.requestFinished?(self, downloadData)  
  // 其中delegate?是因为delegate也是optional的  
  @optional func requestFinished(request: HttpRequest!, downloadData: NSMutableData!)  
    
  // other funcs ...  
}  
  
var delegate: HttpRequestDelegate?  
var downloadData = NSMutableData()  
delegate.requestFinished(self, downloadData)  

当然我们也可以使用!来强制拆包,这是我们在保证有值的情况下才会这么用:

var strValue: String?  
strValue = "1234"  
  
let integer = strValue!.toInt()  
// 更安全的写法是  
if strValue {  
  let integer = strValue!.toInt()  
}

隐式强拆包类型:使用!来声明变量,会成为隐式强拆包可选类型,这表示这个类型永远不会出现nil的情况,但一旦出来,
在调用时就会崩溃。

// Implicitly Unwrapped Optionals  
// 使用这种方式声明的话,在调用时不需要使用?或!来说明。  
var myLabel: UILabel!   
  
myLabel = UILabel(frame: CGRectMake(10, 100, 300, 10))  
myLabel.text = "label" 

总结:
通常在什么情况下才会使用optional类型呢?
(1)当我们需要声明这样一个变量,变量在设计初始化函数中没有进行初始化时,就需要声明这个变量为optional类型。因为变量在使用前必须先
声明,并且在设计初始化函数中进行初始化。比如我们在viewDidLoad函数中才进行初始化的控件(类成员),就需要声明为optional且必须是var声明,
因为let声明的常量只能是在初始化函数中进行初始化。
(2)当我们不知道是否会有值的时候,这个变量可以声明为optional,比如代理,我们并没有要求必须传代理过来,那么就需要声明为optional。
(3)作为函数参数时,如果这个参数可以没有值,那么就使用optional类型,比如传代理的时候,通常就是可选的,可以设置为nil

var evalList = [Evakmodel]()   //数组
var vrstore = Storemodel()     //函数
var web view = UIWebView()  //初始化方法
var topbtn:UIImafeView!     //解包

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,523评论 19 139
  • 简介 这是一个Swift语言教程,基于最新的iOS 9,Xcode 7.3和Swift 2.2,会为你介绍Swif...
    张嘉夫阅读 8,694评论 0 50
  • 基础部分(The Basics) 当推断浮点数的类型时,Swift 总是会选择Double而不是Float。 结合...
    gamper阅读 5,211评论 0 7
  • 132.转换错误成可选值 通过转换错误成一个可选值,你可以使用 try? 来处理错误。当执行try?表达式时,如果...
    无沣阅读 5,101评论 0 3
  • 今天就是大年初一啦,新年新气象,我突然觉得该好好规划一下。日子一天天过的飞快,最近几年都没有啥进步,天天懒散的有点...
    快乐一家亲阅读 3,097评论 0 0