发布于 2014-10-27 09:56:17 | 173 次阅读 | 评论: 0 | 来源: 网友投递

这里有新鲜出炉的Swift教程,程序狗速度看过来!

Swift编程语言

SWIFT,苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C*共同运行于Mac OS和iOS平台,用于搭建基于苹果平台的应用程序。


本文为大家讲解的是Swift中Nil Coalescing运算符的使用技巧详解,感兴趣的同学参考下。

在Swift官方《The Swift Programming Language》文档的Basic Operators一节中添加了Nil Coalescing Operator小结,介绍了一个新的运算符Nil Coalescing,符号是??,它的表现形成如下:

 
let c = a ?? b

这个运算符有两个条件:

  • a必须是Optional类型的。
  • b的类型必须要和a解包后的值类型一致。

符合这两个条件后,我们来解释一下上述这行代码,意思就是c的值是a或b中一个的值,但有前提条件,就是当a解包后值不为nil时,那么就将a解包后的值赋值给c,如果a解包后值为nil,那么就将b的值赋值给c。

我们还可以用三目运算来更形象的解释这个运算符:

 
let c = a != nil ? a! : b

从上面的代码我们很容易理解,当a的值不等于nil时,将a解包后的值赋值给c,否则将b的值赋值给c。

我们来看看官方给的代码示例:

 
let defaultColorName = "red"
var userDefinedColorName: String?   // 默认值为nil
 
var colorNameToUse = userDefinedColorName ?? defaultColorName
// 因为userDefinedColorName的值是nil,所以colorNameToUse的值为"red"
 
userDefinedColorName = "green"
    colorNameToUse = userDefinedColorName ?? defaultColorName
    // 因为userDefinedColorName的值不为nil,所以colorNameToUse的值为"green"

大家看到这应该对Nil Coalescing这个运算符有比较清晰的理解了,但在实际运用中,我们还需要注意以下几点。

编译器中的类型匹配原则

原谅我在末尾加的;,编码习惯而已 = =||

我们先来看一段代码:

 
let a: Int? = nil;
    let b: Int? = 7;
 
    let c = a != nil ? a! : b; // 因为a的默认值为nil,所以c的值为{Some 7}
    let d = a ?? b; // 这里d的值为nil,这是怎么回事?

首先我们需要注意的是,在官方文档中有这么一句话:“The expression b must match the type that is stored inside a”。但是上面的代码示例中,我们的b是Int?类型,那么此时我们的编译器会怎么处理呢?我们通过自己实现一个Nil Coalescing运算符来说明,代码片段如下:

 
infix operator ??? {
        associativity right;
        precedence 110;
    }
 
    func ???<T>(a: T?, b: @autoclosure () -> T) -> T {
        return a != nil ? a! : b();
    }
 
    let d = a ??? b; // 这里d的值仍然是nil

从上面的代码片段中我们可以看出,a的类型是根据传入的b的类型决定的,所以当我们传入的b是Int?类型时,编译器其实将a的类型自动转换为Int??类型了,也就是Optional(a),那么我们就能解释let d = a ?? b;这行代码。因为a == nil但是Optional(a) != nil,所以d = Optional(a)!,d的值为nil。

Nil Coalescing运算符返回值的类型

我们先看示例代码片段:

 
let a: Int? = nil;
    let b: Int? = 5;
    let c: Int? = 6;
 
    // 因为a的默认值为nil,所以将b的值赋值给x,x的值为{Some 5},类型为Int?
    let x = a != nil ? a! : b;
    // 因为c的值不为nil,所以将c解包后的值赋值给y,但是y的值却是{Some 6},而不是6,这是怎么回事?
    let y = c != nil ? c! : b;

根据上面我们提到的编译器中类型判断的原则就可以理解了,因为b的类型是Int?,所以在编译时c的类型已经成了Int??,所以为Int??解包的类型就是Int?了。

如果我们声明变量y的类型,编译器就要提出抗议了:

 
// 如何a为Int?类型,那么编译器就不会通过,因为会导致赋值运算符两边类型不等
    let x: Int = a != nil ? a! : b;
 
    // 这种写法和上面一样,都不会编译通过
    let y: Int = a ?? b;

 



最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务