Quick browse Swift notes
Quick browse Swift: https://docs.swift.org/swift-book/GuidedTour/GuidedTour.html
Variables are also constants
//Multiline string, using "" ""
let quotation = """ I said "I have \(3) apples." And then I said "I have \(3 + 4) pieces of fruit." """ print(quotation)
//Create an empty array, variable
var array = [String]()
//Create an empty dictionary. key is of String type and value is of Float type
var dictionary = [String: Float]()
//Create a dictionary. key is of String type and value is of any type
var dictionary1 = [String: Any]()
//String
var string = "hello"
//Optional type?
var optionnalString: String? = "hello"
control flow
// if let
if let str = optionnalString { print(str) }
//Optional type
//let nickName: String = nil / / error: 'nil' cannot initialize specified type 'String' let nickName: String? = nil // It feels like a trinocular operator. If there is no, it is nil let fullName: String = "John" // ?? Operator set default let name: String = "My name is \(nickName ?? fullName)"
//Switch supports any type of comparison, not limited to integer comparison
Functions and closures
//Function
// func function name (formal parameter) - > return value /** func <#name#>(<#parameters#>) -> <#return type#> { <#function body#> } */ func person(fullName name: String, age: Int) -> String { return "\(name) age:\(age)" }
//About formal parameters:
// 1. In parentheses (), the words of multiple parameters are separated by commas, which is the same as in most languages
// 2. Before the colon is the formal parameter, after the colon is an empty space, followed by the parameter type
// 3. Shape parameters can be preceded by a "parameter label". It can also not be written. If it is not written in the old version of Swift, you need to use "" to indicate that no parameter label is used. In Swift5, the existence of parameter labels is weakened. No error will be reported without writing, adding "" and compiling
//Tuple
//Use () to define a tuple
//Tuples can be used as function return values
func calculatesStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) { var min = scores[0] var max = scores[0] var sum = 0 for score in scores { if score > max { max = score } else if score < min { min = score } sum += score } return (min, max, sum) }
//Function nesting
//Implementation of nesting another function in one function
//Function as the return value of another function
//Returning a function in () looks like returning a function as an element of a tuple
//((function parameter) - > return value of function)
func makeIncrementer() -> ((Int) -> Int) { func addOne(num: Int) -> Int { return num+1 } return addOne(num:) }
//Function as parameter
//Closure
Objects and classes
//class name
class Shape { // Variable var numberOfSides = 0 // constant let sumNumbers = 100 // initialization init(sides: Int) { numberOfSides = sides } func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." } }
//Create a shape instance
var shape = Shape() shape.numberOfSides = 10
//Inherit
class rectangle: Shape { var sideLength: Double var sidWidth: Double // ? Will an error be reported if sideLength and sidWidth are not added to the init function? Why? init(sideLength: Double, sidWidth: Double, sides: Int) { self.sideLength = sideLength self.sidWidth = sidWidth super.init(sides: sides) } // Define a variable and write set and get methods by the way var perimeter: Double { get { return 3.0 * sideLength } set { sideLength = newValue / 3.0 // The newValue here is more interesting. After set, a tep value will be saved first, which is newValue. } } // willSet and didSet // }
enum and struct
//Enumeration
enum AliasAPI: Int { case register = 1 case login case getPersonalInfo case updatePersionalInfo func API() -> String { switch self { case .register: return "register/v1" case .login: return "login/v1" case .getPersonalInfo: return "getPersonalInfo/v2" case .updatePersionalInfo: return "updatePersionalInfo/v2" } } } let api = AliasAPI.login let apiRawValue = api.rawValue print(apiRawValue) let apiString = api.API() print(apiString) //enum APICommad: String { // case register // case login // case getPersonalInfo // case updatePersionalInfo //} // //func getApi(command: APICommad) -> String { // return command.rawValue //} //let apiValue = getApi(command: .login) //print(apiValue) enum APICommad: String { case register case login case getPersonalInfo case updatePersionalInfo } let apiValue = APICommad.login print(apiValue)
Protocols and extensions
// protocol
//Classes, enumerations, and structures can all use protocols.
//Declare an agreement
protocol ActivitiseProtocol { var name: String { get } // There's no {get} here. It's popular var age: Int { get } mutating func eat() // Why use mutating to modify } class Person: ActivitiseProtocol { var name: String = "" var age: Int = 0 var dog: Dog? func eat() { print("having dinner") } } class Dog: ActivitiseProtocol { var name: String = "" var age: Int = 0 func eat() { print("Eat dog food") } } var dog = Dog() dog.eat() dog.name = "Huahua" var p = Person() p.eat() p.name = "Xiaoming" p.dog = dog print(p.dog?.name ?? "")
error handling
//Use this Error protocol to customize the Error type
enum XXError: Error { // Note that Error is a protocol here case parater case api case url case network }
//throw throws an error, which is similar to other languages
// do- catch. It's the same as other languages
do { } catch { }
// try?
// defer
///Generics
//Write a name in < > to represent a common type. This is the same as the generic type in C# and should be available in other languages
func makeArray<Item>(item: Item, numberOfTimes: Int) -> [Item] { var result = [Item]() for _ in 0..<numberOfTimes { result.append(item) } return result } var myArray:[String] = makeArray(item: "value", numberOfTimes: 3) print(myArray) var myArray1:[Dog] = makeArray(item: dog, numberOfTimes: 3) print(myArray1)