0000_0000_0000_0100.Optional<T> 可选类型闲谈

0000 0000 0000 0100

写于2015.04.07 10:13

清明已过,是时候收收心,继续码代码了。

Optional 可选类型闲谈

在我印象中,可选类型应该分为显示可选类型和隐式可选类型。分别是这样的:

var explicitPara:Type?  //显示  初始化时假如不给赋值 默认都是nil
var implicitPara:Type!  //隐式

不知道自己记得对不对。两者都是可选类型,自然就有共性,可选类型定义为一个变量(不仅仅是class)要么有值,且值等于x,要么就不存在(nil)。

注:与oc中nil是一个指针指向不存在的对象不同,swift中,nil可不是一个指针,而是一个特定类型的空值。任何类型的可选变量都可以设为nil,通俗理解就是不仅仅是class类型可以=nil, string ,int ,char都可以不存在=nil。这样使得编程时候更为安全。

昨天我还对显示可选类型和隐式可选类型之间的差异询问了群里的朋友,以及再次翻阅了The Swift programming Language

可选类型总觉得就是把值放进一个叫做Optional的盒子中。可选类型是一个枚举,声明是这样的:

enum Optional<T>:Reflectable,NilLiteralConvertibel{
    case None
    case Some(T)

    /// 构建一个 a `nil` instance.
    init()

    /// 构建一个 a non-\ `nil` instance that stores `some`.
    init(_ some: T)

    /// If `self == nil`, returns `nil`.  Otherwise, returns `f(self!)`.
    func map<U>(f: (T) -> U) -> U?

    /// Returns a mirror that reflects `self`.
    func getMirror() -> MirrorType

    /// Create an instance initialized with `nil`.
    init(nilLiteral: ())

}

可见两种情况 None 以及 Some(T), 对于T,只不过是一个泛型,指代传入的类型(传入Int,T就是Int ;传入String,T就是String;传入类,T就是特定class)。这个还是有点意思的。

继续上面,既然把值放入了盒子中,自然取出来就是要有一个解包(unwrap)的行为,swift是用!表示该行为。方便记忆,举个例子:

var str:String? = "hello world"     //把值放入盒子中包裹起来了

/*
    输出Optional("hello world") 连带外面那层盒子也打印出来了
    其中"hello world" 存储到了 some 中
*/
println(str)                        

println(str!)                       //输出“hello world” . 解包取出值  盒子已经丢弃

解包就是这么一个形式,上面是一个显示的可选类型,当然解包方式还包括if-let可选绑定,??等。

显示可选类型和隐式可选类型两者有什么不同,使用场景又是怎样? 当时问题就这么蹦出来…

  1. 首先必须明确可选类型定义:两种情况:值存在且等于x(程序中的赋值);值不存在=nil。那么也就是说 explicit Optionalimplicit Optional 都存在值不存在情况喽。
  2. 显示可选类型总是要通过一些手段(比如if-let)来检查值是否存在,然后再解包取值()。确实这么做能够提高安全性,但是有时候过于繁琐。就比如有些情况是这样的,可选类型一旦经过初始化后,一直都是有效的。既然我们已经明确知道可选类型变量初始化之后很长一段时间,或者说始终,都是有值的。那么我们还要每次进行繁琐的解包行为呢?(ps:用if-let先可选绑定取值或者用!强制解包取值)。
  3. 因此我们使用隐式可选类型(implicity Optional),即类似(var para:Type!)来声明。这样做的好处用一个简单实例来表示:
    var str:String! = "hello world"     //初始化赋值
    
    //注意没有使用 ! 来解包了 而是偷偷帮我们解包取值了 这也就是为啥叫做隐式解包
    //打印结果就是hello world 与Optional("hello world")不同
    println(str)
    
  4. 但是需要强调的是假如变量用来存储的值是有可能没有的,最好还是使用显示可选类型,也就是带有?的。那么什么时候用隐士可选类型呢?
  5. 你会注意一些IBOutlet都是带有!的隐式可选类型。那是因为一旦Storyboard初始化完成,那么这些接口都是赋值完毕不再改动,以后用起来就不需要再去显示解包了,这里注意(不是没有了解包,而是偷偷地 自动地帮你解包),不再需要每个都判断值是否存在,也不必用!来解包取值,直接使用即可。
  6. 再举个例子加深下自身理解。就好比平常用的,控制器中总会有那么些声明:

    class ViewController:UIViewController{

    //请看这里 变量声明
    var searchResult :Result!       //这里是用 ! 还是 ?
    
    override viewDidLoad(){
    ...
    }
    ...
    

    }

    我现在这么理解,假设当然处于一个其他ControllerA中,有一个button跳转到这个ViewController,并且传递给searchResult值,你必然肯定值是存在的(ps:当然在SB中跳转 我们会在prepareForSegue中来设置)。一旦赋值好就不改变了,那么自然就是用隐式可选类型恰当。假如这个searchResult是在当前ViewController下通过http Get请求获取,自然存在没有值的情况,那么用?合适吧。

    不过希望自己能理解的是,假如隐式可选类型等于nil了,那么你在使用时不做判断处理直接拿来使用必定要抛出一个错误。 所以你在使用隐式可选类型之前一定要考虑,是否一旦赋值必定不会再存在值为空的情况。假如还是有可能,建议用?

目前就理解到这个程度。若以后还有新的理解 或者上述表达哪里不准确,我将进一步修改。

时间: 2024-07-30 09:50:43

0000_0000_0000_0100.Optional<T> 可选类型闲谈的相关文章

Swift中的Optional类型 (可选类型)与强制解包 ? !

我们在swift的开发中会经常遇见?和! ,理解这两个符号深层次的内容对我们的开发是相当有利的: 目前网上对swift3.0的教程还相当的少,如果去搜索会发现早期的说法,在定义变量的时候,swift是不会给变量赋值初始值的,所以当你声明一个字符串变量的时候,var string:String   就会被系统报错,但是目前的swift版本却不报错了. 但是你要给一个字符串赋值未nil的时候,var string:String = nil 就一定是错误的   因为nil并不是一个字符串类型,而实际上

Why Coding Like this -------Optional揭秘 自己写一个可选类型类

title: "Why coding like This -- Optional 揭秘" date: 2015-08-12 00:21:16 categories: "why coding like this" tags: [swift进阶] Optional 揭秘 Topic 1: 请简单写出可选类型的声明方式,以及几种解包形式. Example: /// 几种声明方式 var optionalValue : Optional<Int> //完整声明

Swift:可选类型(Optional)

在我们使用objective-c表示字符串信息的时候,可以用下面方法书写. NSString *str = @"秋恨雪"; str = nil; 因为objective-c是弱类型语言,所以这里的str既可以是具体的字符串也可以是nil.但到了Swift中就不可以了,因为Swift是类型安全的语言,一个String类型的变量不可能既能是具体的字符串,又可以为nil(更严格的说String类型的内容只能是字符串).所以,在Swift中有了可选类型的概念.(其实这一概念也是"借鉴

Swift学习-----可选类型

可选类型 * 可选类型表示变量可以有值, 也可以没有值 * C 和 Objective-C 中并没有可选类型这个概念 * Swift中只有可选类型才可以赋值为nil * 如果你声明一个可选常量或者变量但是没有赋值,它们会自动被设置为nil * 格式: Optional<类型> 或 在类型后面加上?号 可选类型的取值是一个枚举 * None 没有值 * Some 有值 * 由于可选类型在Swift中随处可见, 所以系统做了一个语法糖, 在类型后面加上? 注意: * nil不能用于非可选的常量和变

Swift 可选类型(补充)

// 可选类型 // 可选类型: 这个值要么存在等于X,要么这个值根本就不存在 var serverResponseCode : Int? = 404 // ?的意思是这个只存在为404,要么这个值就不存在为nil let possbileNumber = "123" // let coverNumber: Int? = possbileNumber.toInt() var responseCode: Int? = 404 // 要么存在为404 responseCode = nil 

Swift的结构体,枚举,可选Optional,可选链

//: Playground - noun: a place where people can play import Cocoa var str0 = "Hello, playground" //类是引用类型,结构体与枚举是值类型 //*****************结构体*************** struct Point { var x = 0 var y = 1 //结构体的的方法 //为了能够在实例方法中修改属性值,可以在方法定义前添加关键字mutating mutat

初步swift语言学习笔记2(可选类型?和隐式可选类型!)

作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/28904115 转载请注明出处 假设认为文章对你有所帮助.请通过留言或关注微信公众帐号fengsh998来支持我,谢谢. 可选类型.隐式可选类型 在swift中.可选类型其根源是一个枚举型.里面有None和Some两种类型.事实上所谓的nil就是Optional.None, 非nil就是Optional.Some, 然后会通过Some(T)包装(wrap)原始值,这

swift语言-可选类型

可选类型 什么是可选类型 可选值类型的数据有两种可能:有值.没有值(nil).注意需要在变量类型后面加问号(?).如果是Int加问号(?),则变量的为Int?型的.问号(?)是可选类型的标志. 可选值可以使用if判断有没有值 #import Foundation var optValue: Int? = nil if optValue != nil{ println("not nil") }else{ println("nil") } 如何获得可选值里的值? 强制解

Swift入门(四)——可选类型(Optionals)与断言(Assert)

可选类型是什么? 首先看一个问题,Swift中String类型的变量有一个叫做toInt的方法,可以把String类型变量转换为Int类型变量. var stringValue = "5" var intValue = stringValue.toInt(); println("intvalue = \(intValue)") 执行以上方法后得到了奇怪的结果: intvalue = Optional(5) 其实,可以发现,toInt方法的返回值并不是Int,而是In