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
......暂时只想到这些,任何人都可以继续往下补充!
Swift :?和 !的更多相关文章
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- Swift与C#的基础语法比较
背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...
- iOS开发系列--Swift语言
概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...
- 算法与数据结构(十七) 基数排序(Swift 3.0版)
前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关.今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数字较小的情况下,基数排序算法的效率还是比 ...
- 算法与数据结构(十五) 归并排序(Swift 3.0版)
上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...
- Swift enum(枚举)使用范例
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- swift开发新项目总结
新项目用swift3.0开发,现在基本一个月,来总结一下遇到的问题及解决方案 1,在确定新项目用swift后,第一个考虑的问题是用纯swift呢?还是用swift跟OC混编 考虑到新项目 ...
- swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明
关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...
- 【swift】BlockOperation和GCD实用代码块
//BlockOperation // // ViewController.swift import UIKit class ViewController: UIViewController { @I ...
- iOS开发系列--Swift 3.0
概述 从写第一篇Swift文章的时候到现在Swift已经从1.2发展到了今天的3.0,这期间由于Swift目前还在发展阶段并不能向下兼容,因此第一篇文章中的部分代码在当前的Xcode环境中已经无法运行 ...
随机推荐
- TCP/IP详解学习笔记(14)-- TCP可靠传输的实现
1.概述 为方便描述可靠传输原理,假定数据传输只在一个方向上进行,即A发送数据,B给出确认 2.以字节为单位的滑动窗口 TCP的滑动窗口是以字节为单位的.为了便于说明,字节编号取得 ...
- gson转换带有objectId的问题
/** * * @Description: objectid 转换成string 不然就会objectid对象序列化了 * @param @param obj * @param @return * @ ...
- ajax 方法解密
1:GET访问 浏览器 认为 是等幂的就是 一个相同的URL 只有一个结果[相同是指 整个URL字符串完全匹配]所以 第二次访问的时候 如果 URL字符串没变化 浏览器是 直接拿出了第一次访问的结果 ...
- ajax success 和complete 的区别
Function) success - 当请求成功时调用的函数.这个函数会得到一个参数:从服务器返回的数据(根据“dataType”进行了格式化). Function) complete - 当请求完 ...
- CentOS 安裝 VMware Workstation / VMware Player
参考:http://www.vixual.net/blog/archives/650 序列号:1F04Z-6D111-7Z029-AV0Q4-3AEH8 注意说明:刚开始有很长的一系列协议信息,可以用 ...
- linux ubuntu装机到可实现java(eclipse,intellij IDEA,android)开发全过程
前言:linux是个很强的东西,你可以在其中体验开发的神速,有如神助,但是同时系统的不完整,错误漏洞多也是ubuntu等系统的诟病,所以大家遇到任何问题,第一时间请淡定,随后百度,google一下吧, ...
- C#关于一个程序,只可以有一种实例的方法
方法一:使用线程互斥变量. 通过定义互斥变量来判断是否已运行实例.把program.cs文件里的Main()函数改为如下代码: 说明:程序中通过语句 System.Threading.Mutex ru ...
- DataGridView点击排序完成后如何禁止自动排序
Summary: Disable sorting after clicking DataGridView columnheader,Prevent databound DataGridView fro ...
- SDUST 作业10 Problem I 液晶显示
Description 你的朋友刚买了一台新电脑,他以前用过的最强大的计算工具是一台袖珍计算器.现在,看着自己的新电脑,他有点失望,因为他更喜欢计算器上的LC显示器.所以,你决定写一个LC显示风格的程 ...
- Linux命令学习---目录
一.文件相关命令 1.文件显示 1)tail,head,more,less,cat,nl