1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 |
//: Playground - noun: a place where people can play import UIKit // -----------------------Swift初见-------------------------------------- // 简单输出 print("hello, world") // print可以自定义连接符或者自定义结束符 print(1, 2, 3, 4, separator: "-") print(1, 2, 3, 4, terminator: "") print(1, 2, 3, 4, separator: "->", terminator: "->End\n") // let声明常量,var声明变量 let myConstant = 11 var myVariable1 = 42 myVariable1 = 56 // 可以让编译器推断常量或者变量的类型,也可以自己显式指定 var myVariable2:Double = 6 // 值永远的不会被隐式转换为其他类型,必须显式转换 let string1 = "the label is" let integer1 = 94 let string2 = string1 + String(integer1) // 把值转换为字符串的另一种写法 let string3 = "the label is \(integer1)" // 数组和字典都是用[]创建 var list1 = ["apple", "banana", "orange"] list1[2] = "pear" var dic = ["class": "2班", "grade": "1年级"] dic["class"] = "3班" // 创建一个空数组或者字典 let emptyArray = [String]() let emptyDictionary = [String: Float]() // 如果数组或者字典的类型已经被推断出来,就可以用[]或者[:]清空数组或者字典 list1 = [] dic = [:] // for和if后面的条件小括号可以省略,但是语句的大括号不能省略 // Swift3中已经不支持++和--,只能 += 1和 -= 1 // if中必须是布尔表达式,不会隐性和0比较 let list2 = [1, 2, 3, 4] var cnt = 0 for tempitem in list2 { if tempitem < 3 { cnt += 1 } else { cnt -= 1 } } // 用if和let处理值缺失的情况(用可选值) // 如果变量的可选值是nil,条件会判断为false,大括号内的语句不会被执行 var optionalName: String? = nil if let name = optionalName { print("hello, \(name)") } // ?可以规避实例为nil时,调用实例方法报错的现象,因为当实例为nil时候,因为实例是可选类型,所以语句会直接忽略后面的不再执行,故而不会出现异常(也就是说?前面的值为nil时,?后面的操作会被全部忽略) // nil不可以用在不是可选值的常量或者变量中,如果一个常量或者变量可能会没有值,那就必须声明为可选值 // 如果声明了可选值但是没有初始化,它的默认值为nil,如果不是可选值,且没有初始化,可以定义,但是必须初始化后才能使用 var myValue: String? = nil // 如果我们非常确定一个可选值一定有值的话,我们可以用"!"对它进行强制拆包 var myValue2: String? = "hello, everyone!" print(myValue2!) // 另一种处理可选值的方法是通过使用??操作符来提供一个默认值,如果不加??,该变量会输出nil let nickName: String? = nil let fullName: String = "John" print("Hi, \(nickName ?? fullName)") //此时会输出"Hi, John\n" // switch和case支持任何类型的数据,还支持以下方式: let vegetable = "red pepper" switch vegetable { case "apple": print("1") case "banana", "orange": print("2") case let x where x.hasSuffix("pepper"): print("It is a \(x)") default: print("~~~") } // switch语句必须要写default语句,不需要写break语句,因为它匹配成功后就会退出switch语句,不会继续执行 // 使用for-in遍历字典,用两个变量来表示每个键值对,字典里面是一个无序的集合 let dic2 = [ "apple": [1, 2, 3], "orange": [7, 10, 11] ] for (key, values) in dic2 { for value in values { if value > 0 { //balabala... } } } // 使用while或者repeat while语句 var n = 2 while n < 100 { n = n * 2 } repeat { n = n / 2; } while n > 20 // 不包含上界用..< 包含上界用... // 如果不希望print换行就写 print("\(i) ", terminator: "") for i in 0..<4 { print("\(i) ", terminator: "") } for j in 0...4 { print(j) } // 使用func声明函数,使用->指定返回值的类型 func greet(person: String, day: String) -> String { return "Hi, \(person), today is \(day)" } // 我们在写函数的时候,如果不提供参数的标签,那么参数的标签就是参数的名字,我们可以在参数名称前面加上自己想要的文字作为函数的参数标签,如果我们不想使用参数标签的话我们可以在参数名称前面加上"_" // 下面三个语句,分别使用自定义标签、参数名称以及不使用标签 // 内部使用的时候采用参数名称(内部参数名) func myfunc1(name: String, Address adr: String) -> Void { print("My name is \(name), my address is \(adr)") } func myfunc2(name: String, adr: String) -> Void { print("My name is \(name), my address is \(adr)") } func myfunc3( _ name: String, _ adr: String) -> Void { print("My name is \(name), my address is \(adr)") } // 外部调用的时候使用的是参数标签名(外部参数名) myfunc1(name: "John", Address: "1234") myfunc2(name: "John", adr: "1234") myfunc3("John", "1234") // 二进制、八进制、十进制、十六进制 var a1 = 0b100 // 4 var a2 = 0o100 // 64 var a3 = 100 // 100 var a4 = 0x100 // 256 // 十进制指数 var a5 = 1.25e-2 // 0.0125 // 元组:可以将多个类型的值聚合起来: // 注意!元组是用小括号括起来的() ; 数组和字典是用大括号括起来的[] let tuples1 = ("John", 21, 1.78) // 如果想要分解元组可以这样: let (name, age, height) = tuples1 print("my name is \(name), my age is \(age), my height is \(height)") // 如果说只想用name可以用下划线代替想要忽略的值,只指定name变量 let (name2, _, _) = tuples1 print("my name is \(name2)!~~~") // 元组可以使用类似下标的形式访问,不过是以"tuplesName.0" "tuplesName.1" "tuplesName.2"的形式 print("my name is \(tuples1.0) and my age is \(tuples1.1)") // 也可以给元组定义标签,这样就可以直接使用标签的名字进行访问啦~~~ let tuples2 = (name: "TomCat", age:"22") print("hello, my name is \(tuples2.name) and my age is \(tuples2.age)") // 可以用元组来做到让一个函数返回多个值 func myfunc4(scores: [Int]) -> (min: Int, max: Int, sum: Int) { let min = scores[0] let max = scores[1] let sum = 0 return (min, max, sum) } // 函数可以带有可变个数的参数 func func8(arr: Int...) -> Int { var sum = 0 for number in arr { sum += number } return sum } func8() func8(arr: 1, 2, 3) // 函数可以嵌套,被嵌套的函数可以访问外侧函数的变量 func func5() -> Int { var y = 10 func add() { y += 20 } add() return y } // 函数可以作为返回值 func func6() -> ((Int) -> Int) { func func7(number: Int) -> Int { return 1 + number } return func7 } var value6 = func6() //此时value6是func6的返回值类型,func6的返回值类型是一个函数类型,它表示接收一个int类型,返回一个int类型的函数类型 print(value6(7)) // print "8\n" // 函数可以作为参数 // 如下condition就是一个函数类型的参数 func func9(arr: [Int], condition: (Int) -> Bool) -> Bool { for item in arr { if condition(item) { return true } } return false } func lessThanTen(number: Int) -> Bool { return number < 10 } var numbers = [20, 19, 7, 12] func9(arr: numbers, condition: lessThanTen) // 闭包 // 函数实际上是一种特殊的闭包,它是一段之后能够被调取的代码 // 可以使用{}创建一个匿名闭包,使用in将参数和返回值类型声明与闭包函数体进行分离 numbers.map({ (number: Int) -> Int in let result = 3 * number return result }) // 更简洁的写法:如果一个闭包的类型已知,比如作为一个回调函数,就可以忽略参数的类型和返回值。单个语句闭包会把它语句的值当作结果返回 let value7 = numbers.map({number in 3 * number}) print(value7) // 可以通过参数的位置而不是参数名字来引用参数 // 如果一个闭包是作为最后一个参数传给一个函数的时候,它可以直接跟在括号后面 // 当一个闭包是传给函数的唯一参数,可以完全忽略括号 let arr2 = numbers.sorted { $0 > $1 } print(arr2) // 使用class来创建一个类 // 使用一个构造函数来初始化类实例,使用init来创建一个构造器 class className1 { var value = 0 var name = "hahaha" init(value: Int) { self.value = value } func func10() -> String { return "A shape with \(value) sides" } } // 创建一个类的实例,不是new不是new不是new!!是在类名后面加括号。 // 使用点来访问实例的属性和方法 var instanceName1 = className1(value: 5) instanceName1.value = 2 var stringName2 = instanceName1.func10() // 子类在后面加上“:父类名字”就能继承自父类~创建类的时候并不需要一个标准的根类,所以可以忽略父类 // 如果要重写父类的方法,必须使用override标记(如果没有添加override就重写父类方法的话编译器会报错)。编译器也同样会检测override标记的方法是否确实在父类中 class className2: className1 { var sideLength: Double init(sideLength: Double, value: Int) { self.sideLength = sideLength super.init(value: value) name = "xixi" } override func func10() -> String { print("lalala~") return name } } // 除了储存简单的属性之外,属性可以有getter和setter class className3 { var sideLength: Double = 2 var perimeter: Double { get { return 3.0 * sideLength } set { sideLength = newValue / 3.0 } } } var instanceName2 = className3() print(instanceName2.perimeter) instanceName2.perimeter = 8 print(instanceName2.sideLength) // willSet和didSet 在设置一个新值之前或之后运行的代码 class className4 { var age: Int = 0 { willSet { print("we will set an new value \(newValue) to age") } didSet { print("we have changed \(oldValue) to \(age)") } } } var instanceName4 = className4() instanceName4.age = 8 instanceName4.age = 12 // 使用enum创建枚举 enum Rank: Int { case Ace = 1 case Two, Three, Four, Five, Six case Jack, Queen, King func simpleDescription() -> String { switch self { case .Ace: return "ace" case .Jack: return "jack" default: return String(self.rawValue) } } } let ace = Rank.Ace let aceRawValue = ace.rawValue // 使用struct创建结构体。结构体和类相似,比如方法和构造器。结构体是传值,类是传引用 struct Card { var rank = 1 func func11() -> String { return "hello" } } // 使用protocol来声明协议 // mutating 关键字用来标记一个会修改结构体的方法 protocol ExampleProtocol { var value11: Int {get} mutating func adjust() } // 类、枚举和结构体都可以实现协议 // Extension 扩展是给已经存在的类,结构体,枚举类型和协议增加新的功能 // 扩展能够增加新功能,但是不能覆盖已有的功能 // 错误处理 // 定义错误类型: enum PrinterError: Error { case OutOfPaper case NoToner case OnFire } // 使用throw关键字来抛出一个错误、使用throws关键字来表示一个可以抛出错误的函数。 // 如果在函数中抛出一个错误,这个函数会立刻返回并且调用该函数的代码进行错误处理 func send(job: Int, toPrinter printerName: String) throws -> String { if printerName == "Never Has Toner" { throw PrinterError.NoToner } return "Job sent" } // 在do-catch中进行错误处理,使用try标记抛出错误的代码 do { let printerResponse = try send(job: 1440, toPrinter: "Gutenberg") print(printerResponse) } catch PrinterError.OnFire { print("I'll just put this over here, with the rest of the fire") } catch let printerError as PrinterError { print("Printer error: \(printerError).") } catch { print(error) } // 错误处理的另一种方法:使用try? 将结果转换为可选的。如果函数抛出错误,该错误会被抛弃并且结果为nil。否则的话,结果会是一个包含函数返回值的可选值 let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler") // 使用defer代码块表示在函数返回之前,函数中最后会执行的代码 // 泛型 // 可以使用where对参数做出一些约束,比如必须是实现了某一个协议,或者说具有一个特定的父类 |
❤ 点击这里 -> 订阅《PAT | 蓝桥 | LeetCode学习路径 & 刷题经验》by 柳婼