Swift3.0基础部分(The Basics)(二)

类型安全和类型推断(Type Safety and Type Inference)
  • Swift是一个类型安全的语言,所以会在编译的时候会检查类型不匹配的错误。这么做可以尽可能早的在开发过程中发现错误。
  • 类型检查帮助避免在不同类型的值的错误。虽然这样,但也不意味着必须把每个变量(常量)的类型写出来。因为Swift使用类型推断来给出合适的类型。
let meaningOfLife = 42
//meaningOfLife is inferred to be of type Int

当不声明一个浮点型时,默认是Double类型。

let pi = 3.14159
//pi is inferred to be of type Double
let anotherPi = 3 + 0.14159
//anotherPi is also inferred to be of type Double
数字型的字面值(Numeric Literals)
  • 整型的字面可以这么写:
    • 十进制:不需要前缀
    • 二进制:前缀为"0b"
    • 八进制:前缀为"0o"
    • 十六进制:前缀为"0x"

以下这些的值都是17

let decimalInteger = 17
let binaryInteger = 0b10001
let octalInteger = 0o21
let hexadecimalInteger = 0x11
  • 浮点型的字面可以为十进制(没有前缀),也可以为十六进制(前缀为"0x")。十进制数用大写或者小写的e表示指数,十六进制数用大写或小写的p表示指数。
    十进制:

    • 1.25e2 means 1.25 x 10^2, or 125.0.
    • 1.25e-2 means 1.25 x 10^(-2), or 0.0125.

    十六进制:

    • 0xFp2 means 15 x 2^2, or 60.0.
    • 0xFp-2 means 15 x 2^(-2), or 3.75.

    下面这些浮点型的值都是12.1875

let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0

numeric literals为了更好的阅读代码可以包含额外的格式,整型和浮点型都可以使用前缀"0"和下划线"_"

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
数值类型的转换(Numeric Type Conversion)#
  • 整型的转换(Integer Conversion)
    当然,整形的存储是不能超过类型的范围的,那UInt8(0255)和Int8(-128127)为例:
let cannotBeNegative: UInt8 = -1
//UInt8 cannot store negative numbers, and so this will report an error.
let tooBig: Int8 = Int8.max + 1
//Int8 cannot store a number larger than its maximum value,
//and so this will also report an error

当两种数值不是一个类型的时候是不能进行运算的,哪怕他们都是“整型”:

let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let towThousandAndOne = twoThousand + UInt16(one)
//swift的强制转换和OC是不同的,swift是将类型放在括号外面,而将变量(常量)放在括号里面。
  • 整型和浮点型之间的相互转换(Integer and Floating-Point Conversion)
    在整型和浮点型之间转换一定要明确:
let three = 3
let pointOneFourOneFiveNine = 0.141459
let pi = Double(three) + pointOneFourOneFiveNine
// pi equals 3.14159, and is inferred to be of type Double
类型的别称(Type Aliases)

类型的重命名用到的是"typealias"关键字。

typealias AudioSample = UInt16
//correct
let max: AudioSample = AudioSample.max
//wrong
let max: AudioSample = UInt16.max
布尔型(Boolean)

Swift中的布尔型与C语言和OC都不一样,为"Bool",而其值和C语言是一直的,分别为"true"和"false"。
因为type safety的缘故,下面的代码是错误的

let i = 1
if i {
    //this example will not compile, and will repot an error
}

所以,这段代码应该这么写:

let i = 1
if i == 1 {
    //this example will compile successfully
}

因为"i == 1"的返回值是Bool,所以这段代码可以执行。

元组(Tuples)

元组就是一组多个值合成为一个单一的值,而这一组的多个值并不是一定要相同的类型。
🌰:

let http404Error = (404, "Not Found")
//http404Error is of type (Int, String)

你可以在创建一个元组的时候任意的排序类型。
你也可以在定义一个元组的时候,将类型分离,🌰:

let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
//Prints "The status code is 404"

如果你只需要为元组中的某个元素命名是,其他的可以用下划线(_)代替:

let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// Prints "The status code is 404"

你也可以通过访问元组的索引值来访问相应的元素:

print("The status code is \(http200Status.statusCode)")
// Prints "The status code is 200"
print("The status message is \(http200Status.description)")
// Prints "The status message is OK"

在定义一个元组的时候,就可以为每个元素命名,这样就可以直接通过元素名称来访问:

let http200Status = (statusCode: 200, description: "OK")

print("The status code is \(http200Status.statusCode)")
// Prints "The status code is 200"
print("The status message is \(http200Status.description)")
// Prints "The status message is OK"
可选变量(Optionals)#

在C语言和OC中是没有optionals的概念的,但在OC中有一个类似的类型就是NSNil。Optionals通俗点讲,就是这个值可能存在,也可能不存在。举个🌰:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber is inferred to be of type "Int?", or "optional Int"
  • nil
    在声明一个变量的时候可以分配一个特殊的值——nil:
var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value

在声明一个可选变量的时候不赋给初始值,默认为nil(数值类型的值同样为nil)。

  • 可选绑定(Optional Binding)
    可选绑定,如果一个可选变量的值不为nil,则将值赋给另外一个变量(常量)。可选绑定可以用在if和while的判断条件中。🌰:
if let actualNumber = Int(possibleNumber) {
        print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
        print("\"\(possibleNumber)\" could not be converted to an integer")
}
// Prints ""123" has an integer value of 123"

你可以在一个if判断条件中包含多个可选绑定和"where"子句来进行判断,如果其中有任意一个可选绑定为空(nil),或者"where"的返回值为"false",整个可选绑定都会不成功:

if let firstNumber = Int("4"), secondNumber = Int("42") where irstNumber < secondNumber {
        print("\(firstNumber) < \(secondNumber)")
}
// Prints "4 < 42"
  • 隐式解析可选类型(Implicitly Unwrapped Optional)(也不知道是不是叫这个名字)
    有些变量在声明的时候就已经有值了,如果还是每次都判断是否为空就会非常低效,所以就有了这个Implicity Unwrapped Optional类型,意思就是我声明的这个变量不为空,用感叹号表示(!)。
    下面这个🌰展示了Optionals和Implicity Unwrapped Optional的区别:
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark

同样的,你可以判断隐式解析可选类型是否为空(nil),也可以进行可选绑定。
🌰:

if assumedString != nil {
    print(assumedString)
}
// Prints "An implicitly unwrapped optional string."
if let definiteString = assumedString {
    print(definiteString)
}
// Prints "An implicitly unwrapped optional string."
异常处理(Error Handling)

当一个方法遇到错误情况,它就会抛出(throws)一个错误。而方法的调用者就会捕捉(catch)到错误信息,并及时处理。

func canThrowAnError() throws {
    //this function may or may not throw an error
}

当一个方法可以抛出错误的时候在它声明方法名的时候要包括"throws"关键字。当你调用一个可以抛出错误的方法时,在前面用"try"关键字来修饰。
Swift会自动将错误信息从当先这个范围传递出去,知道会遇到"catch"子句的时候才会进行处理。

do {
    try canThrowAnError()
    //no error was thrown
} catch {
    //an error was thrown
}

"do"状态创建了一个新的可以允许错误信息传递给一个或者多个"catch"子句的包含范围。
🌰:

func makeASandwich() throws {
// ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}

上面这个🌰中,"makeASandewich()"将会在没有干净盘子的时候执行"washDishes()"。之所以"makeASandwich()"可以抛出一个错误,是因为这个方法包含了"try"表达式。如果没有错误抛出,那么"eatASandwich()"这个方法就会执行。

  • 断言(Assertions)
    在某些情况下,如果一个特定的条件不满足,那么代码就不会继续执行。在这些情况下,你可以在你的代码中设置一个断言(asserttion)来结束代码的执行或者提供一个调试值为空或者不存在的机会。

    • 用断言进行调试(Debug with Assertions)
      assertion会在runtime检查一个Boolean表达式的值是否为true。字面的意思就是,一个assertion"断言"一个表达式是否为真。如果表达式的值为true,那么代码会照常执行,如果表达式的值为false,代码执行结束,app会直接终止。
      但你在调试情况下使用assertions,可以附加一条自己的信息。在Swift标准库中,调用"assert(::file:line:)"方法,这是一个全球变量:
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
//this causes the assertion to trigger, because age is not >= 0

assertions的信息也可以省略。

assert(age >= 0)
  • 什么时候使用断言(When to Use Assertions)
    使用assertions首先要确保表达是的值有可能为false,但是想要代码继续执行的话,值一定为true。以下几种情况适用assertions:
    • 一个整数下标索引值传到了一个自定义的下标实现,而值超出了范围(太小或太大)。
    • 给函数传入一个值,但是非法的值可能导致函数不能正常执行。
    • 一个可选值现在为nil,但是代码需要一个不为nil的值才能成功执行。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容