Swift is a new programming language for iOS and OS X applications. It is based on C and Objective-C, but does not have some compatibility constraints of C. Swift adopts a secure programming mode and adds modern features to make programming easier, more flexible and fun. The interface is based on the Cocoa and Cocoa Touch frameworks that are widely loved by the people, showing a new direction of software development.
Variables and constants
Variable definition uses var, constants use let, type-safe, automatic type derivation, note that there must be spaces on both sides of the = sign assigned. Variables and constant names are available for almost all characters, and these are very similar to javascript. Chinese programming is awesome.
var a = 123 //a is Intlet b = "helo" //b is Stringvar Cats croak = "Meow"
number
- Decimal
- Binary 0b101
- Octal 0o5
- Hexadecimal 0x5
A relatively long number can be added to improve the readability of the program. For example, 0_0 is actually 0, and the line cannot be added to the beginning.
Boolean type
true and false. When the process controls if, the judgment statement must return a Bool value, such as:
let i = 1 if i { //Compilation error}
This way it can pass
if i == 1 { }
It doesn't have automatic type conversion like js
Type alias
Adding an alias to the current type can also improve the readability of the program, such as
typealias Audio sampling = UInt16
Can be used elsewhere var discovered maximum amplitude = audio sampling.min
Tuples
It can be a set of values that do not have to be of the same type, for example, define myself:
var jserme = ("183cm", 26, "76kg")
Can be accessed like an array
println(jserme.0) //Return 183cm
Restore tuples to independent variables or constants
let jserme = ("183cm",26,"76kg") let (height, age, weight) = jserme println("height是 \(height)")
You can also name each value (it's like turning an array into an object in JS...)
let jserme = (height:"183cm",age:26,weight:"76kg") println("height是 \(jserme.height)")
String
String literals can only be defined by "", and String is essentially an ordered collection of Characters.
for char in "A word is released"{ println(char) } /* one Word now that out */
Literal and judgment whether it is empty
var String = "I'm a string" var 空String = "" if 空String.isEmpty { println("This is an empty string") } if 空String == "" { println("This is an empty string") }
There are two methods for string instances that havePrefix and haveSuffix, such as:
var Idiom array = [ "A word is released", "It's about to break out", "One call and a hundred responses", "One hammer to make a sound", "Nothing", "A lifetime", "love at first sight" ] var count = 0 for idiom in Idiom array { if(idiom.hasPrefix("one")){ count++ } } println(count) //Output 7
Like js, string is also a reference to pass a value. The modification of the following two variables will not affect each other.
var A string = "I'm String One" var Two strings = A string Two strings = "I'm String Two" println("String one:\(A string), String two:\(Two strings)")
Interval operator
Closed intervals use a...b, from a to b, including a and b, half intervals a..b, from a to b, without b, for example:
var Idiom array = [ "A word is released", "It's about to break out", "One call and a hundred responses" ] for i in 0..Idiom array.count { println("The\(i)Idioms are:\(Idiom array[i])") } //How to use it here... will report an error because the idiom array [3] has no value
Two sets, array and dictionaries
Compared with JS's loose requirements for arrays and object members, Swift requires that the member types in arrays and dictionaries must be consistent.
var Shopping list: String[] = ["egg", "milk"] //It can also be the following//var Shopping List = ["Egg", "Milk"]
The array can be modified using the append method or +=
var Shopping list = ["egg", "milk"] Shopping list.append("apple") Shopping list += "strawberry" println("\(Shopping list)") //[Egg, Milk, Apple, Strawberry]
The acquisition of arrays can be obtained through indexes or interval operators.
var Shopping list = ["egg", "milk"] println("\(Shopping list[0])") //eggprintln("\(Shopping list[0..1])") //[egg]println("\(Shopping list[0...1])") //[Eggs, Milk]println("\(Shopping list[0...2])") //[Egg, Milk,]
Definition of dictionaries
var airports: Dictionary<String, String> = ["TYO": "Tokyo", "DUB": "Dublin"] //It can also be simplified to//var airports = ["TYO": "Tokyo", "DUB": "Dublin"]
Its modification and reading use [], but cannot be used.
airports["BJ"] = "Beijin"
Control statements
As shown in the previous examples, the conditions of the control statement do not have brackets like js
for var index = 0; index < 3; index++ { println("index is \(index)") } //index is 0 //index is 1 //index is 2
function
Function declaration and call:
func sayHello(personName: String) -> String { let greeting = "Hello, " + personName + "!" return greeting } println(sayHello("jserme"))
The function without return is essentially a Void, which is equivalent to an empty tuple()
Functions with multiple return values and default parameters:
func info(word:String = "aha") -> (length:Int, containA:Bool){ var containA = false for char in word { if( char == "a") { containA = true break } } return (word.utf16count, containA) } println(info(word: "Bobo")) //(2, false) println(info()) //(3, true)
The external parameter name that is easy to read is separated from the parameter definition by spaces before the parameter definition, such as the following multiple parameters
func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String { return s1 + joiner + s2 } //When callingjoin(string: "hello", toString: "world", withJoiner: ", ") // returns "hello, world"
The parameter name is the same as the external parameter name. You can add a # mark to the parameter name:
func containsCharacter(#string: String, #characterToFind: Character) -> Bool { for character in string { if character == characterToFind { return true } } return false } let containsAVee = containsCharacter(string: "aardvark", characterToFind: "v") // containsAVee equals true, because "aardvark" contains a "v"
The parameters of the function are constants and cannot be modified. If modified within the function, add var before the variable definition.
func alignRight(var string: String, count: Int, pad: Character) -> String { let amountToPad = count - countElements(string) for _ in 1...amountToPad { string = pad + string } return string } let originalString = "hello" let paddedString = alignRight(originalString, 10, "-") // paddedString is equal to "-----hello" // originalString is still equal to "hello"
If you want to modify the passed parameters in the function, you can use the inout keyword to identify them. The passed parameters need to be prefixed &, and this internal implementation should be a pointer.
func swapTwoInts(inout a: Int, inout b: Int) { let temporaryA = a a = b b = temporaryA } var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt, &anotherInt) println("someInt is now \(someInt), and anotherInt is now \(anotherInt)") // prints "someInt is now 107, and anotherInt is now 3"
Function type, you can use functions as parameters and return values like js
func addTwoInts(a: Int, b: Int) -> Int { return a + b } //The function type is (Int, Int) -> Intfunc multiplyTwoInts(a: Int, b: Int) -> Int { return a * b }//The function type is (Int, Int) -> Int //Receive a function type named mathFunctionfunc printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) { println("Result: \(mathFunction(a, b))") } printMathResult(addTwoInts, 3, 5) // prints "Result: 8" //Return function typefunc stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 } func chooseStepFunction(backwards: Bool) -> (Int) -> Int { return backwards ? stepBackward : stepForward } var currentValue = 3 let moveNearerToZero = chooseStepFunction(currentValue > 0) // moveNearerToZero now refers to the stepBackward() function
Closure
A function is called a closure together with a variable of the context it contains. Such as sort function:
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"] func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } var reversed = sort(names, backwards) println(reversed) // reversed is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]s
Use closures can be expressed as:
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"] var reversed = sort(names, {(s1:String, s2:String) -> Bool in return s1 > s2 }) println(reversed) // reversed is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
It can also be simplified to
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"] var reversed = sort(names, { s1, s2 in s1 > s2 } ) println(reversed)
enumerate
By the following syntax statement
enum Barcode { case UPCA(Int, Int, Int) = (1,2,3) case QRCode(String) = "hello" }
Classes and structures
It is recommended to use capital letters to name them
struct Resolution { var width = 0 var heigth = 0 } class VideoMode { var resolution = Resolution() var interlaced = false var frameRate = 0.0 var name: String? }
Generate an instance:
let someResolution = Resolution() let someVideoMode = VideoMode()
Attribute access and modification, use. Syntax:
println("The width of someVideoMode is \()") = 12880 println("The width of someVideoMode is now \()")
The structure has an automatic member initializer, but the class instance does not:
let vga = resolution(width:640, heigth: 480)
Structures and enumerations are both value types, and classes are reference types
For values that reference the same instance, you can use === and !== to make judgments
Delay attribute, @lazy, set to initialize specific attributes when called
class DataImporter { /* DataImporter is a class that imports data from external files. This class will take a lot of time to initialize. */ var fileName = "" // This provides data import function} class DataManager { @lazy var importer = DataImporter() var data = String[]() // This provides data management functions} let manager = DataManager() += "Some data" += "Some more data" // The importer property of the DataImporter instance has not been created yet
Classes, structures, and enumerations can be set and getter.
struct AlternativeRect { var origin = Point() var size = Size() var center: Point { get { let centerX = + ( / 2) let centerY = + ( / 2) return Point(x: centerX, y: centerY) } set { //The setter does not define the parameter name that represents the new value, so the default name newValue can be used. = - ( / 2) = - ( / 2) } } }
Remove get and set
Attribute monitoring can be handled using willset and didset
Type attributes are a bit like static variables declared with static keywords
struct SomeStructure { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { // Return an Int value here } }
Subscript
Classes, structures, and enums can all have subscripts, and it adds a shortcut to them, as follows:
struct TimesTable { let multiplier: Int subscript(index: Int) -> Int { return multiplier * index } } let threeTimesTable = TimesTable(multiplier: 3) println("3of6Double yes\(threeTimesTable[6])") // Output "6 times 3 is 18"
inherit
Define a class
class Vehicle { var numberOfWheels: Int var maxPassengers: Int func description() -> String { return "\(numberOfWheels) wheels; up to \(maxPassengers) passengers" } init() { numberOfWheels = 0 maxPassengers = 1 } }
Inheritance class
class Bicycle: Vehicle { init() { () numberOfWheels = 2 } }
Rewrite properties and methods
class Car: Vehicle { var speed: Double = 0.0 override var speed: Double { get { return } set { = min(newValue, 40.0) } } init() { () maxPassengers = 5 numberOfWheels = 4 } override func description() -> String { return () + "; " + "traveling at \(speed) mph" } }
Prevent rewriting, add the keyword @final before methods and attributes, and errors will occur during compilation
Constructor
You can write multiple inits in the statement, which is a bit like overloading
struct Celsius { var temperatureInCelsius: Double = 0.0 init(fromFahrenheit fahrenheit: Double) { temperatureInCelsius = (fahrenheit - 32.0) / 1.8 } init(fromKelvin kelvin: Double) { temperatureInCelsius = kelvin - 273.15 } } let boilingPointOfWater = Celsius(fromFahrenheit: 212.0) // Yes 100.0let freezingPointOfWater = Celsius(fromKelvin: 273.15) // Yes 0.0”
Class destruction
Some places are called anti-initialization, a very awkward name
class Player { var coinsInPurse: Int init(coins: Int) { coinsInPurse = (coins) } func winCoins(coins: Int) { coinsInPurse += (coins) } deinit { (coinsInPurse) } } var player = Player(coins:200) player = nil //Calling the deinit method
Extended
For classes, structures, enums, everything they can be expanded
class Player{ var age:Int } extension Player{ func repetitions(task: () -> ()) { for i in 0..self { task() } } }
protocol
It's actually an interface description
protocol SomeProtocol { var mustBeSettable: Int { get set } var doesNotNeedToBeSettable: Int { get } func someTypeMethod() }
Agreement inheritance
protocol InheritingProtocol: SomeProtocol, AnotherProtocol { // protocol definition goes here }
Generics
The generic version of this function uses node type naming (usually represented by the letter T in this case) instead of the actual type name (such as Int, String, or Double). The node type name does not mean that T must be of any type, but it stipulates that a and b must be T of the same type, regardless of whether T represents any type. Only the actual type passed in by the swapTwoValues function every time it is called determines the type represented by T.
func swapTwoValues<T>(inout a: T, inout b: T) { let temporaryA = a a = b b = temporaryA }
Operator overloading
Here is a demonstration of overloading + operator
struct Vector2D { var x = 0.0, y = 0.0 } @infix func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: + , y: + ) }
- Prefix
- Post-operator @postfix
- Combination assignment operator @assignment
- Comparison operator @infix
@prefix @assignment func ++ (inout vector: Vector2D) -> Vector2D { vector += Vector2D(x: 1.0, y: 1.0) return vector }
Custom operators
Personalized operators can only use these characters /= - + * % < >! & | ^. ~
operator prefix +++ {} @prefix @assignment func +++ (inout vector: Vector2D) -> Vector2D { vector += vector return vector }
The value of association is none by default, and can be left, right, and none by default, and the priority is 100 by default.
operator infix +- { associativity left precedence 140 } func +- (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: + , y: - ) } let firstVector = Vector2D(x: 1.0, y: 2.0) let secondVector = Vector2D(x: 3.0, y: 4.0) let plusMinusVector = firstVector +- secondVector // The value of plusMinusVector at this time is (4.0, -2.0)
From: