Skip to content

Instantly share code, notes, and snippets.

@prespondek
Last active January 29, 2019 04:41
Show Gist options
  • Save prespondek/5c50a817a112e8311f7add7dcbfbbac2 to your computer and use it in GitHub Desktop.
Save prespondek/5c50a817a112e8311f7add7dcbfbbac2 to your computer and use it in GitHub Desktop.
Swift Cheat Sheet
// Swift cheat sheet.
// Comparision of Swift to C++
// I used "Learning Swift - buidling apps for macOS, iOS and Beyond" book for reference
// comment
/* comment
*/
// all the basic comparisons and arthmetic work the same a cpp + - / * || && etc
// these dont work ++, --
// swift is unicode aware so you can use characters beyond 8bit char
// Basic types are Int, Bool, Double, String
// Swift uses both the carriage return and ; as command delimiters
// Swift uses {} to delimit functions.
var variable = 1 // mutable variable.
let variable = 1 // const variable
// swift is a statically typed language. "var" and "let" work like "auto" in cpp
var variable : Int = 1 //explictly definied type
let variable : Int = 1 //explictly definied const type
// explictly definied variables do not have to be initialised but the error used before assigned
let const_array = [1,2,3]
var mutable_array: [Int] = [1,2,3] // explicitly definied
var empty_array = [Int]() // empty array
// accessing arrays works the same as cpp
mutable_array.append(1)
mutable_array.remove(at:2) // removes second element
mutable_array.insert(3,at:2) // inserts element at index
mutable_array.count()
let tuple (0,"text") // swift supports tuples
tuple.0 // get value at index
let named_tuple = (first:0, last:"text") // label index
tuple.last // get value using label
var sets = Set<String>() // empty set
var sets : Set = ["one","two","three"]
var dict = ["first": "foo",
"second": "bar"] // swift supports dictionaries
set.index(of:"two") // returns index of element with value
dict["first"] //get variable at "first"
dict.removeValue(forKey:"first") // remove value with index "first"
if i > 2 { // if statments are the same minus the brakets
} else if i > 1 {
} else {}
for element in array {} // iterate through an array
for number in 1 ..< 10 {} // ... generates a range. ..< exclude the last number defined
for number in stride(from:0,to:1,by:0.1) {} // stride increment by 0.1. 0 to 0.9
for number in stride(from:0,through:1,by:0.1) {} // 0 through 1.0
for number in "word" {} // iterate through characters in string
while var count = 0 < 10 {} // while loops are the same. swift allows you to define variables inline
switch var idx = 0 {
case 0:
case 1:
fallthrough // unlike cpp case statments break by default, fallthrough allows old behaviour
case 2...4 // you can use range statments
case 5:
default:
} // switch also works for strings unlike cpp
//...
case (1, _): // switch also works for tuples. The underscore is a wildcard and will match with anything
case (1, let string): // you can also capture the wildcard elements for use within the case statement.
enum enumeration : CaseIterable { // enums raw type can be defined. In cpp this is always an int.
case ENUM1 = 1, ENUM2, ENUM3,
case ENUM4 (value: Int) // you can associate variables with enums. This is VERY different from cpp
case ENUM5 = "string" // raw value to enum can be any type
indirect case ENUM6(enumeration) {} // indirect allows associated value be same type as the enumeration.
}
let state = enumeration.ENUM4(value:5) // you need to use the enum variable name to get scope unlike cpp
state = .ENM3 // once intitalised as an enum the type name can infered.
state.rawValue // get the value associated with enum. raw values must be the same type.
enumeration.allCases.count // with CaseIterable we can get the number of enum variants.
let num_string = String(Int(1.22)) // cast works like cpp
var optional : Int? = nil // variables can't be nil unless the ? is added. It becomes a optional type. Effectly this a cpp pointer.
var new_var : Int = optional! // optionals need to be unwrapped (dereferenced in cpp speak) to use them. Will crash if nil.
var optional : Int! // this is the same as an optional but pointer will be dereferenced by default.
if let check = optional {} // another way of check if a the value is not nil is to assign it to a non optional variable
let count = optional?.count // using the ? instead of ! will return a nil rather than crash if one of the reference chain is nil.
val variable = optional["one"] ?? "unspecified" // if a value doesn't exist or is nil you can use a default rather than crash.
val variable = optional["one", default: "unspecified"] // a different way of doing the same thing.
val dict : [String:Any] = ["one":"one", "two":2, "three":3.0] // Any allows you to assign a value of Any type. I'm assuming this works like a union in cpp
if dict["one"] is String {} // check the variables type
var variable = dict["one"] as? String // return a pointer if value is String
// Functions
func function (first: Int, second: Int) {} // function
function (first:1,second:1) // call previous function
func function (_ first: Int, _ second: Int) {} // you don't need to use value names when calling
function (1,1) // this is now allowed
func function (first val1: Int, second val2: Int = 2) {} //override value names and assign default values
func function () -> Int {
return 1
} // function returns a value of Int
func function () -> (first: Int, second: Int) {} // functions can also return tuples
func variadic (values: Any...) {} // pass as many values as you like
func function () -> (first: inout Int, second: inout Int) {} // required to pass by reference
function (first: &val1, second: &val2) // pass by reference
// Function Pointers
var func_pointer : (Int,Int) -> Int // this is the same as a cpp function pointer
func function (func_label: (Int)->Int) -> Int // copy function pointer into another function
function (func_label: func_pointer)
func function() -> (Int) -> Int { // you can return a function pointer
var variable = 0
func inner_func(number: Int) -> Int { // functions can be defined in other functions
return variable + number // functions can capture variables from the outer scope
}
return inner_func // functions can be returned
}
// Closures
// Swift seems to define some special keywords to break the one command per line rule. This allows you to have some really small functions.
func function(by: (Int,Int) -> Bool) {}
function(by: {(n1 Int, n2 : Int) -> Bool in return n1 > n2}) // "in" allows return to be on same line.
function(by: {n1,n2 in return n1 > n2}) // but function definiton can be assumed.
function(by: {n1,n2 in n1 > n2}) // you can omit return if the function is only a one line comparison.
function(by: {$0 > $1}) // you can omit the variable name and use indices with $.
var function = {(n1 Int, n2 : Int) -> Bool in n1 > n2} // they can be used like a normal function pointer
defer {} // any instructions in the defer block will be run at the end of the outer block. If "defers" the instuction to the end of the scope.
guard i + 1 == 2 else {} // guard works exactly like assert in cpp.
// Object Oriented Programming
// I should be noted that, like Objective C, swift avoids multiple inheritence problems by only allowing a class to inherit
// from one other class, but can inherit from multiple protocols.
// protocols are like a pure abstract class in cpp. They can not explicitly define data though.
protocol Vehicle {
var numWheels : Int { get } // define privacy of member variables
var isMoving : Bool { get, set }
func move (speed: Int) // pure virtual function (no definition)
}
// structures is swift seem to have a similar purpose to their cpp kin.
// To that end apple have changed some characteristic which destiguish them from classes.
// Structures can only inherit from protocols. Unlike classes they are value types so they a copied rather than referenced.
struct Engine {
var valves : Int
var cylinders : Int
mutating func removeValve() { self.valves -= 1 } // structs and enums methods are const by default. "mutating" allow you to modify member values.
subscript(row: Int, column: Int) -> Int { // subscipts allow you to access any struct, class or enum using the [] operator
get {}
set(newValue) {}
}
}
var engine = Engine(valves:1,cylinders:1) // memberwise initialisator.. classes can't do this without a constructor
class Carrage {
required init() {} // it is required that this initialiser is called
var num_passangers
func removePassanger () {}
}
// Unlike most other types, class are reference values.
// This means references to the same class instance can be stored in multiple places using ARC.
class Car : Carrage, Vehicle // classes can inherit from multiple protocols and one other classes
{
var color : String // member variable
lazy var engine : Engine() // lazy vars are not created until they are accessed
override removePassanger () { // override function in Carrage
super.removePassanger() // call overridden function
}
final func brake () {} // final functions can not be overridden.
var owner : String? { // optional owner
willSet(newValue) {} // observer functions are called before and after a member variable is modified
didSet {
if owner != oldValue {}
}
}
init(wheels: Int) {} // constructor
convenience init (color: String) { // overided constructor
self.init(4)
}
convenience init? (speed: Int) { // the allows constructor to fail and return nil
return nil
}
deinit() {} // destructor
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment