Swift
Swift is a powerful and intuitive programming language developed by Apple for building iOS, macOS, watchOS, and tvOS applications. Introduced in 2014, Swift is designed to be modern, safe, and efficient. It incorporates elements from various programming languages and aims to provide a seamless development experience for both beginners and experienced developers.
Getting Started
To get started with Swift, you can use the Swift Playgrounds app on macOS or iPadOS, or you can use the Swift REPL on Linux. You can also use the Xcode IDE on macOS, which includes a Swift compiler and a visual interface builder.
To run swift code on linux or windows, you can use docker to run a swift container:
docker run -it --rm --volume .:/app --name learn-swift swift swift /app/app.swift
Another way:
docker run -dit --volume .:/app --name learn-swift swift
docker exec learn-swift swift /app/app.swift
Topics
- Variables
- Primitive types
- Operators
- String
- Collections
- Conditional Statements
- Loops
- Functions
- Structs
- Enums
Variables
//variables
var myVariable = 42
//constant
let myConstant = 42
//type annotations
var myVariable2: Double = 70
Primitive types
var a: String = "Hello, World!"
var b: Int = 10
var c: Double = 10.5
var d: Bool = true
var e: Character = "A"
var f: Float = 10.5
//optional
var h: String? = nil
print(type(of: a))
print(type(of: b))
print(type(of: c))
print(type(of: d))
print(type(of: e))
print(type(of: f))
print(type(of: h))
Operators
//arithmetics operators
var a = 10
var b = 20
var c = a + b
var d = a - b
var e = a * b
var f = a / b
var g = a % b
//comparison operators
var h = a == b
var i = a != b
var j = a > b
var k = a < b
var l = a >= b
var m = a <= b
//logical operators
var n = true && false
var o = true || false
var p = !true
//assignment operators
var q = 10
q += 10
q -= 10
q *= 10
q /= 10
q %= 10
//range operators
var r = 1...10
var s = 1..<10
//ternary conditional operator
var t = a > b ? "a is greater than b" : "a is less than or equal to b"
//nil-coalescing operator
var u: String? = nil
var v = u ?? "default value"
String
//simple string
var str = "Hello, playground"
//concatenation
var str1 = "Hello"
var str2 = "World"
var str3 = str1 + " " + str2
//string interpolation
var name = "John"
var age = 25
var message = "My name is \(name) and I am \(age) years old."
//multiline string
var str4 = """
This is a multiline string.
It can contain multiple lines.
"""
//unicode
var heart = "\u{1F496}"
//empty string
var emptyString = ""
//check if string is empty
if emptyString.isEmpty {
print("String is empty")
}
//string length
var str5 = "Hello, World!"
print("Length of str5 is \(str5.count)")
//accessing characters
var str6 = "Hello, World!"
print(str6[str6.startIndex])
print(str6[str6.index(before: str6.endIndex)])
print(str6[str6.index(after: str6.startIndex)])
print(str6[str6.index(str6.startIndex, offsetBy: 7)])
//inserting and removing
var str7 = "Hello"
str7.insert("!", at: str7.endIndex)
print(str7)
str7.remove(at: str7.index(before: str7.endIndex))
print(str7)
//substring
var str8 = "Hello, World!"
let index = str8.firstIndex(of: ",") ?? str8.endIndex
let newStr = str8[..<index]
let newStr2 = str8[index...]
//compare strings
var str9 = "Hello"
var str10 = "Hello"
if str9 == str10 {
print("Strings are equal")
}
//prefix and suffix
var str11 = "Hello, World!"
if str11.hasPrefix("Hello") {
print("String starts with Hello")
}
if str11.hasSuffix("World!") {
print("String ends with World!")
}
//uppercase and lowercase
var str12 = "Hello, World!"
print(str12.uppercased())
print(str12.lowercased())
//replacing
var str13 = "Hello, World!"
print(str13.replacingOccurrences(of: "Hello", with: "Hi"))
//splitting
var str14 = "Hello, World!"
print(str14.split(separator: ","))
print(str14.split(separator: ",", maxSplits: 1))
print(str14.split(separator: ",", omittingEmptySubsequences: false))
Collections
Array: In swift, arrays are used to store ordered lists of values of the same type. Arrays are zero-indexed, which means the first element is at index 0, the second element is at index 1, and so on.
// array
var arr = [1,2,3,4,5]
// type array
var arr1: [Int] = [1,2,3,4,5]
// add elements
arr.append(6)
// remove elements
arr.remove(at: 0)
// count elements
arr.count
// check if empty
arr.isEmpty
// get element
arr[0]
// set element
arr[0] = 10
//loop
for i in arr {
print(i)
}
//map
arr.map { (i) -> Int in
return i * 2
}
//filter
arr.filter { (i) -> Bool in
return i % 2 == 0
}
//reduce
arr.reduce(0) { (result, i) -> Int in
return result + i
}
Sets: In swift, sets are used to store distinct values of the same type. Sets are unordered collections of unique elements.
//create an set
var set: Set = [1, 2, 3, 3, 4, 5, 5]
//print set length
print(set.count) // 5
//check if empty
print(set.isEmpty) // false
//add element
set.insert(6)
//remove element
set.remove(1)
//loop
for i in set {
print(i)
}
//map
let mappedSet = set.map { (i) -> Int in
return i * 2
} // [4, 6, 8, 10, 12]
//filter
let filteredSet = set.filter { (i) -> Bool in
return i % 2 == 0
} // [2, 4, 6]
//reduce
let reducedSet = set.reduce(0) { (result, i) -> Int in
return result + i
}// 20
Dictionary: In swift, dictionaries are used to store key-value pairs of the same type. Dictionaries are unordered collections of key-value associations.
var capitalCity = [
"Indonesia": "Jakarta",
"Japan": "Tokyo",
"Korea": "Seoul",
"China": "Beijing"
]
//typed collection
var capitalCity: [String: String] = [
"Indonesia": "Jakarta",
"Japan": "Tokyo",
"Korea": "Seoul",
"China": "Beijing"
]
//empty dictionary
var capitalCity = [String: String]()
var capitalCity: [String: String] = [:]
//add element
capitalCity["USA"] = "Washington"
capitalCity["England"] = "London"
//remove element
capitalCity.removeValue(forKey: "USA")
//count elements
capitalCity.count
//check if empty
capitalCity.isEmpty
//get element
capitalCity["Indonesia"]
//loop
for (country, city) in capitalCity {
print("\(country) : \(city)")
}
//map
capitalCity.map { (country, city) -> String in
return "\(country) : \(city)"
}
//filter
capitalCity.filter { (country, city) -> Bool in
return country == "Indonesia"
}
//update value
capitalCity.updateValue("Jakarta Baru", forKey: "Indonesia")
//get keys
capitalCity.keys
//get values
capitalCity.values
Tuple: is a group of values combined into a single value. Tuples are useful for temporary groups of related values.
var product = ("Ice Cream", 3.99)
// get element
product.0
product.1
// update value
product.0 = "Ice Cream Baru"
//destructure
let (name, price) = product
//tuple with label
var product = (name: "Ice Cream", price: 3.99)
// get element
product.name
product.price
// update value
product.name = "Ice Cream Baru"
// loop
for (key, value) in product {
print("\(key) : \(value)")
}
// nested tuple
var product = (name: "Ice Cream", price: (3.99, 4.99))
// get element from nested tuple
product.name
product.price.0
product.price.1
// dictionary inside tuple
var product = (name: "Ice Cream", price: ["small": 3.99, "large": 4.99])
// get element from dictionary inside tuple
product.name
product.price["small"]
product.price["large"]
Conditional Statements
let a = 5
// if statement
if a < 10 {
print("a is less than 10")
} else {
print("a is greater than or equal to 10")
}
// if-else if-else statement
if a < 10 {
print("a is less than 10")
} else if a < 20 {
print("a is less than 20")
} else {
print("a is greater than or equal to 20")
}
// switch statement
switch a {
case 0:
print("a is 0")
case 1:
print("a is 1")
case 2:
print("a is 2")
case 3:
print("a is 3")
default:
print("a is greater than 4")
}
//ternary conditional operator
let b = a < 10
? "a is less than 10"
: "a is greater than or equal to 10"
Loops
//for loop
for index in 1...5 {
print("\(index) times 5 is \(index * 5)")
}
//while loop
var index = 1
while index <= 5 {
print("\(index) times 5 is \(index * 5)")
index += 1
}
//repeat-while loop
index = 1
repeat {
print("\(index) times 5 is \(index * 5)")
index += 1
} while index <= 5
Functions
//function
func printName(name: String){
print("Hello, \(name)")
}
//function with return value
func add(a: Int, b: Int) -> Int {
return a + b
}
//function with multiple return values
func getMinMax(arr: [Int]) -> (min: Int, max: Int) {
var min = arr[0]
var max = arr[0]
for value in arr {
if value < min {
min = value
} else if value > max {
max = value
}
}
return (min, max)
}
//function with variadic parameters
func sum(numbers: Int...) -> Int {
var total = 0
for number in numbers {
total += number
}
return total
}
//function with default parameter value
func greet(name: String, msg: String = "Good morning!") {
print("Hello, \(name), \(msg)")
}
//function with inout parameters
//inout parameters can be modified within the function
//and the changes are reflected in the original value
func swap(a: inout Int, b: inout Int) {
let temp = a
a = b
b = temp
}
var x = 10
var y = 20
swap(&x, &y) // x = 20, y = 10
//function with return value as optional
func divide(a: Int, b: Int) -> Int? {
if b == 0 {
return nil
}
return a / b
}
//function with nested function
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backward ? stepBackward : stepForward
}
//function with function as parameter
func printResult(_ function: (Int, Int) -> Int, a: Int, b: Int) {
let result = function(a, b)
print("Result: \(result)")
}
//function with function as return value
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
return backward ? stepBackward : stepForward
}
Structs
//simple struct
struct Person {
var name: String
var age: Int
}
var p = Person(
name: "John",
age: 25
)
//print the properties of the instance
print(p.name) //John
print(p.age) //25
//change the properties of the instance
p.name = "Bob"
p.age = 30
//structs with default values
struct Employee {
var name: String = "Unknown"
var age: Int = 0
}
//structs with computed properties
struct Circle {
var radius: Double = 0.0
var area: Double {
return 3.14 * radius * radius
}
}
var c = Circle(radius: 5.0)
print(c.area) //78.5
//structs with property observers
struct Progress {
var task: String
var amount: Int {
didSet {
print("\(task) is now \(amount)% complete")
}
}
}
var p = Progress(task: "Loading data", amount: 0)
p.amount = 30
p.amount = 80
p.amount = 100
//structs with property observers
struct Progress {
var task: String
var amount: Int {
didSet {
print("\(task) is now \(amount)% complete")
}
}
}
var p = Progress(task: "Loading data", amount: 0)
p.amount = 30
p.amount = 80
p.amount = 100
//structs with type property
struct Circle {
static let pi = 3.14
var radius: Double
var area: Double {
return Circle.pi * radius * radius
}
}
print(Circle.pi) //3.14
var c = Circle(radius: 5.0)
print(c.area) //78.5
//structs with type method
struct Math {
static func abs(number: Int) -> Int {
if number < 0 {
return -number
}
return number
}
}
print(Math.abs(number: -35)) //35
print(Math.abs(number: 40)) //40
//structs with access control
struct Person {
var name: String
private var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
func display() {
print("Name: \(name), Age: \(age)")
}
}
var p = Person(name: "John", age: 25)
p.display() //Name: John, Age: 25
print(p.name) //John
print(p.age)
//Error: 'age' is inaccessible due to 'private' protection level
Enums
//example of enum
enum CompassPoint {
case north
case south
case east
case west
}
var directionToHead: CompassPoint = CompassPoint.west
print(directionToHead)
//enum with switch
directionToHead = .south
switch directionToHead {
case .north:
print("Lots of planets have a north")
case .south:
print("Watch out for penguins")
case .east:
print("Where the sun rises")
case .west:
print("Where the skies are blue")
}
//enum with raw value
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
let earthsOrder = Planet.earth.rawValue
print(earthsOrder) // 3
//enum with raw value
enum CompassPoint2: String {
case north, south, east, west
}
let sunsetDirection = CompassPoint2.west.rawValue
print(sunsetDirection) // west
//enum iterable
enum Beverage: CaseIterable {
case coffee, tea, juice
}
for beverage in Beverage.allCases {
print(beverage)
}
//enum associated value
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
print("QR code: \(productCode).")
}