iOS编程——Swift语法之 "?" 和 "!"
2015-08-17 15:03
507 查看
首先先让我们来了解下Swift中“nil”的含义:在OC中nil指的是一个空对象,它指向一个不存在的对象的指针;而在Swift中它表示的是一个不确定的值,含义是“值缺失”,"nil"只可以用于optionals类型的,比如下面的代码(结果在注释里):
首先来看一个String方法的API:它对String类型扩展了一个将String转换为Int?的方法:
分析完了"?",让我们再来看一下"!","!"之前说过是保证肯定有值,那来看看用法:
为什么要这么做呢?让我们假设一个情况:有一个变量在开始可能是nil设置为了"?“类型,可在第一次赋值之后我们可以肯定它以后都会有值,这样每次使用都要重复的进行判断和解析,效率会非常低。所以就可以声明为”!“类型,以后就不需要重复判断和解析了,效率会提高很多。也就是下面的代码:
但是需要注意的是:必须保证有值才可以用"!",否则就会报错,比如下面的代码就是错误的:
总结一下: "?"和”!“是一种安全类型:可选类型,不同的是"?"使用时需要进行解包处理,解包失败就是“nil”,适用于可能没有值的情形。而"!"使用时不需要解包(在第一次赋值时编译器已经自动解包),但是必须保证有值,否则会报错。两者都可以通过if语句强制解析和if let可选绑定来进行使用。
var oneString = "111" //Error: Cannot assign a value of type 'nil' to a value of type 'String' oneString = nil //Error: Binary operator '==' cannot be applied to operands of type 'String' and 'nil' if oneString == nil { println(oneString) }可以看到对oneString赋值nil和对nil的比较都会报错,那应该怎么用呢,这就涉及到了optionals(可选)类型:
首先来看一个String方法的API:它对String类型扩展了一个将String转换为Int?的方法:
extension String { func toInt() -> Int? }注意:Int后面跟了一个"?",Int?表示:返回值是一个可选类型的,如果有值就是Int型的,如果没有值,就是“nil”。让我对这个函数测试一下:
let oneString = "111" let possibleNum = oneString.toInt() //possibleNum: Optional(111) println("possibleNum: \(possibleNum)") //possibleNum can use > if possibleNum > 1 { println("possibleNum can use >") } //Error: Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'? let addNum = possibleNum + 10根据打印很明显看出来:Int?打印出来以后是Optional类型的,它可以用来做比较运算;但是不可以做+运算,报错:Int?没有解包,需要用"?"或者"!"来解包。 解包是神马意思呢,其实很简单就是把optional类型转换为Int类型的:只不过“?”表示转换可能会失败,如果失败就是“nil”;而“!”则是表明一定有值,一定可以转换成功,如果没有对应值使用"!"会导致报错。让我们来一步步测试下:
let oneString = "111" let possibleNum = oneString.toInt() //unwrapped value: 111 if possibleNum != nil { println("unwrapped value: \(possibleNum!)") }
分析:possibleNum是Int?类型的,上面说过“?”类型的如果值不存在就是“nil”,那反过来:如果不为“nil”,那肯定有值可以解包,所以possibleNum!会解包成功得到Int类型的值:111,这种方法叫做if语句强制解析;
let oneString = "111" let possibleNum = oneString.toInt() //oneNum: 111 if let oneNum = possibleNum { println("oneNum: \(oneNum)") }分析:通过使用if let 来进行赋值得到解包后的值,这种方法叫做可选绑定。只有possibleNum有值才可以解包成功,if语句才会成立。如果possibleNum没值是什么样呢,试一下:
let oneString = "abc" let possibleNum = oneString.toInt() if let oneNum = possibleNum { println("oneNum: \(oneNum)") } //possibleNum: nil println("possibleNum: \(possibleNum)")分析:possibleNum是Int?类型的,因为转换失败所以是”nil“,if语句不会成立。打印之后是nil。
分析完了"?",让我们再来看一下"!","!"之前说过是保证肯定有值,那来看看用法:
let oneString = "111" let possibleNum: Int! = oneString.toInt() //possibleNum: 111 println("possibleNum: \(possibleNum)") //possibleNum can use > if possibleNum > 1 { println("possibleNum can use >") } //addNum: 121 let addNum = possibleNum + 10 println("addNum: \(addNum)")通过代码和日志可以看到,Int!类型的变量possibleNum不同于 "Int?",它可以不经过处理直接用来做+运算,这种带"!"的类型叫做隐式解析可选类型。
为什么要这么做呢?让我们假设一个情况:有一个变量在开始可能是nil设置为了"?“类型,可在第一次赋值之后我们可以肯定它以后都会有值,这样每次使用都要重复的进行判断和解析,效率会非常低。所以就可以声明为”!“类型,以后就不需要重复判断和解析了,效率会提高很多。也就是下面的代码:
let optionalString: String? = "one string" let convertedString1 = optionalString!//需要用"!"进行解包获取值 let implicitlyUnwrappedOptionalString: String? = "one string" let convertedString2 = implicitlyUnwrappedOptionalString//不需要用"!"
但是需要注意的是:必须保证有值才可以用"!",否则就会报错,比如下面的代码就是错误的:
let oneString = "abc" let possibleNum: Int! = oneString.toInt() //Error: unexpectedly found nil while unwrapping an Optional value let add = possibleNum + 10
总结一下: "?"和”!“是一种安全类型:可选类型,不同的是"?"使用时需要进行解包处理,解包失败就是“nil”,适用于可能没有值的情形。而"!"使用时不需要解包(在第一次赋值时编译器已经自动解包),但是必须保证有值,否则会报错。两者都可以通过if语句强制解析和if let可选绑定来进行使用。
相关文章推荐
- Swift版 ScrollView和UITouch事件冲突
- 慕课Swift-进入OOP时代笔记
- 关东升的《从零开始学Swift》即将出版
- swift学习笔记之数据类型
- 关东升的《Swift2.0》(暂定名)即将出版
- Swift:面向对象(继承与构造方法)
- swift 中的 Selector 类型
- swift-学习之路,字典、数组、循环-控制流
- Swift环境下实现UILabel居上 居中 居下对齐
- Swift和OC混编
- [Swift]初学Swift语言个人笔记
- 深度解析swift中的String
- Swift 可选值(Optional Values)介绍
- Swift字典的使用
- 关于flex匿名函数和swift闭包
- 玩儿转Swift——学习笔记(持续更新)
- swift入门-实现简单的登录界面
- Watch OS 2 Complication开发教程(三)基本数据(持续连载中)
- Swift:面向对象(属性)
- 窥探Swift之新添数据类型元组与可选值