Swift学习第一枪
1常量和变量常量和变量把一个名字和一个指定类型的值关联起来。常量的值一旦设定就不能改变,而变量的值可以随意更改。 1.1声明常量和变量常量和变量必须在使用前声明,用 let 来声明常量,用 var 来声明变量。 let maximumNumberOfLoginAttempts = 10//允许的最大尝试登录次数 var currentLoginAttempt = 0//当前尝试登录次数 这两行代码可以被理解为: 你可以在一行中声明多个常量或者多个变量,用逗号隔开: var x = 1.0,y = 2.0,z = 3.0 var x = 12,y = 22,z = 32 1.2类型的标注当你声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类 这个例子给 welcomeMessage 变量添加了类型标注,表示这个变量可以存储 String 类型的值: var welcomeMessage: String **声明中的冒号代表着“是…类型”,所以这行代码可以被理解为: welcomeMessage = "Hello" 你可以在一行中定义多个同样类型的变量,用逗号分割,并在最后一个变量名之后添加类型标注: var red,green,blue: Double 注意: 1.3常量和变量的命名你可以用任何你喜欢的字符作为常量和变量名,包括 Unicode 字符: let π = 3.14159 let 你好 = "你好世界" let ?? = "dogcow" 常量与变量名不能包含数学符号,箭头,保留的(或者非法的)Unicode 码位,连线与制表符。也不能以数字开 一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类 注意: 你可以更改现有的变量值为其他同类型的值,在下面的例子中, friendlyWelcome 的值从 “Hello!” 改为了 “Bonj var friendlyWelcome = "Hello!" friendlyWelcome = "Bonjour!" // friendlyWelcome 现在是 “Bonjour!” let languageName = "Swift" languageName = "Swift++" // 这会报编译时错误 - languageName 不可改变 1.4输出常量和变量你可以用 print(_:separator:terminator:) 函数来输出当前常量或变量的值: print(friendlyWelcome) // 输出 “Bonjour!” **注意:**Swift 用字符串插值(string interpolation)的方式把常量名或者变量名当做占位符加入到长字符串中,Swift 会 print("The current value of friendlyWelcome is (friendlyWelcome)") // 输出 "The current value of friendlyWelcome is Bonjour! 2.注释2.1 单行注释Swift 中的注释与C 语言的注释非常相似。单行注释以双正斜杠( // )作为起始标记: // 这是一个注释 2.2 行多行注释,其起始标记为单个正斜杠后跟随一个星号( /* ),终止标记为一个星号后跟随单个正斜杠( */ ): /* 这是一个,多行注释 */ 2.3 Swift 的多行注释可以嵌套在其它的多行注释之中/* 这是第一个多行注释的开头 /* 这是第二个被嵌套的多行注释 */ 这是第一个多行注释的结尾 */ 3 分号Swift 并不强制要求你在每条语句的结尾处使用分号( ; ),当然,你也可以按照你自己的习惯添加分号。有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句: let cat = "?"; print(cat);var title :String; // 输出 "?" 4 整数整数就是没有小数部分的数字,比如 42 和 -23 。整数可以是 有符号 (正、负、零)或者 无符号 (正、零)。 4.1整数范围你可以访问不同整数类型的 min 和 max 属性来获取对应类型的最小值和最大值: let minValue = UInt8.min // minValue 为 0,是 UInt8 类型 let maxValue = UInt8.max // maxValue 为 255,是 UInt8 类型 min 和 max 所传回值的类型,正是其所对的整数类型(如上例UInt8,所传回的类型是UInt8),可用在表达式中 4.2 Int一般来说,你不需要专门指定整数的长度。Swift 提供了一个特殊的整数类型 Int ,长度与当前平台的原生字长相 ? 在32位平台上, Int 和 Int32 长度相同。 ? 在64位平台上, Int 和 Int64 长度相同。 除非你需要特定长度的整数,一般来说使用 Int 就够了。这可以提高代码一致性和可复用性。即使是在32位平台 4.3UIntSwift 也提供了一个特殊的无符号类型 UInt ,长度与当前平台的原生字长相同: ? 在32位平台上, UInt 和 UInt32 长度相同。 ? 在64位平台上, UInt 和 UInt64 长度相同。 注意: 5.浮点数浮点数是有小数部分的数字,比如 3.14159 , 0.1 和 -273.15 。 ? Double 表示64位浮点数。当你需要存储很大或者很高精度的浮点数时请使用此类型。 ? Float 表示32位浮点数。精度要求不高的话可以使用此类型。 注意: Double 精确度很高,至少有15位数字,而 Float 最少只有6位数字。选择哪个类型取决于你的代码需要处理的 6.类型安全和类型推断Swift 是一个类型安全(type safe)的语言。类型安全的语言可以让你清楚地知道代码要处理的值的类型。如果你的代码需要一个 String ,你绝对不可能不小心传进去一个 Int 。由于 Swift 是类型安全的,所以它会在编译你的代码时进行类型检查(type checks),并把不匹配的类型标记 当你要处理不同类型的值时,类型检查可以帮你避免错误。然而,这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型,Swift 会使用 类型推断 (type inference)来选择合适的类型。有了类型推断,编译器可以在编译代码的时候自动推断出表达式的类型。原理很简单,只要检查你赋的值即可。 因为有类型推断,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。常量和变量虽然需要明确类型,但是大部分工作并不需要你自己来完成。当你声明常量或者变量并赋初值的时候类型推断非常有用。当你在声明常量或者变量的时候赋给它们一个字面量(literal value 或 literal)即可触发类型推断。(字面量就是会直接出现在你代码中的值,比如 42 和 3.14159 。) let meaningOfLife = 42 // meaningOfLife 会被推测为 Int 类型 同理,如果你没有给浮点字面量标明类型,Swift 会推断你想要的是 Double : let pi = 3.14159 // pi 会被推测为 Double 类型 当推断浮点数的类型时,Swift 总是会选择 Double 而不是 Float 。 let anotherPi = 3 + 0.14159 // anotherPi 会被推测为 Double 类型 原始值 3 没有显式声明类型,而表达式中出现了一个浮点字面量,所以表达式会被推断为 Double 类型。 7.数值型字面量整数字面量可以被写作: ? 一个十进制数,没有前缀 ? 一个二进制数,前缀是 0b ? 一个八进制数,前缀是 0o ? 一个十六进制数,前缀是 0x 下面的所有整数字面量的十进制值都是 17 : let decimalInteger = 17 let binaryInteger = 0b10001 // 二进制的17 let octalInteger = 0o21 // 八进制的17 let hexadecimalInteger = 0x11 // 十六进制的17 浮点字面量可以是十进制(没有前缀)或者是十六进制(前缀是 0x )。小数点两边必须有至少一个十进制数 let decimalDouble = 12.1875 let exponentDouble = 1.21875e1 let hexadecimalDouble = 0xC.3p0 数值类字面量可以包括额外的格式来增强可读性。整数和浮点数都可以添加额外的零并且包含下划线,并不会影 let paddedDouble = 000123.456 let oneMillion = 1_000_000 let justOverOneMillion = 1_000_000.000_000_1 8.数值型类型转换通常来讲,即使代码中的整数常量和变量已知非负,也请使用 Int 类型。总是使用默认的整数类型可以保证你的 8.2整数转换不同整数类型的变量和常量可以存储不同范围的数字。 Int8 类型的常量或者变量可以存储的数字范围是 -12 let cannotBeNegative: UInt8 = -1 // UInt8 类型不能存储负数,所以会报错 let tooBig: Int8 = Int8.max + 1 // Int8 类型不能存储超过最大值的数,所以会报错 由于每种整数类型都可以存储不同范围的值,所以你必须根据不同情况选择性使用数值型类型转换。这种选择性 SomeType(ofInitialValue) 是调用 Swift 构造器并传入一个初始值的默认方法。在语言内部, UInt16 有一个构 8.3整数和浮点数转换整数和浮点数的转换必须显式指定类型: let three = 3 let pointOneFourOneFiveNine = 0.14159 let pi = Double(three) + pointOneFourOneFiveNine // pi 等于 3.14159,所以被推测为 Double 类型 这个例子中,常量 three 的值被用来创建一个 Double 类型的值,所以加号两边的数类型须相同。如果不进行转 let integerPi = Int(pi) // integerPi 等于 3,所以被推测为 Int 类型 当用这种方式来初始化一个新的整数值时,浮点值会被截断。也就是说 4.75 会变成 4 , -3.9 会变成 -3 。 9类型别名类型别名(type aliases)就是给现有类型定义另一个名字。你可以使用 typealias 关键字来定义类型别名。 typealias AudioSample = UInt16 定义了一个类型别名之后,你可以在任何使用原始名的地方使用别名: var maxAmplitudeFound = AudioSample.min // maxAmplitudeFound 现在是 0 本例中, AudioSample 被定义为 UInt16 的一个别名。因为它是别名, AudioSample.min 实际上是 UInt16.mi 10 布尔值(Bool)Swift 有一个基本的布尔(Boolean)类型,叫做 Bool 。布尔值指逻辑上的值,因为它们只能是真或者假。Swift 有两个布尔常量, true 和 false : let orangesAreOrange = true let turnipsAreDelicious = false orangesAreOrange 和 turnipsAreDelicious 的类型会被推断为 Bool ,因为它们的初值是布尔字面量。就像之前提到的 Int 和 Double 一样,如果你创建变量的时候给它们赋值 true 或者 false ,那你不需要将常量或者变量声明为 Bool 类型。初始化常量或者变量的时候如果所赋的值类型已知,就可以触发类型推断,这让 Swift 代码更加简洁并且可读性更高。当你编写条件语句比如 if 语句的时候,布尔值非常有用: if turnipsAreDelicious { print("Mmm,tasty turnips!") } else { print("Eww,turnips are horrible.") } // 输出 "Eww,turnips are horrible." 条件语句,例如 if let i = 1 if i { // 这个例子不会通过编译,会报错 } 然而,下面的例子是合法的: let i = 1 if i == 1 { // 这个例子会编译成功 } i == 1 的比较结果是 Bool 类型,所以第二个例子可以通过类型检查。类似 i == 1 这样的比较.和 Swift 中的其他类型安全的例子一样,这个方法可以避免错误并保证这块代码的意图总是清晰的。 11.元组元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。 let http404Error = (404,"Not Found") // http404Error 的类型是 (Int,String),值是 (404,"Not Found") (404,“Not Found”) 元组把一个 Int 值和一个 String 值组合起来表示 HTTP 状态码的两个部分:一个数字和一 你可以把任意顺序的类型组合成一个元组,这个元组可以包含所有类型。只要你想,你可以创建一个类型为 (Int,I let (statusCode,statusMessage) = http404Error print("The status code is (statusCode)") // 输出 "The status code is 404" print("The status message is (statusMessage)") // 输出 "The status message is Not Found" 如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线( _ )标记: let (justTheStatusCode,_) = http404Error print("The status code is (justTheStatusCode)") // 输出 "The status code is 404" 此外,你还可以通过下标来访问元组中的单个元素,下标从零开始: print("The status code is (http404Error.0)") // 输出 "The status code is 404" print("The status message is (http404Error.1)") // 输出 "The status message is Not Found" 你可以在定义元组的时候给单个元素命名: print("The status code is (http200Status.statusCode)") // 输出 "The status code is 200" print("The status message is (http200Status.description)") // 输出 "The status message is OK" 作为函数返回值时,元组非常有用。一个用来获取网页的函数可能会返回一个 (Int,String) 元组来描述是否获取 10.可选类型10.1nil你可以给可选变量赋值为 nil 来表示它没有值: var serverResponseCode: Int? = 404 // serverResponseCode 包含一个可选的 Int 值 404 serverResponseCode = nil // serverResponseCode 现在不包含值 注意: 11.错误处理你可以使用错误处理(error handling)来应对程序执行中可能会遇到的错误条件。 func canThrowAnErrow() throws { // 这个函数有可能抛出错误 } 一个函数可以通过在声明中添加 throws 关键词来抛出错误消息。当你的函数能抛出错误消息时,你应该在表达式 do { try canThrowAnErrow() // 没有错误消息抛出 } catch { // 有一个错误消息抛出 } 一个 do 语句创建了一个新的包含作用域,使得错误能被传播到一个或多个 catch 从句。 func makeASandwich() throws { // ... } do { try makeASandwich() eatASandwich() } catch Error.OutOfCleanDishes { washDishes() } catch Error.MissingIngredients(let ingredients) { buyGroceries(ingredients) } 在此例中, makeASandwich() (做一个三明治)函数会抛出一个错误消息如果没有干净的盘子或者某个原料缺 如果没有错误被抛出,eatASandwich() 函数会被调用。如果一个匹配 Error.OutOfCleanDishes 的错误被抛出,washDishes 函数会被调用。如果一个匹配 Error.MissingIngredients 的错误被抛出,buyGroceries(_:) 函数会随着被 catch 所捕捉到的关联值 [String] 被调用。抛出,捕捉,以及传播错误会在错误处理。 学习地址 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |