Swift基本类型

Swift的类型是在C和OC的基础上发展而来的,Int是整型;Double和Float是浮点型;Bool是布尔型;String是字符串。类似OC,Swift也提出了三个集合类型:Array、Set、Dictionary;

除了上述比较熟悉的类型,Swift还增加了OC中没有的类型,比如元组(Tuple);Swift还增加了可选(Optional)类型。

Swift是一个类型安全的语言(甚至以此著称),可选(Optional)就是一个很好的例子。Swift可以让你清除地知道值的类型。如果你的代码期望得到一个String,你却不小心传入一个Int,Swift的类型安全机制会在开发阶段发现这个问题,避免在runtime出错。

常量和变量

在OC以及C中,一个值类型或引用类型数据是常量还是变量由关键字const决定。在Swift中,在没有const这一说喽。

let和var

Swift使用let来声明常量,使用var来声明变量;

声明

Swift在声明一个变量或者常量可以携带类型信息,也可以不携带。

P.S:声明变量/常量时,不指明类型而让Swift编译器隐式处理的这种行为被称为『类型推测』(Type Inference),后文有更详细介绍。

赋值

本来常量和变量是编程语言里非常基础的概念,没啥好讲的,但Swift世界里,有些许不同,在赋值过程中,需要注意:

  1. 无论是常量还是变量,在定义时都可以没有右值(即没有初始化值,譬如var a: Intlet b: NSObject),在其他语言中,系统往往会在这种情况下为它们分配一个默认值,譬如OC会设置默认值0或者nil;但这在Swift的世界里是不可能的,Swift不会为它们设置任何默认值,无论是在什么时候;
  2. 无论是常量还是变量,在第一次使用(访问)之前必须要保证有与类型匹配的值(譬如,var a:Int; print("a = \(a)")是不合法的);
  3. 和其他语言一样,常量只能进行一次赋值,变量可以进行任意多次赋值;但无论何时,赋值时右值都必须与其定义时的类型匹配,Swift不会帮你做任何转换;

第3点意味着:

  • let aInt: Int = 0; aInt = 5不合法,常量只能进行一次初始化;
  • var aObject: NSObject; aObject = nil不合法,右值nil与NSObject类型不匹配;
  • var aInt: Int; aInt = 0.0不合法,右值0.0与Int类型不匹配;

说明

  • 常量/变量使用之前没有初始化/赋值在Xcode的编译错误通常是:『Variable variableName used before being initialized』;
  • 常量/变量赋值时类型不对的编译错误是:『Cannot assign a value of type WrongType to a value of type CorrectType』;

总之,一定要深刻理解到Swift是一门类型安全的语言,《The Swift Programming Language》是这么说的:

Swift is a type safe language. A type safe language encourages you to be clear about the types of values your code can work with. If part of your code expects a String, you can not pass it an Int by mistake.

类型推测(Type Inference)

显然,『类型推测』在处理引用类型时非常便利,这会使得代码更简洁;但是在处理值类型时可能会有些许麻烦,譬如1.0推断为float还收double?在这种记忆力不是特别牢靠(不太确认)的情况下最好还是显式写出变量/常量的类型吧。

静态局部变量、静态全局变量、全局变量

「静态局部变量」、「静态全局变量」、「全局变量」这些是C语言里的概念,在Swift似乎不存在。

可选类型(Options)

正如上文所阐述的,Swift是一门『类型安全』的语言,在对对象赋值时,左值类型和右值类型必须匹配,否则无法通过编译;但在OC中,有非常非常多的机会与nil指针打交道,譬如:

  • 某个方法/函数返回nil指针,表示返回的对象不存在;
  • 某个方法/函数的某个传入参数为nil,表示传入空值;
  • 某个strong类型指针赋值nil,表示不再持有原对象;

Swift的创建是基于Objective-C的,何况还得保证与之兼容,必然考虑到了这个问题,Swift中能够赋值nil的类型叫「可选类型」(optional)。

理解optionals

C和OC中并没有可选这个概念。在OC的对象世界里,一个指针要么对应这一个对象,要么对应着nil;很多时候我们不知道这个指针到底是空指针,还是有一个有效的对象与之对应,所以我们在OC中经常会写大量大量的if语句判断某个指针是否为空。而在Swift中,不需要这么麻烦,因为它是一门类型安全的语言,NSObject类型变量在运行时一定有一个NSObject对象与之对应,不可能是nil值。想想这个就激动,想象一下,以前在OC中调用具有返回值的方法时经常需要对返回值进行判断,因为必须要考虑它可能返回nil啊,譬如:

NSMutableArray *aArray = [NSMutableArray array];
NSString *aStr = [self aFuckMethod]; // aFuckMethod的实现代码不可见,不知道一定会返回一个NSString
if (aStr) {
[aArray addObject:aStr];
}

如果在Swift中,aFuckMethod的原型为func aFuckMethod() -> String,则清晰表明了aFuckMethod方法一定会返回一个非String类型对象,那么上面一段代码就可以省掉那个if语句了;对比Swift,确实感觉到了OC是一个门太落后的语言,太罗嗦了!

回过头来阐述Swift的optional。简而言之:

You use optionals in situations where a value may be absent. An optional says:

 * There is a value, and it equals x 

or
 * There is not value at all

相对于OC,Swift的optionals对值类型(譬如整型、结构体)和引用类型(类对象)的处理更具一致性。在OC中,一个方法要不返回一个对象要不返回nil,后者表示『缺乏一个合法的对象』;然而,这只对对象起作用;对于结构体、基本的C类型或者枚举都不起作用,处理这些类型,OC方法一般会返回一个特殊值(譬如NSNotFound)来暗示值缺失,这种方法会假设方法的调用者知道并有意识对特殊值进行判断。然而,Swift的optionals可以让你暗示任意类型的缺失,并不需要一个特殊值。

P.S:稍微体会一下,就会意识到Swift的optional高明多了。

使用optionals

Optional类型默认值

在OC中,若声明一个对象(指针)但不赋值,系统会默认将之设置为nil;在Swift中也类似,对于一个optional,若不对其赋值,则默认为nil,这可不是我瞎说,文档有说明:

If you define an optional variable without providing a default value, the variable is automatically set to nil for you.

P.S:似乎这是Swift唯一为变量/常量设置默认值的时机。

简而言之,你可以对一个optional变量赋值nil,也可以赋值相应的对象。

在OC中,我们经常需要对一个类类型指针进行判断,判断它是否为nil;在Swift中使用optional也不省心,也常常需要写if语句判断,只是Swift中提供了更多丰富的处理方式。

强制解析(Foreced Unwrapping)符!

You can use an if statement to find out whether an optional contains a value by comparing the optional against nil. You perform this comparison with the == or !=.

当你确定可选包确实含值之后,你可以在可选的名字后面加一个感叹号!来获取值。这个惊叹号表示『我知道这个可选有值,请使用它』,这被称为可选值的强制解析(forced unwrapping),如下:

let strNumber = "42"
var convertNumber: Int?
convertNumber = strNumber.toInt()
if convertNumber != nil {
println("转换后的结果为:\(convertNumber!)")
}

值得注意的是,使用!来获取一个不存在的可选值会导致runtime error。因此使用!强制解析前,一定要确定optional包含一个非nil的值。

总之,一定要记住,惊叹号!对于optional而言是『强制解析符』,而不是仅仅是『解析符』,这可不是咬文嚼字,虽然只有两字之差,但意思差远了。

可选绑定(Optional Binding)

使用可选绑定(optional binding)来判断optional是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在ifwhile语句中来对可选的值进行判断并把值赋给一个常量或者变量,如下:

let strNumber = "42"
if let actualNumber = strNumber.toInt() {
println("转换后的结果为:\(actualNumber)")
}

这段代码可以理解为:
如果strNumber.toInt()返回的optional包含一个Int值,则创建一个叫actualNumber的新常量(actualNumber为Int类型)并将可选包含的值赋给它。

这段『可选绑定』的代码显然比前一段『强制解析』的代码要简短一些,可是,我总觉得Swift的这一部分设计不好,晦涩难懂。首先,
下意识里,let actualNumber = strNumber.toInt()等价两句代码:let temp = strNumber.toInt()let actualNumber = temp,得到的actualNumber应该是一个optional啊,怎么文档给出的解释暗示actualNumber是一个Int类型变量呢?Fuck!

Implicitly Unwrapped Optionals

『隐式解析可选』作为右值?

『隐式解析可选』似乎比普通optional更安全,既然这么好,为什么不放弃前面的普通optional呢?似乎是不行的,文档这么说:

Do not use an implicitly unwrapped optional when there is a possibility of a variable becoming nil at a later point. Always use a normal optional type if you need to check for a nil value during the lifetime of a variable.

元组(Tuple)

元组概述

元组(tuples)早已经是很多高级语言(譬如Python)的中重要组成成分了,它用来把多个值组合成一个复合值,而这些值可以是任意类型(无所谓变量还是常量,无所谓值类型还是引用类型,无所谓optional还是non-optional),并不要求是相同类型。

使用元组

分解元组(Decompose Tuple)

Swift中的元组分解(decompose)和Python中差不多,你可以使用如下语法将一个元组分解成单独的常量和变量:

let http404Error = (404, "Not Found")
// http404Error的类型是(Int, String),值是(404, "Not Found") var (status, statusMessage) = http404Error

在decompose时,如果只需要一部分元组信息,使用_来标记要忽略的部分。

Tuple支持下标操作

可以使用下标访问一个元组中指定的元素,譬如http404Error.0表示访问上述元组http404Error的第一个元素(值为404的Int型)。

给Tuple元素命名

使用下标访问Tuple元素难免不够完美,毕竟数字太冰冷了;Swift的Tuple还支持给Tuple元素命名,譬如:

let http404Error = (status: 404, message:"Not Found")
println("状态码:\(http404Error.status), 信息:\(http404Error.message)")

理解元组

根据我的理解,Tuple并不算一种类型(事实上Swift中也不存在所谓的Tuple类型),它更应该看成是Swift所支持的一种语言特性(语法)。Tuple看起来像数组,但显然不同于数组,数组可是一种数据类型,数组包括大量的功能方法,「元组」是不存在所谓的方法的。也正因为如此,元组的使用场景比较单一,一般用来临时组织数据(譬如组织函数/方法的返回值和参数)。

Swift初见的更多相关文章

  1. Swift 初见

    http://numbbbbb.gitbooks.io/-the-swift-programming-language-/chapter1/02_a_swift_tour.html 本页内容包括: 简 ...

  2. 【Swift初见】Swift词典

    顾名思义.当我们仰望的时候,我们将基于索引查找我们需要找到的资源.在swift这同样适用,每个对象包括字典key和value.我们key为了找到当前这个key相应的value.与数组不同的是,字典项字 ...

  3. 【Swift初见】SourceKitService Terminated

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/weasleyqi/article/details/36162085 心血来潮想试试最新的Xcode6 ...

  4. 从今天开始学习Swift -- Swift 初见 (转)

    原文地址:http://www.cocoachina.com/newbie/basic/2014/0604/8675.html   Swift系列文章由CocoaChina翻译小组翻译自苹果的官方文档 ...

  5. 【Swift初见】Swift数组(二)

    在苹果的开发文档中对Array还提供了其它的操作算法: 1.Sort函数: 对数组进行排序.依据指定的排序规则,看以下的代码: var array = [2, 3, 4, 5] array.sort{ ...

  6. Swift语言快速入门

    Swift语言快速入门(首部同步新版官方API文档和语法的Swift图书,确保代码可编译,作者专家在线答疑,图书勘误实时跟进) 极客学院 编著   ISBN 978-7-121-24328-8 201 ...

  7. Swift语言的基础详解

    1.1.关于swift · Swift 是一种适用于 iOS 和 OS X 应用的全新编程语言,它建立在最好的 C 和 Objective-C 语言之上,并且没有 C 语言的兼容性限制.Swift 采 ...

  8. Swift UI

    概述 Apple近日发布了Swift编程语言,Swift是供iOS和OS X应用编程的新编程语言.相信很多开发者都在学习这门新语言.   废话不多说,下面我就来学习使用Swift创建一个简单的UI应用 ...

  9. Swift -- 中文版两大官方文档汇总

    Swift官方文档由CocoaChina翻译小组精心翻译制作而成,目前两本文档中文版已全部完成!在此,我们对所有参与的译者.组织人员以及工作人员表示衷心的感谢!本文为您提供两本文档的在线阅读以及下载! ...

随机推荐

  1. win10 配置pylucene

    参考文章 http://lxsay.com/archives/269 Windows 10 64 Bit 编译安装 PyLucene 6.2, 6.4 或 6.5 POSTED ON 2017-02- ...

  2. iOS开发 CGBitmapContextCreate

    最近项目中,需要对图片进行各种操作. 使用CGBitmapContextCreate 创建位图上下文. CG_EXTERN CGContextRefCGBitmapContextCreate(void ...

  3. [转载] C/C++中怎样获取日期和时间

    C/C++中怎样获取日期和时间摘要:  本文从介绍基础概念入手,探讨了在C/C++中对日期和时间操作所用到的数据结构和函数,并对计时.时间的获取.时间的计算和显示格式等方面进行了阐述.本文还通过大量的 ...

  4. nopCommerce从无到有01-初探nopCommerce

    nopCommerce框架的基本结构: 该结构可以参考DDD(领域驱动设计)模式. (注:上图源自他人文章,具体出处不祥,在此引用,感谢原创) nopcommerce官方地址:http://www.n ...

  5. 5.4 heapq--堆队列算法

    本模块实现了堆队列算法,也叫作优先级队列算法.堆队列是一棵二叉树.而且拥有这样特点,它的父节点的值小于等于不论什么它的子节点的值,假设採用数组array实现,能够把它们的关系表示为:heap[k] & ...

  6. PHP函数parse_url()如何使用

    又是一个非常使用的函数. <?php $url='http://www.cnblogs.com/lovebing'; $data = parse_url($url); var_dump($dat ...

  7. Kick the ball!(dfs)湖南省赛第十届

    Problem K: Kick the ball! Time Limit: 1 Sec  Memory Limit: 128 MB  Special Judge Submit: 109  Solved ...

  8. 本机上使用Three.js载入纹理

    怎样载入纹理 // 首先, 创建一个纹理 var mapUrl = "../images/molumen_small_funny_angry_monster.jpg"; var m ...

  9. 数据迁移实战:基于Kettle的Mysql到DB2的数据迁移

    From:https://my.oschina.net/simpleton/blog/525675 一.什么是ETL ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数 ...

  10. Hive merge(小文件合并)

    当Hive的输入由非常多个小文件组成时.假设不涉及文件合并的话.那么每一个小文件都会启动一个map task. 假设文件过小.以至于map任务启动和初始化的时间大于逻辑处理的时间,会造成资源浪费.甚至 ...