共计 8671 个字符,预计需要花费 22 分钟才能阅读完成。
Basic
Syntax
// variable
var number = 6
var title : String?
// const value, should be initialized before use it, can't be changed after its definition
let speed = 200
let name : String? = nil
Base data type
Type | Desc |
---|---|
UInt8 | UInt8.min is 0, UInt8.max is 255 |
Int | On the 32-bit platform, it’s as Int32; On the 64-bit platform, it’s as Int64. |
Uint | On the 32-bit platform, it’s as UInt32; On the 64-bit platform, it’s as UInt64. |
Double | 64-bit floating-point number |
Float | 32-bit floating-point number |
Boolean | true or false |
Numeric
/* Numeric Literals */
// They are the same number, in another word, their values are the same.
let decimalInteger = 17
let binaryInteger = 0b10001
let octalInteger = 0o21
let hexadecimalInteger = 0x11
// Optional exponent (exp)
1.25e2
1.25e-2
// pad with extra zeros and underscores to make them easier to read.
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneBillion = 1_000_000.000_000_1
/* Numeric Type Conversion */
// Type automatic convert
let a : UInt16 = 2000
let b : UInt8 = 1 // Different type can't be sum together
let c = a + b // Here, system use b to create a new UInt16 object, so this new object can sum with a.
// Type force convert
let three = 3
let num = 0.14159
let pi = Double(three) + num // conversions between integer and floating-point numeric types must be made explict.
// Truncate
let integerPi = Int(pi)
// The rules for combining numeric constants and variable are different from the rules for numeric literals.
// Number literals don’t have an explicit type in and of themselves.
Type Aliases
typealias MyInt16 = UInt16
var num : MyInt16 = MyInt16.min // it's actually calls the UInt16.min
Tuples
let http404Error = (404, "Not Found") // compose a tuple
let (statusCode, statusMessage) = http404Error // decompose a tuple
let (justTheStatusCode, _) = http404Error // use a underscore(_) to ignore other values
let statusCodeByIndex = http404Error.0 // get the tuple's individual element value by index, start at 0
// name the tuple's individual element
let http200Status = (statusCode : 200, description : "OK")
let status200 = http200Status.statusCode
let description200 = http200Status.description
Optional : variable can be a value or nil. Just add a‘?’after the variable’s type. nil
meaning“the absence of a valid object.”
only optional type can be nil.
const value should not be nil, it has no specific meaning in application.
var name:String? = "Hello"
// Because the initializer might be fail, it returns an optional Int (Int?), rather than an Int.
let num = Int("123")
var answer : Int? // the answer is automatically set to nil.
// In Objective-C, nil is a pointer to a nonexistent object.
// In Swift, nil isn’t a pointer—it’s the absence of a value of a certain type.
// Include multiple condition
// If any of the values in the optional bindings are nil or any Boolean condition evaluates to false, the whole if statement’s condition is considered to be false.
if let firstNum = Int("4"), let secondNum = Int("5"), firstNum < secondNum && secondNum < 100 {print("\(firstNum) < \(secondNum) < 100")
}
let hobby : String? // ordinary optional
let myHobby = hobby! // must require a exclaimation point to unwrap the object.
// An implicitly unwrapped optional as giving permission for the optional to be force-unwrapped if needed
let address : String! // implicitly option. the name can be accessed when it is nil and without exclaimation point.
let hisAddress = address // it is permitted, no need for an exclaimation point.
// we are recommanded to use the ordinary optional in development.
// because the implicitly optional can easily be out of control.
// ######## error #########
// this will trigger a runtime error
var str : String! = nil
print(str.count)
// this will trigger a runtime error
var bag : String?
print(str!.count). // 'str!' is nil, so it can't be accessed.
// this will trigger a compiler error
var pack : String?
print(str.count) // str is an ordinary option, need an unwrap(!).
// #######################
Function’s argument and its label
-
use argument label
func addTwo(arg1 a : Int, arg2 b : Int) -> Int { let c = a + b return c } let sum = addTwo(arg1: 4, arg2: 28)
-
Tell argument’s name apparently
func addTwo(a : Int, b : Int) -> Int { let c = a + _b return c } let sum = addTwo(a: 4, b: 28)
-
use [_] to pass over the label (Recommended)
func addTwo(_ a : Int, _ b : Int) -> Int { let c = a + b return c } let sum = addTwo(4, 28)
-
Function’s define and invoke no need to be sequenced. It can be invoked before it’s define.
// invoke function goToSchool() //function definition func goToSchool() {print("I go to school.") }
Object Oriened
Class
class Person {
var name = "neo"
var age = 0
init () {}
init (_ name : String, _ age : Int) {
self.name = name
self.age = age
}
}
// use different init function to create object.
var a = Person()
var b = Person("Mike", 26)
print(a.name + " " + String(a.age))
print(b.name + " " + String(b.age))
Optional
class BlogPost {
// title can be String or nil
var title : String?
}
let post = BlogPost()
print(post.body + "hello!")
//post.title = "yo"
// Optional Binding
if let actualTitle = post.title {print(actualTitle + "Hey")
}
else {print("post.title is \(post.title)")
}
// Testting for nil
if post.title != nil {print(post.title! + "not nil") // exclaimation '!' means force unbox
}
if post.title == nil {print("It's nil")
}
// Implicity optional
var name : String! = "Amy" // '!' means that implicity optional
if name != nil {
// no need to use '!'
print(name + "not nil")
}
Initializer
-
The rule of initializer
-
A designated initializer must call the designated initializer from the immediately superclass.
class Worker : Person {override init () {super.init() print("subclass's designated initializer") } // it has no conflict with the superclass's convenience method. init (customName : String, age : Int) { // designated initializer call the designated initializer from superclass. super.init(name : customName) self.age = age print("subclass's designated initializer with two parameters") } } class Person { var name = "neo" var age = 0 init () { age = 3 name = "ha" } init (name : String) {self.name = name} convenience init (customName : String, age : Int) {self.init(name : customName) self.age = age } }
- A convenience initializer must call another designated initializer from the same class.
- A convenience initializer must ultimately call a designated initializer.
-
-
designated initializer
init () { age = 3 name = "ha" }
init(_ name : String, _ age : Int) { self.name = name self.age = age }
-
convenience initializer
if we want to invoke the designated initializer self.init() in a newly init method, we should add a keyword‘convenience’to decorate this newly method. (The reason why we use the‘convenience’keyword)
convenience init(name : String) {self.init() self.name = name }
-
Inheritance
Swift only permit single inheritance
class Car { var topSpeed = 200 func drive() {print("Drive at \(topSpeed)") } } // inheritance class FutureCar : Car() { // the method belong to current class func fly() {print("Fly at \(topSpeed + 20)") } } let myRide = Car() // create an instance from the class 'Car'. myRide.drive() let hisCar = FutureCar() hisCar.fly() // method create by the subclass.
-
Polymorphism
-
Override
The method has the same name but the arguments’type or count are different.
If we call with different types or count of arguments , the phenomenons(results) are different.
class Car { var speed = 200 func drive() {print("Drive at \(speed)") // the 'speed' can be use in this class 'Car' } func drive(_ speed : Int) {print("Drive at \(speed)") // the 'speed' can be only used in this func } } let myCar = Car() myCar.drive() myCar.drive(160)
// another case goToSchool() goToSchool("Mike") goToSchool("Micle", "Jhon") goToSchool(15) func goToSchool() {print("I go to school.") } func goToSchool(_ peoleA : String) {print("I go to school with \(peoleA).") } func goToSchool(_ peopleA : String, _ peopleB : String) {print("I go to school with" + peopleA + "and" + peopleB + ".") } func goToSchool(_ speed : Int) {print("I go to school in a speed of \(speed).") }
The subclass define a same method already in the superclass, but the implement of this method is different from that implemented in the superclass. Use the key word‘override’
class Car { var speed = 200 func drive() {print("Drive at \(speed)") } } // inheritance class FutureCar : Car() { // override the method from the superclass. override func drive() {print("Drive at \(speed + 5)") } } let myRide = Car()//create an instance from the class 'Car'. myRide.drive() let hisCar = FutureCar() hisCar.drive() //method override by the subclass.
-
Error Handling
Two way to solve the error on runtime
-
throws
func doSomething() throws {// Here may or may not throw an error}
-
do try catch
do the right things to face the error.
do {try makeSandwich() // no error was thrown eatSandwich()} catch SandwichError.outOfCleanDishes { // an error was thrown washDish()} catch SandwichError.missingIngredients(let ingredients) { // an error was thrown buyGroceries(ingredients) } catch {// catch other errors}
## Assertion & Precondition
A assertion or precondition indicates an invalid program state, there’s no way to catch a failed assertion.
// Assertion let age = -3 assert(age >= 0, "Age can't be less than 0") // (the condition, the message to be shown when the condition is false) assert(age >= 0) // omit the message, it's ok. assertionFailure("Age can't be less than 0") // when the code already check the failure, use the assertionFailure to show message directly. // Precondition let index = -1 precondition(index >= 0, "Index must be greater than 0") precondition(index >= 0) preconditionFailure("Index must be greater than 0") // If you compile in unchecked mode (-Ounchecked), preconditions aren’t checked.But the assertion still check. // Assertion check in debug environment, not check in realease environment. // Precondition check in debug environment and release environment. // Use fatalError(_ :file:line:) to halt execution // During prototyping and early development to create stubs for functionality that hasn’t been implemented yet,write a fatalError as the stub implementation. // if the code use the functionality which hasn't been implemented, that will result in a fatal error. It will remind us to implement the function or method. fatalError("Unimplemented")