├── README.md ├── 2.2基本运算符.playground ├── contents.xcplayground ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangq01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── Contents.swift ├── 2.4集合类型.playground ├── contents.xcplayground ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangq01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── Contents.swift ├── 2.5控制流.playground ├── contents.xcplayground ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangq01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── Contents.swift ├── 2.8枚举.playground ├── contents.xcplayground ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangq01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── timeline.xctimeline └── Contents.swift ├── 2.9类和结构体.playground ├── contents.xcplayground ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangq01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── Contents.swift ├── 2.3 字符串和字符.playground ├── contents.xcplayground ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangq01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── timeline.xctimeline └── Contents.swift ├── 2.6-2.7函数闭包.playground ├── contents.xcplayground ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangq01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── timeline.xctimeline └── Contents.swift ├── MyPlayground.playground ├── contents.xcplayground ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangq01.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── timeline.xctimeline └── Contents.swift └── FoundationSection.playground ├── contents.xcplayground ├── playground.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── wangq01.xcuserdatad │ └── UserInterfaceState.xcuserstate └── Contents.swift /README.md: -------------------------------------------------------------------------------- 1 | # Swift 2 | 有目标,沉住气,踏实干。 3 | You are very nice. 4 | -------------------------------------------------------------------------------- /2.2基本运算符.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2.4集合类型.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2.5控制流.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2.8枚举.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2.9类和结构体.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2.3 字符串和字符.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2.6-2.7函数闭包.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MyPlayground.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2.5控制流.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /2.8枚举.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FoundationSection.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2.2基本运算符.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /2.3 字符串和字符.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /2.4集合类型.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /2.6-2.7函数闭包.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /2.9类和结构体.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MyPlayground.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FoundationSection.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /2.5控制流.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/2.5控制流.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /2.8枚举.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/2.8枚举.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /2.2基本运算符.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/2.2基本运算符.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /2.4集合类型.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/2.4集合类型.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /2.9类和结构体.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/2.9类和结构体.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /2.3 字符串和字符.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/2.3 字符串和字符.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /2.6-2.7函数闭包.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/2.6-2.7函数闭包.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /MyPlayground.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/MyPlayground.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /FoundationSection.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wq469775163/SWIFT_Study/HEAD/FoundationSection.playground/playground.xcworkspace/xcuserdata/wangq01.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /2.8枚举.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /2.3 字符串和字符.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /2.6-2.7函数闭包.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 15 | 16 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /2.9类和结构体.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | 7 | /* 8 | 问题:与 Objective-C 语言不同的是,Swift 允许直接设置结构体属性的子属性。上面的最后一个例子,就是直接设置了someVideoMode中resolution属性的width这个子属性,以上操作并不需要重新为整个resolution属性设置新值。(直接设置结构体属性的子属性) 9 | 10 | Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件。你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口。 11 | 通常一个类的实例被称为对象 12 | 13 | 类和结构体对比 14 | struct Resolution { 15 | var width = 0 16 | var height = 0 17 | } 18 | class VideoMode { 19 | var resolution = Resolution() 20 | var interlaced = false 21 | var frameRate = 0.0 22 | var name: String? 23 | } 24 | 1.UpperCamelCase这种方式来命名 owerCamelCase这种方式为属性和方法命名 25 | 2.属性写上初始化默认值,或者可选类型也行的,就像set方法重写(变量存储属性) 26 | let someResolution = Resolution() 27 | let someVideoMode = VideoMode() 28 | 生成结构体和类实例的语法非常相似:构造器语法的最简单形式是在结构体或者类的类型名称后跟随一对空括号,如Resolution()或VideoMode()。通过这种方式所创建的类或者结构体实例,其属性均会被初始化为默认值。(类名+()) 29 | 通过使用点语法,你可以访问实例的属性。其语法规则是,实例名后面紧跟属性名,两者通过点号(.)连接 30 | 结构体类型的成员逐一构造器: let vga = Resolution(width:640, height: 480)(只是结构体) 31 | 32 | 33 | 结构体和枚举是值类型 34 | 值类型被赋予给一个变量、常量或者被传递给一个函数参数的时候,其值会被拷贝。(不同的实例,里面的数据碰巧一样) 35 | 整数(Integer)、浮点数(floating-point)、布尔值(Boolean)、字符串(string)、数组(array)和字典(dictionary),都是值类型 36 | 37 | 类是引用类型 引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝 38 | 需要注意的是tenEighty和alsoTenEighty被声明为常量而不是变量。然而你依然可以改变tenEighty.frameRate和alsoTenEighty.frameRate,因为tenEighty和alsoTenEighty这两个常量的值并未改变。它们并不“存储”这个VideoMode实例,而仅仅是对VideoMode实例的引用。所以,<改变的是被引用的VideoMode的frameRate属性>,而不是引用VideoMode的常量的值 39 | 40 | 恒等运算符 41 | 等价于(===) 42 | 不等价于(!==) 43 | 检测两个常量或者变量是否引用同一个类实例 44 | let tenEighty = VideoMode() 45 | let alsoTenEighty = tenEighty 46 | if tenEighty === alsoTenEighty { 47 | print("tenEighty and alsoTenEighty refer to the same Resolution instance.") 48 | } 49 | //打印 "tenEighty and alsoTenEighty refer to the same Resolution instance." 50 | 51 | 这意味着绝大部分的自定义数据构造都应该是类,而非结构体 52 | 53 | Swift 中,许多基本类型,诸如String,Array和Dictionary类型均以结构体的形式实现。这意味着被赋值给新的常量或变量,或者被传入函数或方法中时,它们的值会被拷贝。 54 | Objective-C 中NSString,NSArray和NSDictionary类型均以类的形式实现,而并非结构体。它们在被赋值或者被传入函数或方法时,不会发生值拷贝,而是传递现有实例的引用。 55 | 以上是对字符串、数组、字典的“拷贝”行为的描述。在你的代码中,拷贝行为看起来似乎总会发生。然而,Swift 在幕后只在绝对必要时才执行实际的拷贝。Swift 管理所有的值拷贝以确保性能最优化,所以你没必要去回避赋值来保证性能最优化。 56 | */ 57 | 58 | struct Resolute { 59 | var width = 0 60 | var height = 0 61 | } 62 | 63 | let hd = Resolute(width :100, height: 200) 64 | 65 | var cime = hd 66 | cime.width = 8888 67 | 68 | print(hd.width) 69 | print(cime.width) 70 | 71 | -------------------------------------------------------------------------------- /2.5控制流.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | /* 7 | For-In 循环 8 | for _ in 1...power { 9 | answer *= base 10 | } 11 | 当前理解为 下划线符号_(替代循环中的变量)能够忽略当前值,就是不提供遍历时对值的访问 12 | 13 | While 循环 14 | while循环,每次在循环开始时计算条件是否符合; 15 | repeat-while循环,每次在循环结束时计算条件是否符合。 16 | 17 | 条件语句 18 | If else 和OC C一样的用法 19 | Switch:switch判断的什么类型,case可能的类型就是相同的类型 20 | default分支来匹配除了a和z外的所有值,这个分支“保证了swith语句的完备性”。 21 | 不存在“隐式的贯穿” :不需要在 case 分支中显式地使用break语句。每一个 case 分支都必须包含至少一条语句。 22 | 区间匹配 23 | 元组:目前的理解是前提条件是在元组中,(_,1)使用下划线(_)来匹配所有可能的值 24 | 值绑定(Value Bindings):case分支允许将匹配的值绑定一个临时常量或变量,并且在case分支中使用。 25 | Where case分支的模式可以使用where语句来判断额外的条件。 26 | 复合匹配 case分支允许多种情况,只要满足一种就进去(或)。保证类型都是相同的。 27 | 28 | 控制转移语句 29 | continue 30 | break 31 | fallthrough 32 | return 33 | throw 34 | 35 | 提前退出 36 | 37 | 检测 API 可用性 38 | */ 39 | 40 | let finalSquare = 25 41 | 42 | var board: [Int] = Array(repeatElement(0, count: finalSquare + 1)) 43 | board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02 44 | board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08 45 | var square = 0 46 | var diceRoll = 0 47 | repeat { 48 | square += board[square] 49 | diceRoll += 1 50 | if diceRoll == 7 { 51 | diceRoll = 1 52 | } 53 | square += diceRoll 54 | } while square < finalSquare 55 | // 实际上,在这个例子中,点(0, 0)可以匹配所有四个 case。但是,如果存在多个匹配,那么只会执行第一个被匹配到的 case 分支。考虑点(0, 0)会首先匹配case (0, 0),因此剩下的能够匹配的分支都会被忽视掉。 56 | let somePoint = (1,0) 57 | switch somePoint { 58 | case (0,0): 59 | print("One") 60 | case (_,0): 61 | print("Two") 62 | case (-2...2, -1...1): 63 | print("Three") 64 | default: 65 | print("Other") 66 | } 67 | 68 | let(code,name) = ("A","B") 69 | print("\(code)") 70 | 71 | let anotherPoint = (2, 1) 72 | switch anotherPoint { 73 | case (let x, 0): 74 | print("on the x-axis with an x value of \(x)") 75 | case (0, let y): 76 | print("on the y-axis with a y value of \(y)") 77 | case let (x, y): 78 | print("somewhere else at (\(x), \(y))") 79 | default: 80 | print("Oher") 81 | } 82 | 83 | func greet(person: [String: String]){ 84 | 85 | guard let name = person["name"] else { 86 | return 87 | } 88 | print("Hello \(name)") 89 | 90 | } 91 | 92 | greet(person: ["name": "John"]) 93 | 94 | 95 | if #available(iOS 10, *) { 96 | 97 | }else{ 98 | 99 | } 100 | 101 | -------------------------------------------------------------------------------- /2.8枚举.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | 7 | 8 | /* 9 | 问题1:递归枚举的走法不懂 10 | 枚举语法 11 | enum Compasspoint { 12 | // 枚举定义放在这里 13 | } 14 | a:枚举名字大写 15 | b:枚举的成员值(枚举的成员):枚举定义的值(north、south之类的都是) 16 | c:和C OC不同,枚举原始值不会被赋值为默认的整数类型 17 | d:var direction: Compasspoint = Compasspoint.west(var direction = Compasspoint.west) 18 | 19 | 使用 Switch 语句匹配枚举值 20 | 主要是关于switch语法的 a:switch 判断的什么类型,case中选择的就是相同的类型。 21 | b: switch的case分支中必须把所有的类型都要判断全(default:其他类型就好)。 22 | C: case .west: 23 | 24 | 关联值 25 | a:枚举的成员值upc具有(Int,Int,Int,Int)类型的关联值 26 | b:创建了一个名为productB的变量,并将Barcode.upc赋值给它,关联的元组值为(8, 85909, 51226, 3)。 27 | c:productB 同一时间只能存储两个值中的一个 28 | d: case .qrCode(let code): switch的case分支中可以提取每个关联值作为一个常量或变量。简介(case let .upc(A,B,C,D):) 29 | 30 | 原始值 31 | 原始值和关联值是不同的。原始值是在定义枚举时被预先填充的值,像上述三个 ASCII 码。对于一个特定的枚举成员,它的原始值始终不变。关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化。 32 | 当使用整数作为原始值时,隐式赋值的值依次递增1。如果第一个枚举成员没有设置原始值,其原始值将为0 33 | 当使用字符串作为枚举类型的原始值时,每个枚举成员的隐式原始值为该枚举成员的名称。 34 | 使用原始值初始化枚举实例: let possiblePlanet = Planet(rawValue: 7)这个方法接收一个叫做rawValue的参数(参数名),参数类型即为原始值类型,返回值则是枚举成员或nil(可选类型,有7就有值,没有7就是nil) 35 | 36 | 37 | 递归枚举:说实话没看懂,我需要敲一下例子 38 | */ 39 | enum Compasspoint { 40 | case north 41 | case south 42 | case east 43 | case west 44 | } 45 | 46 | var direction = Compasspoint.west 47 | direction = .north 48 | 49 | enum Barcode { 50 | case upc(Int,Int,Int,Int) 51 | case qrCode(String) 52 | } 53 | 54 | var productB = Barcode.upc(12, 23, 56, 89) 55 | //productB = .qrCode("AHJKHJHUUIHII") 56 | 57 | switch productB { 58 | //case Barcode.upc(let number, let B, let C, let D): 59 | // print("\(number)==\(B)") 60 | case .qrCode(let code): 61 | print("\(code)") 62 | case let .upc(A,B,C,D): 63 | print("==\(B)") 64 | } 65 | 66 | indirect enum ArithExpression { 67 | case number(Int) 68 | case addition(ArithExpression,ArithExpression) 69 | case multicaotion(ArithExpression,ArithExpression) 70 | } 71 | 72 | let five = ArithExpression.number(5) 73 | let four = ArithExpression.number(4) 74 | let sum = ArithExpression.addition(five, four) 75 | let product = ArithExpression.multicaotion(sum, ArithExpression.number(2)) 76 | 77 | // ArithExpression这个跟String、Int 一样啊,你传的时候传实例“3”、3 之类的 78 | func evaluate(_ expression: ArithExpression) -> Int { 79 | 80 | switch expression { 81 | case let.number(value): 82 | return value 83 | case let .addition(left, right): 84 | return evaluate(left) + evaluate(right) 85 | case let .multicaotion(left, right): 86 | return evaluate(left) * evaluate(right) 87 | } 88 | } 89 | let result = evaluate(product) 90 | 91 | print(result) 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /2.2基本运算符.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | /* 7 | 问题: 8 | 1.没法names.count直接?说白了就是forin不理解 9 | let names:[String] = ["Ane","Box","Cat","Dog"] 10 | let count = names.count 11 | 12 | for index in 0..< names.count = { 13 | print(index) 14 | } 15 | 这样也是不行的,那我等到去forin去解决了,目前专注当前规定的任务 16 | for index in names = { 17 | print(index) 18 | } 19 | 术语 20 | 运算符分为一元、二元和三元运算符: 21 | 一元运算符对单一操作对象操作(如 -a)。一元运算符分前置运算符和后置运算符,前置运算符需紧跟在操作对象之前(如 !b),后置运算符需紧跟在操作对象之后(如 c!)。 22 | 二元运算符操作两个操作对象(如 2 + 3),是中置的,因为它们出现在两个操作对象之间。 23 | 三元运算符操作三个操作对象,和 C 语言一样,Swift 只有一个三元运算符,就是三目运算符(a ? b : c)。 24 | ‘受运算符影响的值叫操作数’,在表达式 1 + 2 中,加号 + 是二元运算符,它的两个操作数是值 1 和 2。 25 | 26 | 27 | 算术运算符 28 | Swift 中所有数值类型都支持了基本的四则算术运算符: 29 | 加法(+) 30 | 减法(-) 31 | 乘法(*) 32 | 除法(/) 33 | 加法运算符也可用于 String 的拼接: 34 | "hello, " + "world" // 等于 "hello, world" 35 | 36 | 37 | 求余运算符 38 | 1.-9%4 = -1 39 | 2.在对负数 b 求余时,b 的符号会被忽略。这意味着 a % b 和 a % -b 的结果是相同的。 40 | 41 | 42 | 比较运算符(Comparison Operators) 43 | 所有标准 C 语言中的比较运算符都可以在 Swift 中使用: 44 | 等于(a == b) 45 | 不等于(a != b) 46 | 大于(a > b) 47 | 小于(a < b) 48 | 大于等于(a >= b) 49 | 小于等于(a <= b) 50 | 每个比较运算都返回了一个标识表达式是否成立的布尔值: 51 | 1 == 1 // true, 因为 1 等于 1 52 | 元组可以比较的 53 | 1.比较元组大小会按照从左到右、逐值比较的方式,直到发现有两个值不等时停止。如果所有的值都相等,那么这一对元组我们就称它们是相等的 (1, "zebra") < (2, "apple") // true,因为 1 小于 2 54 | 2.Bool 不能被比较,也意味着存有布尔类型的元组不能被比较。 55 | 3.Swift 标准库只能比较七个以内元素的元组比较函数。如果你的元组元素超过七个时,你需要自己实现比较运算符。 56 | 57 | 58 | 空合运算符(Nil Coalescing Operator) 59 | 空合运算符(a ?? b)将对可选类型a进行空判断,如果a包含一个值就进行解封,否则就返回一个默认值b.这个运算符有两个条件: 60 | 表达式a必须是Optional类型 61 | 默认值b的类型必须要和a存储值的类型保持一致 62 | a != nil ? a! : b 63 | 上述代码使用了三目运算符。当可选类型 a 的值不为空时,进行强制解封(a!),访问 a 中的值;反之返回默认值 b。无疑空合运算符(??)提供了一种更为优雅的方式去封装条件判断和解封两种行为,显得简洁以及更具可读性。 64 | 65 | 66 | 区间运算符(Range Operators) 67 | 闭区间运算符(a...b)定义一个包含从 a 到 b(包括 a 和 b)的所有值的区间。a 的值不能超过 b。 ‌ 闭区间运算符在迭代一个区间的所有值时是非常有用的,如在 for-in 循环中: 68 | 半开区间运算符(a.. 2 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 25 | 26 | 30 | 31 | 35 | 36 | 40 | 41 | 46 | 47 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /2.3 字符串和字符.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | /* 7 | 问题: 8 | 1.每一个字符串都是由编码无关的 Unicode 字符组成,并支持访问字符的多种 Unicode 表示形式(representations)。 9 | 2.for index in greeting.characters.indices { 10 | print("\(greeting[index])") 11 | } for in 不是太理解,包含全部索引的范围(Range) 12 | 3.字符串的 Unicode 表示形式 这部分没懂,先过去把。再读文档也是浪费时间效率低 13 | 14 | 15 | 16 | 定义:字符串是例如"hello, world","albatross"这样的有序的Character(字符)类型的值的集合,通过String类型来表示。 17 | 18 | 1.初始化空字符串 19 | 要创建一个空字符串作为初始值,可以将空的字符串字面量赋值给变量(常量也行),也可以初始化一个新的String实例: 20 | 您可以通过检查其Bool类型的isEmpty属性来判断该字符串是否为空: 21 | let emptyString = "" 22 | var anotherEmptyString = String() 23 | if emptyString.isEmpty { 24 | print("Nothing to see here") 25 | 26 | 2.字符串是值类型 27 | Swift 的String类型是值类型。 如果您创建了一个新的字符串,那么当其进行常量、变量赋值操作,或在函数/方法中传递时,会进行值拷贝。 任何情况下,都会对已有字符串值创建新副本,并对该新副本进行传递或赋值操作 28 | 您可通过for-in循环来遍历字符串中的characters属性来获取每一个字符的值: 29 | 通过标明一个Character类型并用字符字面量进行赋值,可以建立一个独立的字符常量或变量 let exclaMark:Character = "!" 30 | 字符串可以通过传递一个值类型为Character的数组作为自变量来初始化: 31 | 您可以用append()方法将一个字符(字符串)附加到一个字符串变量的尾部. 32 | 注意:您不能将一个字符串或者字符添加到一个已经存在的字符变量上,因为字符变量只能包含一个字符。 33 | 34 | 3 Unicode 标量 35 | Swift 的String类型是基于 Unicode 标量 建立的。 Unicode 标量是对应字符或者修饰符的唯一的21位数字 36 | 字符串字面量可以包含以下特殊字符: 37 | 转义字符\0(空字符)、\\(反斜线)、\t(水平制表符)、\n(换行符)、\r(回车符)、\"(双引号)、\'(单引号)。 38 | Unicode 标量,写成\u{n}(u为小写),其中n为任意一到八位十六进制数且可用的 Unicode 位码。 39 | let blackHeart = "\u{2665}" 字符串字面量包括unicode标量 40 | 可扩展的字形群集 41 | 每一个 Swift 的Character类型代表一个可扩展的字形群。 42 | 43 | 4 访问和修改字符串 44 | 4.1 字符串索引 不同的字符可能会占用不同数量的内存空间,Swift 的字符串不能用整数(integer)做索引。 45 | 使用startIndex属性可以获取一个String的第一个Character的索引。使用endIndex属性可以获取最后一个Character的后一个位置的索引。因此,endIndex属性不能作为一个字符串的有效下标。如果String是空串,startIndex和endIndex是相等的。 46 | 通过调用 String 的 index(before:) 或 index(after:) 方法,可以立即得到前面或后面的一个索引。您还可以通过调用 index(_:offsetBy:) 方法来获取对应偏移量的索引, 47 | eg:greeting[greeting.startIndex] 48 | 4.2 插入和删除 (insert插入的是字符类型 remove这个两个关键字) 49 | 您可以使用 insert(_:at:)、insert(contentsOf:at:)、remove(at:) 和 removeSubrange(_:) 方法在任意一个确认的并遵循 RangeReplaceableCollection 协议的类型里面,如上文所示是使用在 String 中,您也可以使用在 Array、Dictionary 和 Set 中。 50 | 51 | 5.比较字符串 52 | Swift 提供了三种方式来比较文本值:字符串字符相等、前缀相等和后缀相等 53 | 字符串/字符可以用等于操作符(==)和不等于操作符(!=) 54 | 通过调用字符串的hasPrefix(_:)/hasSuffix(_:)方法来检查字符串是否拥有特定前缀/后缀,两个方法均接收一个String类型的参数,并返回一个布尔值,布尔值所以一般和if一起用 55 | 56 | */ 57 | let emptyString = "" 58 | var anotherEmptyString = String() 59 | if emptyString.isEmpty { 60 | print("Nothing to see here") 61 | } 62 | for character in "Dog!🐶".characters { 63 | print(character) 64 | } 65 | 66 | let exclaMark:Character = "!" 67 | 68 | let catCharacter: [Character] = ["C","a","t","y"] 69 | let catString = String(catCharacter) 70 | print(catString) 71 | 72 | var welcome:String = "qwe" 73 | 74 | let exMark:Character = "!" 75 | 76 | welcome.append(catString) 77 | 78 | let mul = 3; 79 | let message = "\(mul) wwwww" 80 | 81 | let wisewords = "\"Imagination is more important than knowledge\" - Einstein" 82 | 83 | let dollarSign = "\u{2665}" 84 | 85 | 86 | 87 | let greeting = "Guten Tag!" 88 | greeting[greeting.startIndex] 89 | greeting[greeting.index(before: greeting.endIndex)] 90 | 91 | greeting[greeting.index(greeting.startIndex, offsetBy: 6)] 92 | 93 | 94 | for index in greeting.characters.indices { 95 | print("\(greeting[index])") 96 | } 97 | 98 | 99 | var welcomeStr = "hello" 100 | welcomeStr.insert("!", at: welcomeStr.endIndex) 101 | welcomeStr.insert(contentsOf: " world".characters, at: welcomeStr.index(before: welcomeStr.endIndex)) 102 | 103 | welcomeStr.remove(at: welcomeStr.index(before: welcomeStr.endIndex)) 104 | print(welcomeStr) 105 | 106 | welcomeStr.removeSubrange(welcomeStr.index(welcomeStr.endIndex, offsetBy: -6)..() 创建和构造一个空的集合 91 | 2. var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"] 和数组一样的 92 | 3.使用布尔属性isEmpty作为一个缩写形式去检查count属性是否为0:和数组一样的 93 | 4.insert remove (如果该值是该Set的一个元素则删除该元素并且返回被删除的元素值,否则如果该Set不包含该值,则返回nil) 94 | removeAll() 95 | << 96 | 5. if favoriteGenres.contains("Funk") 97 | 6. 98 | for genre in favoriteGenres { 99 | print("\(genre)") 100 | } 101 | 7.for genre in favoriteGenres.sorted() { 102 | print("\(genre)") 103 | } 104 | Swift 的Set类型没有确定的顺序,为了按照特定顺序来遍历一个Set中的值可以使用sorted()方法,它将返回一个有序数组,这个数组的元素排列顺序由操作符'<'对元素进行比较的结果来确定.(和数组的enumerate) 105 | >> 106 | 集合操作 107 | 基本集合操作(具体还是看图吧,记住是通过两个集合的比较““创建””一个新的集合) 108 | 集合成员关系和相等 (也是看图吧,记住是比较两个集合返回BOOL值) 109 | 110 | 111 | 字典 112 | Swift 的Dictionary类型被桥接到Foundation的NSDictionary类。 113 | isEmpty count 和set array一样的 114 | 1.airports["LHR"] = "London" // airports 字典现在有三个数据项 115 | airports["LHR"] = "London Heathrow" 116 | // "LHR"对应的值 被改为 "London Heathrow 117 | airports["LHR"] 如果没有key就在键值对,有key就更新键值对 118 | 2.updateValue(_:forKey:)方法在这个键不存在对应值的时候会设置新值或者在存在时更新已存在的值(对字典的作用,一样有就更新,没有就添加),返回一个可选类型的旧值。(有就存在,没有就是nil,反正就是可选类型) 119 | if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") 120 | if let airportName = airports["DUB"] 121 | 都是一样的。 airports["DUB"] airports.updateValue("Dublin Airport", forKey: "DUB")更新字典,返回都是可选类型,update有值就是旧值,索引就不存在旧值不旧值,就是取出来的值。 122 | 使用下标语法来通过给某个键的对应值赋值为nil来从字典里移除一个键值对 123 | airports["APL"] = nil // APL对应的键值对现在被移除了 124 | if let removedValue = airports. removeValue(forKey: "DUB") 125 | removeValue(forKey:)方法也可以用来在字典中移除键值对。这个方法在键值对存在的情况下会移除该键值对并且返回被移除的值或者在没有值的情况下返回nil: 126 | 字典遍历 127 | for (airportCode, airportName) in airports { 128 | print("\(airportCode): \(airportName)") 129 | } 130 | 我们可以使用for-in循环来遍历某个字典中的键值对。每一个字典中的数据项都以(key, value)元组形式返回,并且我们可以使用临时常量或者变量来分解这些元组: 131 | for airportCode in airports.keys { 132 | print("Airport code: \(airportCode)") 133 | } 134 | let airportCodes = [String](airports.keys) 135 | // airportCodes 是 ["YYZ", "LHR"] 136 | 如果我们只是需要使用某个字典的键集合或者值集合来作为某个接受Array实例的 API 的参数,可以直接使用keys或者values属性构造一个新数组 137 | Swift 的字典类型是无序集合类型。为了以特定的顺序遍历字典的键或值,可以对字典的keys或values属性使用sorted()方法。(无序到有序) 138 | */ 139 | 140 | 141 | 142 | let characterArray: [Character] = ["A","B","C","D"] 143 | 144 | for index in characterArray { 145 | print("\(index)") 146 | } 147 | 148 | var someInts = [Int]() 149 | someInts.append(3) 150 | someInts = [] 151 | var strAppend:String = "ww" 152 | strAppend.append("3") 153 | var someIntsTwo:[Int] = [] 154 | 155 | var threeDoubles = Array(repeating: 2.0, count: 3) 156 | var shoppingList = ["A","B","C","D","E","F",6] as [Any] 157 | for item in shoppingList { 158 | print(item) 159 | } 160 | 161 | for (index,value) in shoppingList.enumerated() { 162 | print("Item \(index + 1): \(value)") 163 | } 164 | 165 | 166 | var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"] 167 | airports["LHR"] = "London" 168 | print(airports) 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /2.6-2.7函数闭包.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | 7 | 8 | /* 9 | 函数(Functions) 10 | 11 | 问题1:在 Swift 中,每个函数都有一个由函数的参数值类型和返回值类型组成的类型。你可以把函数类型当做任何其他普通变量类型一样处理,这样就可以更简单地把函数当做别的函数的参数,也可以从其他函数中返回函数。函数的定义可以写在其他函数定义中,这样可以在嵌套函数范围内实现功能封装。 12 | 13 | func sum(a: Int, b: Int) -> Int { 14 | return a + b 15 | } 16 | 没有返回值的函数,一共有三种写法 17 | 省略 18 | () 19 | Void 20 | 21 | 闭包 定义个一个闭包:闭包 = {(形参) -> 返回类型 in 代码实现} 22 | let sumFunc = {(num1: Int, num2: Int) -> Int in return num1 + num2 23 | } 24 | 最简单的闭包,如果没有参数/返回值,则 参数/返回值/in 统统都可以省略 25 | { 代码实现 } 26 | 27 | 函数的定义与调用 28 | (名词:参数,返回类型,调用函数传实参,函数名:greet(),greet(person:)) 29 | greet(person:)和greet(person:alreadGreeted:)这两个函数是不同的,虽然它们都有着同样的名字greet,但是greet(person:alreadyGreeted:)函数需要两个参数,而greet(person:)只需要一个参数 30 | 当你定义一个函数时,你可以定义一个或多个有名字和类型的值,作为函数的输入,称为参数,也可以定义某种类型的值作为函数执行结束时的输出,称为返回类型。 31 | 32 | 全局函数。嵌套函数。 33 | 34 | 35 | 闭包 36 | 闭包的表达式 37 | 内联闭包:调用函数(方法)传的函数类型的参数 38 | */ 39 | 40 | func greet(person: String) -> (String) { 41 | let greeting = "Hello," + person + "!" 42 | return greeting 43 | 44 | } 45 | 46 | // 函数的定义和调用 47 | func addTwoInt(_ a: Int, _ b: Int) -> Int 48 | { 49 | return a + b 50 | } 51 | 52 | //调用函数 addTwoInt(name:) addTwoInt(_:_:) 53 | 54 | 55 | // 定义一个函数类型的常量或者变量,并把合适的函数赋值给他 56 | var leftFunc: (Int,Int) -> Int = addTwoInt 57 | // 函数的调用 58 | leftFunc(5,52) 59 | 60 | // 定义一个Int的常量或者变量,并把函数返回值赋值给他 61 | // addTwoInt(2, 6)这就是函数调用,因为传入具体的参数值了 62 | let resultNum: Int = addTwoInt(2, 6) 63 | print(resultNum) 64 | 65 | 66 | func resultNot(name: String) { 67 | print("\(name)") 68 | } 69 | 70 | let cont = resultNot(name: "555") 71 | print(cont) 72 | 73 | 74 | func printResult(_ addFunc: (Int, Int) -> Int, _ a: Int, _ b: Int) { 75 | print("传入a,b的值作为函数的参数,就像创建一个函数类型常量,并把相同函数类型的函数赋值给常量\(addFunc(a,b))") 76 | } 77 | // leftFunc 和 addTwoInt 肯定是一样的 78 | printResult(leftFunc, 5, 66) 79 | 80 | 81 | func stepForward(_ input: Int) -> Int { 82 | return input + 1 83 | } 84 | 85 | func stepBackward(_ input: Int) -> Int { 86 | return input - 1 87 | } 88 | 89 | func chooseFunc(_ back: Bool) -> (Int) -> Int { 90 | return back ? stepForward : stepBackward 91 | } 92 | 93 | var value = 3 94 | 95 | let name1: (Int) -> Int = chooseFunc(value>0) 96 | name1(value) 97 | 98 | 99 | let name = greet(person: "Tony") 100 | 101 | //http://www.jb51.net/article/95663.htm 102 | // 形势1:闭包的声明最标准不省略 103 | //1.闭包的声明,返回类型()可以省略 104 | var addCloser: (_ num1: Int,_ num2: Int) -> (Int) 105 | 106 | //2.闭包的赋值 107 | addCloser = { 108 | (_ num1: Int, _ num2: Int) -> Int in 109 | return num1 + num2 110 | 111 | } 112 | //3.闭包的调用 113 | let result = addCloser(2,3) 114 | print(result) 115 | 116 | 117 | // 形式2 省略闭包声明中的形参名,闭包赋值中的返回值 (声明的时候可以用个类型,赋值的时候在写名字,返回值也可以不写) 118 | let addCloser1: (Int, Int) -> (Int) 119 | 120 | addCloser1 = { 121 | (num1, num2) in 122 | return num1 + num2 123 | } 124 | 125 | addCloser1(23,45) 126 | 127 | // 形式3 在形式2的基础之上进一步精简 128 | let addcloser3: (Int, Int) -> Int = 129 | { 130 | (num1, num2) in 131 | return num1 + num2 132 | } 133 | addcloser3(22,555) 134 | 135 | //形式4:如果闭包没有接收参数省略in 136 | let addcloser4:() -> String = { 137 | return "这个闭包没有参数,但有返回值" 138 | } 139 | 140 | //形式5:简写的实际参数名 141 | let addCloser5: (String,String) -> String = { 142 | return "闭包的返回值是\($0),\($1)" 143 | } 144 | // $0 和 $1 分别是闭包的第一个和第二个 String类型的 实际参数 145 | addCloser5("Hello","Swift") 146 | 147 | 148 | 149 | //场景二:闭包作为函数的参数 150 | 151 | func combin(handel: (String,String) -> String,num: Int) { 152 | 153 | handel("2","3") 154 | print("hello,Swift\(num)") 155 | } 156 | combin(handel: {(str1,str2) -> (String) in 157 | return str1 + str2 158 | }, num: 5) 159 | 160 | 161 | // 闭包在函数定义里面调用 162 | func combin1(handel: () -> Void,num: Int) { 163 | 164 | handel() 165 | print("hello,Swift45646\(num)") 166 | } 167 | // 函数的调用,将一个闭包表达式作为一个参数传递给闭包 168 | combin1(handel: { 169 | print("可以了456456") 170 | }, num: 5) 171 | 172 | // 一,尾随闭包 173 | func combin1(num: Int,handel:(String,String) -> String) { 174 | print("hello Swwift\(num)") 175 | } 176 | 177 | combin1(num: 5, handel: {(str1,str2) -> String in 178 | return str1 + str2 179 | }) 180 | 181 | combin1(num: 20156) { (text1,text2) -> (String) in 182 | return text1 + text2 183 | } 184 | 185 | // sorted方法 186 | 187 | let names = ["A","B","E","Z","C","A"] 188 | 189 | 190 | func backward(_ s1: String, _ s2: String) -> Bool { 191 | return s1 > s2 192 | } 193 | let names1 = names.sorted(by: backward) 194 | 195 | let names2 = names.sorted { (s1, s2) -> Bool in 196 | return s1 < s2 197 | } 198 | 199 | // 值捕获 200 | 201 | func makeIncrementer(forIncrementer amount: Int) -> () -> Int { 202 | var runningTotal = 0 203 | // 嵌套函数(闭包)在其被定义从上下文捕获了两个值,amount 和 runningTotal 204 | func increamenter() -> Int { 205 | runningTotal += amount 206 | return runningTotal 207 | } 208 | return increamenter 209 | 210 | } 211 | 212 | // 只是将这些常量或者变量的值设置为对应函数或闭包的引用 213 | let increamentByTen = makeIncrementer(forIncrementer: 10) 214 | 215 | increamentByTen() 216 | increamentByTen() 217 | increamentByTen() 218 | 219 | /* 220 | 如果我们单独考虑嵌套函数 incrementer(),会发现它有些不同寻常: 221 | 222 | func incrementer() -> Int { 223 | runningTotal += amount 224 | return runningTotal 225 | } 226 | ncrementer() 函数并没有任何参数,但是在函数定义体内访问了 runningTotal 和 amount 变量,这是因为它从外围函数捕获了 runningTotal 和 amount 变量的引用。捕获引用保证了 runningTotal 和 amount 变量在调用完 makeIncrementer 后不会消失,并且保证了在下一次执行 incrementer 函数时,runningTotal 依旧存在. 227 | */ 228 | 229 | // 引用传递,常量C值传递给D值之后(D对象的所有属性值和C相等),改变C会影响D,因为他们指向同一个对象(class类型,闭包类型) 230 | // 值传递 改变C不影响D,他们是不同的对象(结构体,数组,字典) 231 | 232 | 233 | // 常量C传递给D 234 | let alsoIncreamentByTen = increamentByTen 235 | alsoIncreamentByTen() 236 | 237 | 238 | 239 | 240 | // 闭包的调用在哪里啊,朋友 241 | let closures: (String,String) -> String = { 242 | (name1,name2) in return name1 + name2 243 | } 244 | closures("2","6") 245 | 246 | 247 | var comletionHandle: () -> String = { 248 | "约吗?" 249 | } 250 | // 返回“单纯的函数名“,不是调用。 251 | func doSomeThing2(some: @escaping ()->String) { 252 | comletionHandle = some 253 | } 254 | doSomeThing2{ 255 | return "叔叔号" 256 | } 257 | print(comletionHandle()) 258 | 259 | 260 | 261 | 262 | var completionHandlers: [() -> Void] = [] 263 | func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) { 264 | completionHandlers.append(completionHandler) 265 | } 266 | func someFunctionWithNonescapingClosure(closure: () -> Void) { 267 | closure() 268 | } 269 | 270 | class SomeClass { 271 | var x = 10 272 | func doSomething() { 273 | someFunctionWithEscapingClosure { self.x = 100 } 274 | someFunctionWithNonescapingClosure { x = 200 } 275 | } 276 | } 277 | 278 | let instance = SomeClass() 279 | instance.doSomething() 280 | print(instance.x) 281 | 282 | // 闭包的调用 283 | completionHandlers.first?() 284 | print(instance.x) 285 | 286 | 287 | var arr = ["A","B","C","D","E"] 288 | print(arr.count) 289 | 290 | let customer = {()->String in arr.remove(at: 0)} 291 | 292 | print("\(customer())") 293 | 294 | // 和函数是一样的 295 | 296 | 297 | -------------------------------------------------------------------------------- /FoundationSection.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | /* 7 | 问题 8 | 1 一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,意思是我在不同类中名字是唯一的吗?就行所谓的宏定义。 9 | 2 项目中先声明let var之类的,提示_代替那就是每次都这么声明,不会这么傻逼吧 10 | 3 类型别名 typealias 一个新的名字,怎么和原来的产生联系呢,就是类型别名的具体用法 11 | 4 如果你需要在变量的生命周期中判断是否是nil的话,请使用普通可选类型。那个生命周期什么生命周期?那么举例中的if nil 呢? 12 | 5 do catch catch具体判断条件到具体章节再去做详细学习 13 | 14 | 1.0常量和变量 15 | 常量和变量把一个名字(比如 maximumNumberOfLoginAttempts 或者 welcomeMessage )和一个指定类型的值(比如数字 10 或者字符串 "Hello" )关联起来“”。常量的值一旦设定就不能改变,而变量的值可以随意更改。 16 | 1.1声明常量和变量 17 | 常量和变量必须在使用前声明,用 let 来声明常量,用 var 来声明变量。 18 | 你可以在一行中声明多个常量或者多个变量,用逗号隔开: 19 | var x = 1.0, y = 0.0, z = 1.2 20 | 如果你的代码中有不需要改变的值,请使用 let 关键字将它声明为常量。只将需要改变的值声明为变量。(养成好的代码习惯) 21 | 22 | 2.0类型标注 23 | 当你声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类型。如果要添加类型标注,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称。 24 | 你可以在一行中定义多个同样类型的变量,用逗号分割,并在最后一个变量名之后添加类型标注:var red, grren, blue: Double(这个在变量常量是可以的) 25 | 一般来说你很少需要写类型标注。 26 | 27 | 3.0 常量和变量的命名 28 | 一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类型。同时,你也不能将常量与变量进行互转。 29 | 30 | 4.0 输出常量和变量 字符串插值 31 | Swift 用字符串插值(string interpolation)的方式把常量名或者变量名当做占位符加入到长字符串中,Swift 会用当前常量或变量的值替换这些占位符。将常量或变量名放入圆括号中,并在开括号前使用反斜杠将其转义 32 | 33 | 5.0 分号 34 | 与其他大部分编程语言不同,Swift 并不强制要求你在每条语句的结尾处使用分号(;),当然,你也可以按照你自己的习惯添加分号。有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句:let cat = "🐶"; print(cat) 35 | 36 | 6.0 整数 37 | 整数就是没有小数部分的数字,比如 42 和 -23 。整数可以是 有符号(正、负、零)或者 无符号(正、零)。 38 | 39 | Swift 提供了8,16,32和64位的有符号和无符号整数类型。这些整数类型和 C 语言的命名方式很像,比如8位无符号整数类型是UInt8,32位有符号整数类型是 Int32 。就像 Swift 的其他类型一样,整数类型采用大写命名法。 40 | 你可以访问不同整数类型的 min 和 max 属性来获取对应类型的最小值和最大值: 41 | 42 | let minValue = UInt8.min // minValue 为 0,是 UInt8 类型 43 | let maxValue = UInt8.max // maxValue 为 255,是 UInt8 类型 44 | 一般来说,你不需要专门指定整数的长度。Swift 提供了一个特殊的整数类型Int,长度与当前平台的原生字长相同: 45 | Swift 也提供了一个特殊的无符号类型 UInt,长度与当前平台的原生字长相同:尽量不要使用UInt 46 | 47 | 7.0 浮点数 48 | 浮点类型比整数类型表示的范围更大,可以存储比 Int 类型更大或者更小的数字。Swift 提供了两种有符号浮点数类型:Double表示64位浮点数。Float表示32位浮点数。Double精确度很高,至少有15位数字,而Float只有6位数字。选择哪个类型取决于你的代码需要处理的值的范围,在两种类型都匹配的情况下,将优先选择 Double。 49 | 50 | 8.0 类型安全和类型推断(记住名词) 51 | 当推断浮点数的类型时,Swift 总是会选择 Double 而不是Float。 52 | 53 | 9.0 数值型字面量 54 | 字面量 let str = "Hello World" 字面量就是Hello World 55 | let decimalInteger = 17 56 | let binaryInteger = 0b10001 // 二进制的17 57 | let octalInteger = 0o21 // 八进制的17 58 | let hexadecimalInteger = 0x11 // 十六进制的17 59 | 数值类字面量可以包括额外的格式来增强可读性。整数和浮点数都可以添加“额外的零并且包含下划线”,并不会影响字面量: 60 | let justOverOneMillion = 1_000_000.000_000_1 61 | 62 | 10.0数值型类型转换 63 | swift 值永远不会被隐式转换为其他类型。如果你需要把一个值转换成其他类型,请显式转换。 64 | 在C、Objective-C和Java等其他语言中,整型之间有两种转换方法: 65 | 从小范围数到大范围数转换是自动的;(编译器自动完成) 66 | 从大范围数到小范围数需要强制类型转换,有可能造成数据精度的丢失 67 | 10.1 整数转换 68 | SomeType(ofInitialValue) 是调用 Swift 构造器并传入一个初始值的默认方法。注意,你并不能传入任意类型的值,只能传入 UInt16 内部有对应构造器的值。不过你可以扩展现有的类型来让它可以接收其他类型的值(包括自定义类型)类名+()()中初始化 69 | 10.2 整数和浮点数转换 70 | swift 值永远不会被隐式转换为其他类型。如果你需要把一个值转换成其他类型,请显式转换。记住这句话就行了 71 | 72 | 11.0 类型别名 73 | 类型别名(type aliases)就是给现有类型定义另一个名字。你可以使用typealias关键字来定义类型别名。 74 | 12.0 布尔值 75 | Swift中一个布尔类型 Bool,两个布尔常量 true and false 76 | 77 | 13.0 元组 78 | 元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。元组在临时组织值的时候很有用,但是并不适合创建复杂的数据结构。如果你的数据结构并不是临时使用,请使用类或者结构体而不是元组。 79 | let http404Error = (404,"Not Found") 80 | let http200Error = (statusCode: 200,description: "OK") 81 | let (code,message) = http404Error 82 | let (codeRedef,_) = http404Error 83 | print("wp\(code)") 84 | print("xiabiaois\(http404Error.1)") 85 | print("mingis\(http200Error.statusCode)") 86 | 87 | 14.0 可选类型 88 | 可选类型表示: 89 | 有值,等于 x 90 | 或者 91 | 没有值 92 | Swift 的 nil 和 Objective-C 中的 nil 并不一样。在 Objective-C 中,nil 是一个指向不存在对象的指针。在 Swift 中,nil 不是指针——它是一个确定的值,用来表示值缺失。 93 | 任何类型的可选状态都可以被设置为 nil,不只是对象类型。OC中nil只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型,Objective-C 方法一般会返回一个特殊值(比如NSNotFound)来暗示值缺失。 94 | 如果你的代码中有常量或者变量需要处理值缺失的情况,请把它们声明成对应的可选类型。 nil不能用于非可选的常量和变量。 95 | var serverResponseCode: Int? = 404 serverResponseCode是个可选类型,并且包括一个可选值404 96 | 如果你声明一个可选常量或者变量但是没有赋值,它们会自动被设置为 nil 97 | var surveyAnswer: String? 98 | 99 | 15.0 if 语句以及可选值强制解析 100 | 你可以使用 if 语句和 nil 比较来判断一个可选值是否包含值。你可以使用“相等”(==)或“不等”(!=)来执行比较。if convertedNumber != nil {} 101 | 当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(!)来获取值。这个惊叹号表示“我知道这个可选有值,请使用它。”这被称为可选值的强制解析(forced unwrapping) 102 | print("convertedNumber \(convertedNumber) ") log输出 convertedNumber Optional("contain") 103 | print("convertedNumber \(convertedNumber!) ")log输出 104 | convertedNumber contain 105 | 106 | 16.0 可选绑定 107 | 使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量 108 | if let name = someOptional { 109 | } 110 | 可以这样朋友 if let firstNumber = Int("4"), let secondNumber = Int("52") {} 111 | 112 | 17.0 隐式解析可选类型 (第一次赋值之后确定之后一直有值) 113 | 当可选类型被第一次赋值之后就可以确定之后一直有值的时候,隐式解析可选类型非常有用。 114 | 一个隐式解析可选类型其实就是一个普通的可选类型,但是可以被当做非可选类型来使用,并不需要每次都使用解析来获取可选值。 115 | let possibleString: String? = "An optional string." 116 | let forcedString: String = possibleString! // 需要感叹号来获取值 117 | 118 | let assumedString: String! = "An implicitly unwrapped optional string." 119 | let implicitString: String = assumedString // 不需要感叹号 120 | 你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。 121 | 你仍然可以把隐式解析可选类型当做普通可选类型来判断它是否包含值:if nil 122 | 你也可以在可选绑定中使用隐式解析可选类型来检查并解析它的值: if let name = someOptional {} 123 | 如果一个变量之后可能变成nil的话请不要使用隐式解析可选类型。如果你需要在变量的生命周期中判断是否是nil的话,请使用普通可选类型。 124 | 125 | 18 错误处理 126 | 1.采用Error协议的类型来表示错误。do try catch 进去throws函数有throw抛出就进去catch可选的内容,do函数下面的代码不走了,没有throw抛出,do函数继续走下面的代码 127 | 2.另一种处理错误的方式使用try?将结果转换为可选的。如果函数抛出错误,该错误会被抛弃并且结果为nil。否则的话,结果会是一个包含函数返回值的可选值。(是个可选类型,并且包含一个可选值job send) 128 | enum PrinterError: Error 129 | { 130 | case outofPaper 131 | case noToner 132 | case onFire 133 | } 134 | 135 | // 使用空格throws来表示一个可以抛出错误的函数 136 | func send(job: Int, toPriter prinerName: String) throws -> String 137 | { 138 | if prinerName == "Never Has Toner" { 139 | // 使用throw来抛出一个错误 140 | throw PrinterError.noToner 141 | } 142 | 143 | return "Job sent" 144 | } 145 | 146 | do { 147 | try send(job: 22, toPriter: "Never Has Toner1") 148 | print("jixuzou") 149 | } catch { 150 | print(error) 151 | } 152 | 153 | 19.0 断言 154 | 注意:当代码使用优化编译的时候,断言将会被禁用,例如在 Xcode 中,使用默认的 target Release 配置选项来 build 时,断言会被禁用。 155 | 如果条件判断为 true,代码运行会继续进行;如果条件判断为 false,代码执行结束,你的应用被终止。 156 | let age = -3 157 | assert(age >= 0, "A person's age cannot be less than zero") 158 | // 因为 age < 0,所以断言会触发 159 | 何时使用断言: 160 | 整数类型的下标索引被传入一个自定义下标实现,但是下标索引值可能太小或者太大。 161 | 需要给函数传入一个值,但是非法的值可能导致函数不能正常执行。 162 | 一个可选值现在是 nil,但是后面的代码运行需要一个非 nil 值。 163 | 164 | */ 165 | let uminValue = UInt8.min 166 | let umaxValue = UInt8.max 167 | 168 | let minValue = Int8.min 169 | let maxValue = Int8.max 170 | 171 | typealias uminValueRedef = Int8 172 | 173 | let http404Error = (404,"Not Found") 174 | let http200Error = (statusCode: 200,description: "OK") 175 | let (code,message) = http404Error 176 | let (codeRedef,_) = http404Error 177 | print("wp\(code)") 178 | print("xiabiaois\(http404Error.1)") 179 | print("mingis\(http200Error.statusCode)") 180 | let (code1,message1) = (4041,"ww") 181 | print("wp\(code1)") 182 | 183 | var convertedNumber: String? = "contain" 184 | if convertedNumber != nil { 185 | print("convertedNumber \(convertedNumber!) ") 186 | } 187 | 188 | if let action = convertedNumber { 189 | print("pppppp \(action)") 190 | } 191 | else{ 192 | print("notFound") 193 | } 194 | 195 | if let firstNumber = Int("4"), let secondNumber = Int("52") { 196 | 197 | } 198 | 199 | if let firstNumberRedef = Int("4") 200 | { 201 | print(firstNumberRedef) 202 | } 203 | 204 | 205 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /MyPlayground.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: Playground - noun: a place where people can play 2 | 3 | import UIKit 4 | 5 | var str = "Hello, playground" 6 | var str1 = "Hello, playground" 7 | print(str) 8 | for index in 1...5 9 | { 10 | print(index) 11 | } 12 | 13 | // 简单值 14 | //使用let来声明常量,使用var来声明变量。常量只能赋值一次,变量可以赋值很多次。 15 | let num: Float = 70.0 16 | let num1: Double = 50 17 | var firstVariable:NSInteger = 50; 18 | firstVariable = 55 19 | let num2:Float = 4 20 | 21 | /* 22 | 1.swift 值永远不会被隐式转换为其他类型。如果你需要把一个值转换成其他类型,请显式转换。 23 | 在C、Objective-C和Java等其他语言中,整型之间有两种转换方法: 24 | 从小范围数到大范围数转换是自动的;(编译器自动完成) 25 | 从大范围数到小范围数需要强制类型转换,有可能造成数据精度的丢失 26 | 有一种更简单的把值转换成字符串的方法:把值写到括号中,并且在括号之前写一个反斜杠。 27 | 2.使用方括号[]来创建数组和字典,并使用下标或者键(key)来访问元素。最后一个元素后面允许有个逗号。 28 | let emptyArray1: [String] = [] 29 | */ 30 | 31 | let label = "The width is " 32 | let width = 96 33 | let widthLabel = label + String(width) 34 | 35 | let apples: NSInteger = 3 36 | let applesSummary = "I have \(apples) apples." 37 | 38 | let numMoney: Double = 20.00 39 | let spearkToTom = "I Have \(numMoney) money" 40 | 41 | var shoppingList: [NSString] = ["catfish","water","blue","red",] 42 | shoppingList[1] = "again Value" 43 | print(shoppingList) 44 | 45 | var Diction = [ 46 | "key1": "value1", 47 | "key2": "value2" 48 | ] 49 | print(Diction) 50 | 51 | let emptyArray = [String]() 52 | let emptyDictionary = [String:NSInteger]() 53 | 54 | let emptyArray1: [String] = [] 55 | 56 | shoppingList = [] 57 | print(shoppingList) 58 | Diction = [:] 59 | 60 | 61 | // 控制流 62 | /* 63 | 1.使用if和switch来进行条件操作,使用for-in、for、while和repeat-while来进行循环。包裹条件和循环变量括号可以省略,但是语句体的大括号是必须的。在if语句中,条件必须是一个布尔表达式——这意味着像if score { ... }这样的代码将报错,而不会隐形地与 0 做对比。 64 | 65 | 66 | var serverResponseCode: Int? = 404 67 | serverResponseCode 包含一个可选的 Int 值 404 68 | 69 | serverResponseCode = nil 70 | serverResponseCode 现在不包含值 71 | 72 | 你可以一起使用if和let来处理值缺失的情况。 73 | 2. ?? 74 | 空合运算符(a ?? b)将对可选类型a进行空判断,如果a包含一个值就进行解封,否则就返回一个默认值b.这个运算符有两个条件: 75 | 76 | 表达式a必须是Optional类型 77 | 默认值b的类型必须要和a存储值的类型保持一致 78 | 79 | 3. switch支持任意类型的数据以及各种比较操作——不仅仅是整数以及测试相等。 80 | 运行switch中匹配到的子句之后,程序会退出switch语句,并不会继续向下运行,所以不需要在每个子句结尾写break。(自己直接跳出这个循环了) 81 | 4.你可以使用for-in来遍历字典,需要两个变量来表示每个键值对。字典是一个无序的集合,所以他们的键和值以任意顺序迭代结束。 82 | 5.while repeat while (do while)... ..< 83 | */ 84 | let ListArray:[NSInteger] = [75,28,43,55,66] 85 | var score = 50 86 | 87 | for index in ListArray 88 | { 89 | if index < 50 90 | { 91 | score += 3 92 | } 93 | else 94 | { 95 | score += 5 96 | } 97 | } 98 | print(score) 99 | 100 | var optionalString: String? = "Hello" 101 | print(optionalString == nil) 102 | 103 | var optionName: String? 104 | 105 | var greeting = "Hello!" 106 | //如果变量的可选值是nil,条件会判断为false,大括号中的代码会被跳过。如果不是nil,会将值解包并赋给let后面的常量,这样代码块中就可以使用这个值了。 107 | if let name = optionName 108 | { 109 | greeting = "hello,\(name)" 110 | } 111 | else 112 | { 113 | greeting = "no select Value" 114 | } 115 | print(greeting) 116 | 117 | let nickName: String? = nil 118 | let fullName: String = "John Appleseed" 119 | let allInformation = "hi \(nickName ?? fullName)" 120 | 121 | let vegetable = "red pepper" 122 | switch vegetable 123 | { 124 | case "red": 125 | print("redred") 126 | case "black": 127 | print("black") 128 | case "red pepper": 129 | print("red pepperred pepper") 130 | default: 131 | print("hihihi") 132 | } 133 | 134 | let interestingNumber:[String: [NSInteger]] = [ 135 | "A":[2,5,7,9], 136 | "B":[5,8,9,46,101], 137 | "C":[2,3,100] 138 | ] 139 | var largest1 = 0 140 | var largestkind = "A" 141 | 142 | // 没理解 143 | for (kinds,numbers) in interestingNumber 144 | { 145 | // 取出来其中的一项而已,不是总的数组 146 | print(kinds,numbers) 147 | for number in numbers 148 | { 149 | if number > largest1 150 | { 151 | largest1 = number 152 | largestkind = kinds 153 | } 154 | } 155 | 156 | } 157 | print(largest1,largestkind) 158 | 159 | 160 | var n = 2 161 | while n < 100 162 | { 163 | n = n * 2 164 | } 165 | print(n) 166 | 167 | var m = 2 168 | repeat 169 | { 170 | m = m * 2 171 | }while m < 100 172 | 173 | print(m) 174 | 175 | var total: NSInteger = 0 176 | for index in 0...4 177 | { 178 | total += index 179 | } 180 | print(total) 181 | 182 | /* 183 | 函数和闭包 184 | 使用func来声明一个函数,使用名字和参数来调用函数。使用->来指定函数返回值的类型。 使用 _ 表示不使用参数标签。 185 | func funcName(person:String, day:String) -> String 186 | { 187 | return "Hello \(person),today is \(day)." 188 | } 189 | 1.1默认情况下,函数使用它们的参数名称作为它们参数的标签,在参数名称前可以自定义参数标签 190 | 1.2 使用元组来让一个函数返回多个值。该元组的元素可以用名称或数字来表示。 191 | func calculateStatistics(score: [Int]) -> (min:Int,max:Int,sum:Int) 192 | 1.3 函数可以带有可变个数的参数,(调用的时候可以什么都不传)这些参数在函数内表现为数组的形式: 193 | 1.4 函数可以嵌套。被嵌套的函数可以访问外侧函数的变量,你可以使用嵌套函数来重构一个太长或者太复杂的函数。 194 | (调用这个函数返回一个函数,用一个变量去接收一下,这个变量其实是个函数,按照格式可以调用这个函数。) 195 | */ 196 | 197 | func funcName(person:String, day:String) -> String 198 | { 199 | return "Hello \(person),today is \(day)." 200 | } 201 | funcName(person: "Tom", day: "Thusday") 202 | 203 | func eatGoods(person:String,goods:String) -> String 204 | { 205 | return "Hello \(person),you eat \(goods)." 206 | } 207 | eatGoods(person: "Tom", goods: "MIle") 208 | 209 | func greet(_ person: String,wwww onday: String) -> String 210 | { 211 | return "Hello \(person),today is \(onday)" 212 | } 213 | greet("www", wwww: "hah") 214 | 215 | func sumOf(numbers:Int...) -> Int 216 | { 217 | var sum = 0 218 | for number in numbers 219 | { 220 | sum += number 221 | } 222 | return sum 223 | 224 | } 225 | sumOf() 226 | let sum = sumOf(numbers: 1,5,8,44) 227 | print(sum) 228 | 229 | func makeIncrementer () -> ((Int) -> Int) 230 | { 231 | func addOne(number : Int) -> Int 232 | { 233 | return 1 + number 234 | } 235 | return addOne 236 | } 237 | // 返回一个函数,用一个变量去接收一下,这个变量其实是个函数,按照格式可以调用这个函数。 238 | var increment = makeIncrementer() 239 | increment(7) 240 | //makeIncrementer(8) 241 | 242 | func hasAnyMatchs(list : [Int] , condition : ((Int) -> Bool)) -> Bool 243 | { 244 | for number in list 245 | { 246 | if condition(number) 247 | { 248 | return true 249 | } 250 | } 251 | return false 252 | } 253 | func lessThanTen(number: Int) -> Bool 254 | { 255 | return number < 10 256 | } 257 | var numbers = [21,16,58] 258 | 259 | 260 | numbers.map { (number : Int) -> Int in 261 | return number * 3 262 | } 263 | 264 | numbers.map { (numb:Int) -> Int in 265 | return numb * 9 266 | } 267 | 268 | numbers.map { (number:Int) -> Int in 269 | 270 | if number % 2 != 0 271 | { 272 | return 0 273 | } 274 | else 275 | { 276 | return 2 277 | } 278 | } 279 | /* 280 | 对象和类 281 | 问题 282 | 1:self被用于区别实例变量。 283 | 2: 如果你需要在删除对象之前进行一些清理工作,使用deinit创建一个析构函数。 284 | 3: super.init(name: name) 这个是什么意思,继承父类的name属性值?还是更改父类的name属性的值 285 | 4: self.radius = radius radius两个 V和L开头 286 | 5: set get 方法里面写的是的属性(其他属性)具体要怎么写?newValue是什么?set方法里面不实现出怎么样? 287 | 6: 如果你不需要计算属性,但是仍然需要在设置一个新值之前或者之后运行代码,使用willSet和didSet。 288 | 7: 处理变量的可选值时,你可以在操作(比如方法、属性和子脚本)之前加?。如果?之前的值是nil,?后面的东西都会被忽略,并且整个表达式返回nil。否则,?之后的东西都会被运行。在这两种情况下,整个表达式的值也是一个可选值。(这章简介基本上都没看会啊,朋友) 289 | 1.创建一个类:使用class和类名。类中属性的声明和常量、变量的声明一样,唯一的区别是他们的上下文是类。同样的类中方法声明和函数的声明也是一样的。创建一个类的实例:在类名后面加上括号。使用点语法来访问实例的属性和方法。 290 | 2.缺少一个构造函数来初始化类实例。使用init来创建一个构造器(init(),正常的参数名:参数类型-- 常量变量名:类型)。创建一个类的实例时候,就像传入函数的参数一样传入构造器的参数。每个属性都必须赋值( varnumberofSide:Int = 50 291 | var name: String 无论是通过声明(varnumberofSide)赋值还是通过构造器(name)赋值)。 292 | 3.子类的定义方法:在他们类名后面:父类的名字.可以忽略父类的.子类如果要重写父类的方法的话,需要用override标记——如果没有添加override就重写父类方法的话编译器会报错。编译器同样会检测override标记的方法是否确实在父类中。调用父类的构造器,然后可以修改父类定义的属性值。 293 | */ 294 | class Shape 295 | { 296 | var numbersides = 0 297 | let testClassPro = 20 298 | 299 | 300 | func simpleDescriptions() -> String 301 | { 302 | return "A shape with \(numbersides) sides" 303 | } 304 | 305 | func testClassMethod(number:NSInteger) -> String 306 | { 307 | return "A shape withparameter \(number + 2) sides" 308 | } 309 | 310 | } 311 | // 创建一个类的实例 312 | var shape = Shape() 313 | // 直接修改了。(不知道对不对等号左边set方法和OC类似?) 314 | shape.numbersides = 200 315 | var shapeDiscription = shape.simpleDescriptions() 316 | shape.testClassMethod(number: 22) 317 | 318 | class NameShape 319 | { 320 | var numberofSide:Int = 50 321 | var name: String 322 | init(name: String) 323 | { 324 | self.name = name 325 | } 326 | // 声明 327 | func simpleDescription() -> String 328 | { 329 | return "\(name) shape with \(numberofSide) sides" 330 | } 331 | } 332 | var nameShape = NameShape(name:"WQ") 333 | nameShape.simpleDescription() 334 | 335 | class SonShape: NameShape 336 | { 337 | var sonlenth: Double 338 | init(sonlenth: Double , name:String) 339 | { 340 | self.sonlenth = sonlenth 341 | super.init(name: name) 342 | numberofSide = 100; 343 | 344 | } 345 | 346 | func area() -> Double 347 | { 348 | return sonlenth * Double(numberofSide) 349 | } 350 | 351 | 352 | override func simpleDescription() -> String 353 | { 354 | return "Father override" 355 | } 356 | } 357 | var sonShape = SonShape(sonlenth: 5.2, name:"son") 358 | sonShape.sonlenth 359 | sonShape.area() 360 | sonShape.simpleDescription() 361 | nameShape.simpleDescription() 362 | 363 | 364 | class Circle: NameShape { 365 | 366 | var radius: Double 367 | var radiusName: String 368 | init(radius: Double,radiusName: String) { 369 | self.radius = radius 370 | self.radiusName = radiusName 371 | super.init(name: radiusName) 372 | 373 | } 374 | func area() -> Double 375 | { 376 | return radius * radius 377 | } 378 | 379 | override func simpleDescription() -> String 380 | { 381 | return "A B is \(radius)" 382 | } 383 | } 384 | 385 | var circle = Circle (radius: 25.0, radiusName: "name1") 386 | circle.area() 387 | circle.simpleDescription() 388 | 389 | class EquilateralTriangle: NameShape { 390 | 391 | var sideLength: Double = 0.0 392 | 393 | 394 | init(sideLength: Double, name: String) 395 | { 396 | self.sideLength = sideLength 397 | super.init(name: name) 398 | numberofSide = 3 399 | } 400 | 401 | var perimeter: Double 402 | { 403 | set { 404 | // sideLength = newValue / 3.0 405 | } 406 | 407 | get { 408 | return 3.0 * sideLength 409 | } 410 | } 411 | 412 | override func simpleDescription() -> String { 413 | return "An eque is \(sideLength)" 414 | } 415 | } 416 | 417 | var tra = EquilateralTriangle(sideLength: 3.1, name: "AAA") 418 | print(tra.perimeter) 419 | 420 | tra.perimeter = 2.2 421 | print(tra.perimeter) 422 | 423 | 424 | let opTionS :SonShape? = SonShape(sonlenth: 20.0, name: "WWW") 425 | 426 | 427 | /* 428 | 枚举和结构体 429 | 不懂: 430 | 1.使用init?(rawValue:)初始化构造器在原始值和枚举值之间进行转换。 431 | 2.success例子里面 case let .Result(sunrise, sunset) 判断。(目前的理解是这样的,你switch success也就是你被判断被比较的是枚举成员的实例,所以可能等于的情况也必须是相同的类型即枚举成员的实例) 432 | 433 | 1. let var success 枚举成员的实例,类的实例,类实例,类对象 (目前我理解为都是一样的,具体的var let接受的) 434 | 2.使用enum来创建一个枚举。就像类和其他所有命名类型一样,枚举可以包含方法。(里面的case用大写吧)使用rawVaule属性来访问枚举成员的原始值。枚举的成员值是实际值,并不是原始值的另一种表达方法。实际上,如果没有比较有意义的原始值,你就不需要提供原始值。已知变量类型的情况下你可以使用缩写(Suits.Spades == .Spades) 435 | 3.使用struct来创建一个结构体。结构体和类有很多相同的地方,比如方法和构造器。它们之间最大的一个区别就是结构体是传值,类是传引用。(类是相同的,结构体是独立的) 436 | 437 | 有这样两种传值方式:值传递和引用传递。假如,C值传递D之后,对C作改变不会影响D,因为D是另一个对象,只不过在一开始传了之后D对象的所有属性值和C相等。然后,引用传递的话,改变C会影响D,因为他们指向同一个对象。 438 | 439 | 对于class类型,是引用传递。对于struct是值传递。然后,像是数组,字典,这些他们都是struct,所以都是值传递。(也就是说我作业做的那样是不对的,会产生两份一样的数组) 440 | 441 | 442 | 443 | */ 444 | 445 | // 这是你以前OC写的枚举 446 | enum UITableViewScrollPosition: Int { 447 | case none 448 | case top 449 | case middle 450 | case bottom 451 | } 452 | enum Rank :Int 453 | { 454 | // 枚举成员(类实例) 455 | 456 | case Ace = 1 457 | case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten 458 | case Jack,Queen,King 459 | 460 | func simpleDescription() -> String { 461 | 462 | switch self { 463 | 464 | case .Ace: 465 | 466 | return "ace" 467 | 468 | case .Jack: 469 | 470 | return "Jack" 471 | 472 | case .Queen: 473 | 474 | return "Queen" 475 | 476 | case .King: 477 | 478 | return "King111" 479 | 480 | default: 481 | 482 | return String(self.rawValue) 483 | } 484 | } 485 | 486 | func compareWithOriginal(compareOne:Int , compareTwo :Int) -> String { 487 | if compareOne > compareTwo 488 | { 489 | return String(compareOne) 490 | } 491 | else 492 | { 493 | return String(compareTwo) 494 | } 495 | } 496 | } 497 | 498 | let ace = Rank.Ace 499 | print(ace) 500 | 501 | let aceRawValue = ace.rawValue 502 | ace.simpleDescription() 503 | 504 | let four = Rank.Four 505 | 506 | let compareStr = ace.compareWithOriginal(compareOne: ace.rawValue,compareTwo: four.rawValue) 507 | 508 | 509 | if let convertedRank = Rank(rawValue: 3) { 510 | let threeDescription = convertedRank.simpleDescription() 511 | 512 | } 513 | 514 | enum Suits { 515 | 516 | case Spades,Heards, Diamonds,Clubs 517 | func simpleDescription() -> String { 518 | 519 | switch self 520 | { 521 | case Suits.Spades: 522 | 523 | return "SpadesA" 524 | 525 | case .Heards: 526 | 527 | return "HeardsA" 528 | 529 | case .Diamonds: 530 | 531 | return "DiamondsA" 532 | 533 | default: 534 | 535 | return "ClubsA" 536 | } 537 | } 538 | 539 | func color(suitName:Suits) -> String { 540 | 541 | switch self { 542 | case .Spades,.Clubs: 543 | return "black" 544 | default: 545 | return "red" 546 | } 547 | } 548 | } 549 | // 得到枚举成员的实例 550 | let heaeds = Suits.Spades 551 | let heaedsDesciption = heaeds.simpleDescription() 552 | 553 | // 因为没有提供枚举成员的原始值,那就直接用枚举值类型,实际值类型 554 | heaeds.color(suitName:heaeds) 555 | 556 | 557 | enum ServerResponse 558 | { 559 | case Result(String, String) 560 | case Failure(String) 561 | // case Other(String) 562 | } 563 | 564 | 565 | let success = ServerResponse.Result("6.00 am", "8:00 pm") 566 | let failure = ServerResponse.Failure("Out of cheese.") 567 | 568 | print(success,failure) 569 | 570 | 571 | switch success 572 | { 573 | case let .Result(sunrise, sunset): 574 | 575 | let serverResponse = "jia you \(sunrise) jia you \(sunset)" 576 | 577 | case let .Failure(shibai): 578 | 579 | print("Failure....:\(shibai)") 580 | 581 | // 提示永远不会被执行,因为就这2种情况 582 | default: 583 | print("Failure... ") 584 | } 585 | 586 | struct Card { 587 | 588 | var rank:Rank 589 | var suit:Suits 590 | 591 | func simpleDescription() -> String { 592 | return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" 593 | } 594 | 595 | 596 | } 597 | 598 | let threeOfSpades = Card(rank: Rank.Three, suit: Suits.Spades) 599 | let threeOfSpadesDescription = threeOfSpades.simpleDescription() 600 | 601 | 602 | 603 | /* 604 | 问题: 605 | 1.不是太懂,被{get}搞懵逼了,在protocol中不写提示属性必须实现get set其中一个 606 | 2. 写一个实现这个协议的枚举。因为枚举中不写包含属性,这个怎么办 607 | 608 | 协议和扩展 609 | 1.注意声明SimpleStructure时候mutating关键字用来标记一个会修改结构体的方法。SimpleClass的声明不需要标记任何方法,因为类中的方法通常可以修改类属性(类的性质,你在类的方法前面加mutating会提示报错,自动去掉)。 610 | 类,枚举和结构体继承这个协议,协议里面的属性和方法都必须去重载,否则就提示报错。String也是可以+=的 611 | */ 612 | protocol ExampleProtocal { 613 | 614 | var simpleDescription: String{ 615 | get 616 | } 617 | mutating func adjust() 618 | 619 | } 620 | 621 | class SimpleClass: ExampleProtocal { 622 | 623 | var simpleDescription: String = "A very simple class" 624 | 625 | func adjust() { 626 | simpleDescription += " Now 100% adjusted." 627 | } 628 | } 629 | 630 | var a = SimpleClass() 631 | a.adjust() 632 | let aDescription = a.simpleDescription 633 | 634 | //enum SimpleEnumerate: ExampleProtocal 635 | //{ 636 | // 637 | // case A 638 | // case B 639 | // case C,D 640 | // case E(String,String) 641 | // var simpleDescription: String = "A simple enumerate" 642 | // mutating func adjust() { 643 | // simpleDescription += " enumerate" 644 | // } 645 | //} 646 | 647 | 648 | struct SimpleStructure: ExampleProtocal 649 | { 650 | var simpleDescription: String = "A simple struct" 651 | mutating func adjust() { 652 | simpleDescription += " (adjusted)" 653 | } 654 | } 655 | 656 | var b = SimpleStructure() 657 | b.adjust() 658 | let bDescription = b.simpleDescription 659 | 660 | 661 | 662 | extension Int: ExampleProtocal{ 663 | var simpleDescription: String { 664 | return "The number \(self)" 665 | } 666 | 667 | mutating func adjust() { 668 | 669 | self += 42 670 | } 671 | } 672 | 673 | print(7.simpleDescription) 674 | 675 | 676 | /* 677 | 错误处理 678 | 问题1. let printerError as PrinterError 什么意思 679 | 2. 使用defer代码块来表示在函数返回前,函数中最后执行的代码。 680 | 1.采用Error协议的类型来表示错误。do try catch 进去throws函数有throw抛出就进去catch可选的内容,函数下面的代码不走了,没有throw抛出,继续走下面的代码 681 | 2.另一种处理错误的方式使用try?将结果转换为可选的。如果函数抛出错误,该错误会被抛弃并且结果为nil。否则的话,结果会是一个包含函数返回值的可选值。(是个可选类型,并且包含一个可选值job send) 682 | */ 683 | 684 | 685 | enum PrinterError: Error 686 | { 687 | case outofPaper 688 | case noToner 689 | case onFire 690 | } 691 | 692 | // 使用throws来表示一个可以抛出错误的函数 693 | func send(job: Int, toPriter prinerName: String) throws -> String 694 | { 695 | if prinerName == "Never Has Toner" { 696 | // 使用throw来抛出一个错误 697 | throw PrinterError.noToner 698 | } 699 | 700 | return "Job sent" 701 | } 702 | 703 | do { 704 | try send(job: 22, toPriter: "Never Has Toner1") 705 | print("jixuzou") 706 | } catch { 707 | print(error) 708 | } 709 | 710 | do 711 | { 712 | // 进去throws函数有throw抛出就进去catch可选的内容,函数下面的代码不走了,没有throw抛出,继续走下面的代码 713 | let a = try send(job: 22, toPriter: "Never Has Toner") 714 | print(a) 715 | } 716 | catch PrinterError.outofPaper 717 | { 718 | print("AAAAA") 719 | } 720 | catch let printerError as PrinterError 721 | { 722 | print("wwwww \(printerError)") 723 | } 724 | catch 725 | { 726 | print(error) 727 | } 728 | 729 | 730 | let printerSuccess = try? send(job: 222, toPriter: "22") 731 | let printerFailure = try? send(job: 222, toPriter: "Never Has Toner") 732 | 733 | /* 734 | 泛型,这个就是有问题,没理解。很大问题 735 | */ 736 | //func repeatItem(repeating item: Item,numberofTimes: int) -> [item] 737 | //{ 738 | // 739 | // 740 | //} 741 | 742 | 743 | --------------------------------------------------------------------------------