【亚洲必赢官网】Swift Optional

亚洲必赢官网 1

亚洲必赢官网 2

参考链接:http://blog.csdn.net/zhouleizhao/article/details/40619189

 

挺爱慕这里

言语使用var定义变量,但和别的语言不一样,Swift里不会活动给变量赋开首值,约等于说变量不会有暗中同意值,所以供给选取变量在此之前务要求对其初步化。借使在应用变量在此之前不举办开始化就能报错:

 

   
目前同盟社项目上马用swift写,本身也起头攻读,毕竟苹果出这几个语言,是筹算之后会代替OC的。

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

 

在对于利用? !时本人以为很吸引,怎么区别?。。。。。

上面领悟到的是普普通通值,接下去Optional值要出演了。经喵神提示,Optional其实是个enum
,里面有None
和Some
两种类型。其实所谓的nil正是Optional.None
, 非nil就是Optional.Some
, 然后会通过Some(T)
【亚洲必赢官网】Swift Optional。装进(wrap)原始值,那也是为啥在利用Optional的时候要拆包(从enum里收取来原始值)的缘由,
也是PlayGround会把Optional值显示为接近{Some “hello world”}
的原因,这里是enum Optional的定义:

拆包和平化解包的由来:

? 有一点都不小希望为nil     !一定为非nil  带着可疑 开头研究。。。。。。

enum Optional<T> : LogicValue, Reflectable 
{ 
case None 
case Some(T) 
init() 
init(_ some: T) 
/// Allow use in a Boolean context. 
func getLogicValue() -> Bool 
/// Haskell's fmap, which was mis-named 
func map<U>(f: (T) -> U) -> U? 
func getMirror() -> Mirror}

  其实所谓的 nil 正是 Optional.None, 非 nil 正是Optional.Some,
然后会通过Some(T)包装(wrap)原始值,那也是怎么在使用 Optional
的时候要拆包(从 enum 里抽出来原始值)的由来, 也是 PlayGround 会把
Optional 值彰显为接近 {Some “hello world”}的原因.

斯维夫特语言使用var定义变量,但和别的语言区别,斯威夫Terry不会自行给变量赋开首值,也便是说变量不会有私下认可值,所以供给运用变量从前务须求对其初阶化。要是在利用变量此前不开始展览初叶化就能够报错:

宣示为Optional只必要在品种前面紧跟一个?
即可。如:

1.swift
?和 !的区别

var stringValue : String

var strValue: String? 
//?相当于下面这种写法的语法糖
var strValue: Optional<String>

  一.一 Swift语言使用var定义变量,但和其余语言分化,Swift里不会活动给变量赋初叶值,也正是说变量不会有暗中认可值,所以供给选用变量在此以前务供给对其伊始化。如若在行使变量此前不实行开首化就能报错:

//error: variable ‘stringValue’ used before being initialized

地点那几个Optional的宣示,意思不是”作者申明了3个Optional的String值”,
而是”笔者表明了2个Optional类型值,它大概含有二个String值,也可能什么都不含有”,也正是说实际上大家申明的是Optional类型,而不是宣称了一个String类型,那点亟需记住。

1 var stringValue : String 
2 //error: variable 'stringValue' used before being initialized
3 //let hashValue = stringValue.hashValue
4 let hashValue = stringValue.hashValue

//let hashValue = stringValue.hashValue

建议再读二遍上段文字。

  若在一个视图调整器中 class xxxController

let hashValue = stringValue.hashValue

若果评释为Optional的,若是不显式的赋值就能够有个暗中认可值nil。决断一个Optional的值是不是有值,能够用if来判断:

 1 class AdjustFontViewController: UIViewController{    //报错error: Class 'xxxx' has no initializers  
 2 //Fix-it Stored property 'stringValue' without initial value prevents synthesized initalizers
 3 
 4 var stringValue: String
 5 
 6 }
 7 
 8 //    修改为:
 9 //    当我们不知道变量的值时,可以将改变量设置为可选类型
10 var stringValue: String?  
11 
12 
13 
14 //    表明str是可选类型(是string类型或者nil类型)  
15 var value: String?="hello world"  
16 //value = value?.uppercaseString  
17         
18 //    拆包  
19       if let unwrappedStr = value{  
20           print("拆包:\(unwrappedStr.uppercaseString)")     //如果value(有值,将值复制给常量unwrappedStr)  
21       }  
22       else  
23       {  
24           print("value是nil")    //str不赋初始值时  
25       }  
26        
27 //    确定value有存在的值(如果str没有被赋实际意义的值,强制拆包将造成应用程序崩溃)  
28       print(" 拆包:\(str!.uppercaseString)")  
29  
30 
31 
32 //    两种拆包方式       
33 //    1.隐性拆包  
34       var str1:String! = "hello world"    //已经确定变量str1是有值的(如果未赋值,应用程序将崩溃)  
35       str1 = str1.lowercaseString  
36       print("拆包:\(str1)")  
37         
38       print(str)  
39         
40 //    2.显性拆包
41       var str2:String?="Hello World"  
42       let lowerStr2 = str2?.lowercaseString//lowerStr2是可选的,如果有值,则值为“hello world”否则为nil 
43 
44 
45 
46 
47                       

 
 上边掌握到的是一般值,接下去Optional值要出场了,Optional其实是个enum,里面有None和Some两体系型。其实所谓的nil就是Optional.None,
非nil正是Optional.Some,
然后会通过Some(T)包装(wrap)原始值,那也是干什么在行使Optional的时候要拆包(从enum里抽出来原始值)的因由,
也是PlayGround会把Optional值展现为接近{Some “hello
world”}的由来,这里是enum Optional的定义:

if strValue 
{ 
//do sth with strValue
}

 

enum Optional: LogicValue, Reflectable {   

下一场怎么利用Optional值呢?文书档案中也有涉及说,在动用Optional值的时候须要在切实的操作,举个例子调用方法、属性、下标索引等后边供给增多二个?
,如果是nil值,也就是Optional.None
,会跳过前边的操作不实行,假若有值,便是Optional.Some
,大概就能够拆包(unwrap),然后对拆包后的值实行后边的操作,来保险奉行这些操作的安全性,比方:

 

 case None    case Some(T)    init()    init(_ some: T)    

let hashValue = strValue?.hashValue

 

/// Allow use in a Boolean context.   

strValue是Optional的字符串,假如strValue是nil,则hashValue也为nil,纵然strValue不为nil,hashValue就是strValue字符串的哈希值(其实也是用Optional
wrap后的值)
其它,?还是能够用在平安地调用protocol类型方法上,举例:

  1.二 上边理解到的是常常值,接下去Optional值要出台了。

 func getLogicValue() -> Bool    

@objc protocol Downloadable { 
@optional func download(toPath: String) -> Bool;
}
@objc class Content: Downloadable { 
//download method not be implemented
}
var delegate: Downloadable = Downloadable()
delegate.download?("some path")

    Optional其实是个enum,里面有None和Some二种档期的顺序。其实所谓的nil就是Optional.None,
非nil正是Optional.Some,
然后会通过Some(T)包装(wrap)原始值,那也是干什么在应用Optional的时候要拆包(从enum里抽出来原始值)的因由,
也是PlayGround会把Optional值展现为接近{Some “hello
world”}的由来,这里是enum Optional的定义:

/// Haskell’s fmap, which was mis-named    

因为地点的delegate是Downloadable类型的,它的download
艺术是optional,所以它的具体得以落成有未有download
办法是不明确的。Swift提供了1种在参数括号前增加1个?
的不二等秘书籍来安全地调用protocol的optional方法。
除此以外借令你必要像下边那样向下转型(Downcast),大概会用到 as?

 1 enum Optional<T> : LogicValue, Reflectable {
 2     case None
 3     case Some(T)
 4     init()
 5     init(_ some: T)
 6 
 7     /// Allow use in a Boolean context.
 8     func getLogicValue() -> Bool
 9 
10     /// Haskell's fmap, which was mis-named
11     func map<U>(f: (T) -> U) -> U?
12     func getMirror() -> Mirror
13 }

func map(f: (T) -> U) -> U?

if let dataSource = object as? UITableViewDataSource 
{
 let rowsInFirstSection = dataSource.tableView(tableView, numberOfRowsInSection: 0)
}

壹.二.1  ?的二种选择情形:

func getMirror() -> Mirror

到此地大家看出了?
的三种选择处境:一.证明Optional值变量二.用在对Optional值操作中,用来决断是还是不是能响应前边的操作3.用来安全调用protocol的optional方法四.用到
as? 向下转型(Downcast)

a. 表明 Optional 值为可选变量

}

别的,对于Optional值,无法直接进行操作,不然会报错:

b. 用在对 Optional 值操作中,用来推断是不是能响应前面 的操作

评释为Optional只须要在类型前边紧跟一个?即可。如:

//error: 'String?' does not have a member named 'hashValue'
//let hashValue = strValue.hashValue
// ^ ~~~~~~~~~let hashValue = strValue.hashValue

c. 用于安全调用 protocol 的 optional 方法

var strValue: String?//?约等于下边那种写法的语法糖

上边提到Optional值供给拆包(unwrap)后本事获取原来值,然后才具对其操作,那怎么来拆包呢?拆包提到了三种方式,一种是Optional
Binding
, 比如:

d. 使用 as? 向下转型(Downcast)

var strValue: Optional

if let str = strValue { 
let hashValue = str.hashValue
}

 

上边这几个Optional的宣示,意思不是”小编注明了一个Optional的String值”,
而是”小编注脚了1个Optional类型值,它可能含有1个String值,也说不定什么都不含有”,也正是说实际上大家申明的是Optional类型,而
不是宣称了三个String类型,那或多或少索要记住。

还有一种是在切实可行的操作前增添!
标记,好呢,那又是什么稀奇的语法?!
一向上例子,strValue是Optional的String:

a. Optional 可选值 

壹旦评释为Optional的,假如不显式的赋值就能够有个默许值nil。判定四个Optional的值是或不是有值,可以用if来判别:

let hashValue = strValue!.hashValue

 定义变量时,假若钦赐是可选的,表示该变量能够有三个点名项目的值,也足以是
nil

ifstrValue {

这里的!
意味着“笔者分明这里的的strValue一定是非nil的,尽情调用吧” ,比如那种情形:

 定义变量时,在项目后边增添2个 ?,表示该变量是可选的

//do sth with strValue

if strValue { 
let hashValue = strValue!.hashValue
}

 变量可挑选的暗许值是 nil

}

{}里的strValue一定是非nil的,所以就会一直抬高!,强制拆包(unwrap)并举行前面包车型的士操作。
当然借使不加剖断,strValue异常的大心为nil的话,就能出错,crash掉。
设想下那1种意况,我们有三个自定义的MyViewController
类,类中有一个属性是myLabel
,myLabel是在viewDidLoad中展开起头化。因为是在viewDidLoad中初叶化,所以不能够间接评释为普通值:var
myLabel : UILabel
,因为非Optional的变量必须在宣称时依然构造器中开展初叶化,但我们是想在viewDidLoad中开端化,所以就只可以证明为Optional:var
myLabel: UILabel?
,
固然大家规定在viewDidLoad中会起先化,并且在ViewController的生命周期内不会置为nil,可是在对myLabel操作时,每一次依旧要加上!
来强制拆包(在读取值的时候,也足以用?
,多谢iPresent在还原中升迁),举个例子:

 1 //n1 = nil  //编译错误
 2 
 3 //let str: String = nil   //编译错误
 4   
 5    
 6  var n2 : Int? = 10
 7  
 8  print("-----n2=\(String(describing: n2))")
 9  
10  n2 = nil
11  
12  print("-----n2=\(String(describing: n2))")
13 
14 
15  let str: String! = nil
16 
17  print("-----str=\(str)")
18  

下一场怎么利用Optional值呢?文书档案中也有提到说,在运用Optional值的时候必要在切实的操作,例如调用方法、属性、下标索引等后边供给加上七个?,假设是nil值,也正是Optional.None,会跳过后边的操作不实施,借使有值,就是Optional.Some,或者就能够拆包(unwrap),然后对拆包后的值施行后边的操作,来保障施行那么些操作的安全性,例如:

myLabel!.text = "text"
myLabel!.frame = CGRectMake(0, 0, 10, 10)...

 

let hashValue = strValue?.hashValue

对于那体系型的值,大家得以一贯这么注解:var myLabel: UILabel!
, 果然是高(hao)大(gui)上(yi)的语法!,
那种是优秀的Optional,称为Implicitly Unwrapped Optionals
,
直译正是隐式拆包的Optional,就等于说你每便对那连串型的值操作时,都会自行在操作前补上三个!
拓展拆包,然后在实践前面包车型大巴操作,当然要是该值是nil,也如出1辙会报错crash掉。

 常量可选用未有暗中认可值,首要用来在构造函数中给常量设置早先数值

strValue是Optional的字符串,假设strValue是nil,则hashValue也为nil,借使strValue不为nil,hashValue就是strValue字符串的哈希值(其实也是用Optional
wrap后的值)

var myLabel: UILabel! 
//!相当于下面这种写法的语法糖
var myLabel: ImplicitlyUnwrappedOptional<UILabel>

扬言为Optional只需求在品种前边紧跟一个?就能够,strValue 是 Optional 的 String。如:

此外,?仍是能够用在长治地调用protocol类型方法上,举例:

那么!
粗粗也有三种选取处境一.强制对Optional值实行拆包(unwrap)二.表明Implicitly
Unwrapped Optionals
值,一般用来类中的属性

1 var strValue: String?   //?相当于下面这种写法的语法糖
2 var strValue: Optional<Int>

@objc protocol Downloadable {

斯威夫特是门新生的语言,我们有幸见证了它的诞生,激动之余也在倾倒苹果大马金刀的生产1个新的语言代替三个壹度相比早熟语言的魄力,明日在乐乎早报上看到二个作答是说Swift是一门玩具语言,正当想去戏弄,开采回答已经被删除了。个人以为苹果是很认真的出产斯维夫特的,从Swift的各个细微的布署也能看的出来。
别的那五个小符号就费用了小编不少的光阴来掌握,只怕仍旧会有错误和不妥之处,欢迎大家指正,本文目的在于进行试探。除却,Swift还有好些个很棒的特色,WWDC
2014 会有四三个和Swift语言相关的Video,大家也能够去关注一下。

只要注解为Optional的,假若不显式的赋值就能够有个默许值nil。判别一个Optional的值是或不是有值,能够用if来推断:

@optional func download(toPath: String) -> Bool;

if strValue {
    //do sth with strValue
}

}

 

@objc class Content: Downloadable {

一.二.2  呈现拆包和隐式拆包

//download method not be implemented

 

}

a.
 使用问号(?)注解的可选类型,在拆包时须求动用惊叹号(!),这种拆包方式叫做“显式拆包”;

var delegate: Downloadable = Downloadable()

 

delegate.download?(“some path”)

b.
使用感叹号(!)注明的可选类型,在拆包时方可不采用惊叹号(!),那种代表方法叫做“隐式拆包”。

 
 因为上面包车型客车delegate是Downloadable类型的,它的download方法是optional,所以它的现实贯彻有未有download方法是不鲜明的。斯维夫特提供了壹种在参数括号前增进二个?的秘技来安全地调用protocol的optional方法。

 

别的假设您必要像上边那样向下转型(Downcast),也许会用到as?:

 1  
 2 
 3 
 4 //  在可选类型的问号(?)或感叹号(!)究竟有什么区别呢?这与可选类型的“拆包”(unwrapping)有关,拆包是将可选类型变成普通类型,如果我们直接打印非空的可选类型值,代码如下:
 5 
 6 var n3: Int? = 10
 7 
 8 print(n3)   //输出是:Optional(10)
 9 
10 //print(n3 + 10)     //发生编译错误,加 !可以编译过
11 
12  
13 
14 /* 
15 
16 如果 Optional 值是 nil,不允许参与计算
17 
18  只有解包(unwrap)后才能参与计算
19 
20  在变量后添加一个 !,可以强行解包
21 
22  */
23 
24 var n4: Int? = 10
25 
26 print(n4! + 100)    //显式拆包
27 
28  
29 
30 var n5: Int! = 10
31 
32 print(n5 + 200)  //隐式拆包
33 
34  

iflet dataSource =objectas?UITableViewDataSource {

 

let rowsInFirstSection= dataSource.tableView(tableView,
numberOfRowsInSection:0)

 

}

1.3  ??运算符

?   的二种选拔情况:

 

1.声明Optional值变量

 1 /*
 2 
 3 ?? 运算符可以用于判断 变量/常量 的数值是否是 nil,如果是则使用后面的值替代
 4 
 5  在使用 Swift 开发时,?? 能够简化代码的编写
 6 
 7 */
 8 
 9 
10 let num: Int? = nil
11 
12  
13 let r1 = (num ?? 0) + 10
14 
15 print(r1)

二.用在对Optional值操作中,用来判断是不是能响应前边的操作

 

三.用来安全调用protocol的optional方法

 

四.使用 as? 向下转型(Downcast)

一.4 拆包决断

平素上例子,strValue是Optional的String:

   单个可采用判别

let hashValue = strValue!.hashValue
这里的!表示“作者鲜明这里的的strValue一定是非nil的,尽情调用吧”
,比如那种场所:

 

ifstrValue {   let hashValue= strValue!.hashValue  }

 1  let url = NSURL(string: "http://www.baidu.com")
 2 
 3  
 4 
 5  //: 方法1: 强行解包 - 缺陷,如果 url 为空,运行时会崩溃
 6 
 7  let request = NSURLRequest(URL: url!)
 8 
 9  
10 
11  //: 方法2: 首先判断 - 代码中仍然需要使用 `!` 强行解包
12 
13  if url != nil {
14 
15  let request = NSURLRequest(URL: url!)}
16 
17  
18 
19  //: 方法3: 使用 `if let`,这种方式,表明一旦进入if 分支,u 就不在是可选项
20 
21  if let u = url where u.host == "www.baidu.com" {
22 
23  let request = NSURLRequest(URL: u)
24 
25  }

{}里的strValue一定是非nil的,所以就能够直接助长!,强制拆包(unwrap)并举行前边的操作。
当然假使不加决断,strValue非常大心为nil的话,就能够出错,crash掉

 

设想下那1种情景,我们有贰个自定义的MyViewController类,类中有三个天性是myLabel,myLabel是在viewDidLoad中开张开始化。因为是在viewDidLoad中开端化,所以不可能一贯证明为普通值:var
myLabel :
UILabel,因为非Optional的变量必须在宣称时或许构造器中进行早先化,但大家是想在viewDidLoad中伊始化,所以就不得不声明为Optional:var
myLabel: UILabel?,
纵然我们明确在viewDidLoad中会起首化,并且在ViewController的生命周期内不会置为nil,可是在对myLabel操作时,每一趟依然要抬高!来强制拆包(在读取值的时候,也得以用?,谢谢iPresent在平复中提示),举个例子:

 

myLabel!.text =”text”        myLabel!.frame = CGRectMake(0,0,10,10)

 1.4.二  可选项原则决断

对于那类别型的值,大家得以一贯这么注明:var myLabel: UILabel!,
果然是高(hao)大(gui)上(yi)的语法!, 那种是超过常规规的Optional,称为Implicitly
Unwrapped Optionals,
直译正是隐式拆包的Optional,就约等于说你每一遍对这种类型的值操作时,都会自动在操作前补上3个!进行拆包,然后在推行后边的操作,当然假使该值是nil,也如出一辙会报错crash掉。

    1> 初学 swift 1比相当大心就能够让 if 的嵌套等级次序很深,让代码变得很丑

varmyLabel:UILabel!//!也正是下边那种写法的语法糖varmyLabel:ImplicitlyUnwrappedOptional

 

!  差不多也有三种选择意况

1 if let u == url
2 
3 {
4 
5     if u.host == "www.baidu.com" {
6 
7         let request = NSURLRequest(URL: u)
8 
9 }

一.恐吓对Optional值实行拆包(unwrap)

 

二.申明Implicitly Unwrapped Optionals值,一般用于类中的属性

    2> 使用 where 关键字

留意:if let 不可能与利用 &&、|| 等原则判别。假使要加进条件,可以选取where 子句,where 子句未有智能提示

 

1  if let u = url where u.host == "www.baidu.com"     {
2 
3  let request = NSURLRequest(URL: u)
4 
5  }

 

 

 

亚洲必赢官网 ,文书档案中也有涉及说,在利用Optional值的时候供给在切切实实的操作,比方调用方法、属性、下标索引等后面供给丰盛三个?,经喵神指正,”Optional
Chaining的问号的情趣是询问是不是响应前面这么些艺术,和原来的isResponseToSelector有个别类似”,若是是nil值,也正是Optional.None,固然无法响应后边的主意,所以就能够跳过,假设有值,正是Optional.Some,只怕就能够拆包(unwrap),然后对拆包后的值实行后边的操作,比方:

1 let hashValue = strValue?.hashValue

strValue是Optional的字符串,要是strValue是nil,则hashValue也为nil,如果strValue不为nil,hashValue便是strValue字符串的哈希值

到此地我们看出了?的二种采纳意况:

声明Optional值变量
用在对Optional值操作中,用来判定是还是不是能响应前面包车型地铁操作

别的,对于Optional值,不可能一向开始展览操作,否则会报错:

1 //error: 'String?' does not have a member named 'hashValue'
2 //let hashValue = strValue.hashValue
3 //                ^        ~~~~~~~~~

地点提到Optional值需要拆包(unwrap)后技巧博取原来值,然后手艺对其操作,那怎么来拆包呢?拆包提到了三种方法,壹种是Optional
Binding, 比方:

1 if let str = strValue {
2     let hashValue = str.hashValue
3 }

 

 1 func demo4() {
 2 
 3     let urlString = "http://www.baidu.com/中文"
 4 
 5     // 注意:构造函数如果有 `?` 表示不一定能够创建出对象
 6 
 7     let url = NSURL(string: urlString)
 8 
 9     print(url)
10 
11     
12 
13     // 注意:如果参数中,没有 ? 表示必须要有值,如果为 nil,就崩!
14 
15     if url != nil {
16 
17         let request = NSURLRequest(URL: url!)
18 
19         print(request)
20 
21     }
22 
23 }

 

  1.2 加惊叹号    

    一.贰.一 ! 使用的风貌

  a. 强制对 Optional 值实行拆包(unwrap)

  b. 表明 Implicitly Unwrapped Optionals 值,一般用来类中的属性

 

例子,strValue是Optional的String:

1 1 let hashValue = strValue!.hashValue  //这里的!表示“我确定这里的的strValue一定是非nil的,尽情调用吧”

{}里的strValue一定是非nil的,所以就能够平昔抬高!,强制拆包(unwrap)并实施前边的操作。
当然借使不加判别,strValue十分大心为nil的话,就能出错,crash掉。

 

设想下那1种意况,大家有多少个自定义的MyViewController类,类中有3个属性是myLabel,myLabel是在viewDidLoad中进行起头化。因为是在viewDidLoad中起始化,所以不可能一直证明为普通值:var
myLabel :
UILabel,因为非Optional的变量必须在评释时可能构造器中进行初阶化,但大家是想在viewDidLoad中开首化,所以就只好注明为Optional:var
myLabel: UILabel?,
即使大家规定在viewDidLoad中会开头化,并且在ViewController的生命周期内不会置为nil,不过在对myLabel操作时,每一趟仍旧要增添!来强制拆包(在读取值的时候,也得以用?,谢谢iPresent在复苏中提示),举例:

1 myLabel!.text = "text"
2 myLabel!.frame = CGRectMake(0, 0, 10, 10)

对此那连串型的值,我们得以一直这么注解:var myLabel: UILabel!
,那种是独特的Optional,称为Implicitly Unwrapped Optionals,
直译正是隐式拆包的Optional,就约等于说您每一趟对那类别型的值操作时,都会自动在操作前补上1个!实行拆包,然后在实施后边的操作,当然假若该值是nil,也锲而不舍会报错crash掉。

1 var myLabel: UILabel!  //!相当于下面这种写法的语法糖
2 var myLabel: ImplicitlyUnwrappedOptional<UILabel>

 

展开:对 !应用还有 as

那么!差不多也有二种选择情况
壹.要挟对Optional值实行拆包(unwrap)
2.注明Implicitly Unwrapped Optionals值,一般用于类中的属性

 

 

 

网站地图xml地图