Skip to content

Instantly share code, notes, and snippets.

@ZenkieBear
Last active November 13, 2023 08:51
Show Gist options
  • Save ZenkieBear/7e0ba499f32870cd86de9797bbc7b999 to your computer and use it in GitHub Desktop.
Save ZenkieBear/7e0ba499f32870cd86de9797bbc7b999 to your computer and use it in GitHub Desktop.
learn-swift
print("Hello, world")
// Prints "Hello, world
// Simple Values
var myVariable = 18
myVariable = 33
let myConstant = 18
//print(myVariable, myConstant)
// Type Infer
let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
let explicitFloat: Float = 4
//print(implicitInteger, implicitDouble, explicitDouble, explicitFloat)
// Explicitly Convert Type
let label = "This width is "
let width = 94
let widthLabel = label + String(width)
//print(widthLabel)
// \() expression
let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) frruits."
let price = 5.2
let applePrice = "Apple's price is \(price)"
let zenkie = "Zenkié Bear"
let greetingZenkie = "Salut, \(zenkie)!"
//print(appleSummary, fruitSummary, greetingZenkie, separator: "\n")
// Multiple line string
let quotation = """
Even though there's whitespace to the left,
the actual lines aren't indented.
Except for this line.
Double quotes (") can appear without being escaped.
I still have \(apples + oranges) pieces of fruit.
"""
//print(quotation)
// Arrays and Dictionaries
var fruits = ["strawberries", "limes", "tangerines"]
fruits[1] = "grapes"
var occupations = [
"Zenkie": "Programmer",
"Tayler": "Singer"
]
occupations["Bobo"] = "Product Designer"
//print(fruits, occupations, separator: "\n")
// Appending, array auto grows
fruits.append("blueberries")
//print(fruits)
// Write an empty array or dictionary
fruits = []
occupations = [:]
// Define to an initial constant
let emptyArray: [String] = []
let emptyDictionary: [String: String] = [:]
//print(fruits, occupations, emptyArray, emptyDictionary)
// Control Flow
//let individualScores = [75, 43, 30, 87, 12]
let individualScores = [75, 43, 80, 87, 12]
var teamScore = 0
for score in individualScores {
if score > 50 {
teamScore += 3
} else {
teamScore += 1
}
}
//print(teamScore)
// if after =
let scoreDecoration = if teamScore > 10 {
"🎉"
} else {
"🙂"
}
//print("Score", teamScore, scoreDecoration)
// Optional value
var optionalString: String? = "Hello"
//print(optionalString == nil)
var optionalName: String? = "Zenkie Bear"
optionalName = nil
var greeting = "Hello!"
//if optionalName != nil {
// let name = optionalName
if let name = optionalName { // equal to previous 2 lines
// if the optionName is nil, this block won't be execute
greeting = "Hello, \(name)"
}
//print(greeting)
// ?? operator
let nickname: String? = nil
let fullName: String? = "John Appleseed"
let informalGreeting = "Hi \(nickname ?? fullName)"
//print(informalGreeting)
if let nickname {
print("Hey, \(nickname)")
}
// Switch
let vegetable = "green pe pper"
switch vegetable {
case "celery":
print("Add some raisins and make ants on the log.")
case "cucumber", "watercress":
print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
print("Is it a spicy \(x)?")
default:
print("Everthing tastes good in soup.")
}
// for-in literate
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
for (type, numbers) in interestingNumbers {
var largest = 0
for number in numbers {
if number > largest {
largest = number
}
}
// print("\(type)'s largest is \(largest)")
}
// while loop
var n = 2
while n < 0 {
n *= 2
}
print(n)
var m = 2
repeat {
m *= 2
} while m < 0
print(m)
var total = 0
for i in 0..<4 {
total += i
}
print(total) // 0 + 1 + 2 + 3 = 6
// Functions and Closures
func greet(_ person: String, on lunch: String) -> String {
return "Hello \(person), today's lunch is \(lunch)."
}
//print(greet("Bobo", on: "Beef"))
// Tuples
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int, avg: Double) {
var min = scores[0], max = scores[0], sum = 0
for score in scores {
if score > max {
max = score
}
if score < min {
min = score
}
sum += score
}
var avg = Double(sum) / Double(scores.count)
return (min, max, sum, avg)
}
let staticts = calculateStatistics(scores: [5, 3, 100, 3, 9])
//print(staticts)
//print(staticts.2)
// Nested function
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
print(returnFifteen())
// Function variable
func useIncrementer() -> ((Int) -> Int) {
func addOne(_ number: Int) -> Int {
return number + 1
}
return addOne
}
var incrementer = useIncrementer()
print(incrementer(7))
// Function parameter type
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThan10(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 17, 12]
print(hasAnyMatches(list: numbers, condition: lessThan10))
// Anounymous function
print(numbers.map({(number: Int) -> Int in
if (number % 2 == 1) {
return 0
}
let result = 3 * number
return result
}))
// concisely
let mappedNumbers = numbers.map({number in number * 3})
//print(mappedNumbers)
// Refering to parameter by number
//let sortedNumbers = numbers.sorted (by: { $0 > $1 })
let sortedNumbers = numbers.sorted { $0 > $1 }
//print(sortedNumbers)
// Objects and Classes
class Shape {
var numberOfSides = 0
let name = "Zenkie Bear"
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
func getName() -> String {
return name
}
}
var shape = Shape()
shape.numberOfSides = 7
//print(shape.simpleDescription(), shape.getName())
// Initializer & self
class NamedShape {
var numberOfSides = 0
let name: String
init(_ name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
func getName() -> String {
return self.name
}
}
var namedShape = NamedShape("Zenkié Bear")
namedShape.numberOfSides = 7
//print(namedShape.simpleDescription(), namedShape.getName())
// Extend & Override
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name)
numberOfSides = 4
}
func area() -> Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A square with sides of length \(sideLength)."
}
}
let square = Square(sideLength: 5.2, name: "my test square")
//print(square.area(), square.simpleDescription())
// Experiment
class Circle: NamedShape {
var radius: Double
init(radius: Double, name: String) {
self.radius = radius
super.init(name)
}
func area() -> Double {
return radius * radius * 3.14
}
override func simpleDescription() -> String {
return "A circle with radius of length \(radius)."
}
}
let circle = Circle(radius: 10, name: "my test circle")
//print(circle.area(), circle.simpleDescription())
// Getter & Setter
class EquilateralTriangle: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "A equilateral triangle with sides of length \(sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
//print(triangle.perimeter)
triangle.perimeter = 9.9
//print(triangle.sideLength)
// willSet & didSet
class TriangleAndSquare {
var triangle: EquilateralTriangle {
willSet {
square.sideLength = newValue.sideLength
}
}
var square: Square {
willSet {
triangle.sideLength = newValue.sideLength
}
}
init(size: Double, name: String) {
square = Square(sideLength: size, name: name)
triangle = EquilateralTriangle(sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "test TriangleAndSquare")
//print(triangleAndSquare.square.sideLength, triangleAndSquare.square.sideLength)
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
//print(triangleAndSquare.triangle.sideLength)
// ?. expression
var optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
optionalSquare = nil
let sideLength = optionalSquare?.sideLength ?? -1
//print(sideLength)
// Enumerations ans Structures
enum Rank: Int {
case ace = 1
case two, three, four, five, six, seven, eight, nine, ten
case jack, queen, king
func simpleDescription() -> String {
switch self {
case .ace:
return "ace"
case .jack:
return "jack"
case .queen:
return "queen"
case .king:
return "king"
default:
return String(self.rawValue)
}
}
}
let ace = Rank.ace
let aceRawValue = ace.rawValue
print(ace, aceRawValue)
// Experiment
func compareRanks(a: Rank, b: Rank) -> Bool {
return a.rawValue > b.rawValue
}
var ranks = [Rank.two, Rank.three, Rank.ace, Rank.king, Rank.eight, Rank.ten, Rank.jack]
ranks.sort(by: compareRanks)
//print(ranks)
// Create from rawValue
if let convertedRank = Rank(rawValue: 3) {
// print(convertedRank.simpleDescription())
}
// Actual values
enum Suit {
case spades, hearts, diamonds, clubs
func simpleDescription() -> String {
switch self {
case .spades:
return "spades"
case .hearts:
return "hearts"
case .diamonds:
return "diamonds"
default:
return "clubs"
}
}
func color() -> String {
switch self {
case .spades, .clubs:
return "black"
default:
return "red"
}
}
}
let hearts = Suit.hearts
let heartsDescription = hearts.simpleDescription()
print(hearts, heartsDescription)
// Experiment
print(Suit.spades.color(),
Suit.hearts.color(),
Suit.diamonds.color(),
Suit.clubs.color())
// Assign value when make instance
enum ServerResponse {
case result(String, String)
case failure(String)
}
let success = ServerResponse.result("6:00 am", "8:09 pm")
let china = ServerResponse.result("7:00 am", "5:50 pm")
let failure = ServerResponse.failure("Out of cheese.")
func printResponse(_ response: ServerResponse) {
switch response {
case let .result(sunrise, sunset):
print("Sunrise is at \(sunrise) and sunet is at \(sunset).")
case let .failure(message):
print("Failure... \(message)")
}
}
//printResponse(success)
//printResponse(china)
//printResponse(failure)
// Structure
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
}
let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
//print(threeOfSpades, threeOfSpadesDescription)
func getFullDeckCards() -> [Card] {
var result: [Card] = []
for rank in 1...13 {
for suit in [Suit.spades, Suit.hearts, Suit.diamonds, Suit.clubs] {
result.append(Card(rank: Rank(rawValue: rank) ?? Rank.ace, suit: suit))
}
}
return result
}
for card in getFullDeckCards() {
// print(card.simpleDescription())
}
// Concurrency
func fetchUserID(from server: String) async -> Int {
if server == "primary" {
return 1989
}
return 501
}
func fetchUsername(from server: String) async -> String {
let userID = await fetchUserID(from: server)
if userID == 1989 {
return "Taylor Swift"
}
return "Guest"
}
func connectUser(to server: String) async {
async let userID = fetchUserID(from: server)
async let username = fetchUsername(from: server)
let greeting = await "Hello \(username), user ID \(userID)"
// print(greeting)
}
Task {
await connectUser(to: "primary")
}
Task {
let userIDs = await withTaskGroup(of: Int.self) { taskGrop in
for server in ["primary", "test", "development"] {
taskGrop.addTask {
return await fetchUserID(from: server)
}
}
var results: [Int] = []
for await result in taskGrop {
results.append(result)
}
return results
}
// print(await userIDs)
}
// actor's methods and properties are process security
actor ServerConnection {
var server: String = "primary"
private var activeUsers: [Int] = []
func connect() async -> Int {
let userID = await fetchUserID(from: server)
activeUsers.append(userID)
return userID
}
}
Task {
let server = ServerConnection()
let userID = await server.connect()
// print(userID)
}
// Protocols and Extensions
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
func get() -> String
}
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class"
var anotherProperty = "Hi"
func adjust() {
simpleDescription += " Now 100% adjusted."
}
func get() -> String {
return simpleDescription
}
}
var a = SimpleClass()
a.adjust()
//print(a.simpleDescription)
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
// mutating means this method will change some properties of one instance
mutating func adjust() {
simpleDescription += " (adjusted)"
}
func get() -> String {
return simpleDescription
}
}
var b = SimpleStructure()
b.adjust()
//print(b.simpleDescription, b.get())
// Extension
extension Int: ExampleProtocol {
func get() -> String {
return String(self)
}
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
self += 42
}
}
//print(7.simpleDescription)
// Experiment
extension Double {
var absoluteValue: Double {
return abs(self)
}
}
let number = -5.5
let absoluteNumber = number.absoluteValue
//print(number, number.absoluteValue)
let protocalValue: any ExampleProtocol = a
print(protocalValue.simpleDescription)
print(a.anotherProperty)
//price(protocalValue.anotherProperty)
// Error handling
enum PrinterError: Error {
case outOfPaper
case onToner
case onFire
}
func send(job: Int, printName: String) throws -> String {
if (printName == "Never Has Toner") {
throw PrinterError.onToner
}
return "Job sent"
}
// do-catch
do {
// let printerResponse = try send(job: 1040, printName: "Bi Sheng")
let printerResponse = try send(job: 1040, printName: "Never Has Toner")
print(printerResponse)
//} catch {
// print(error)
} catch let e {
print(e)
}
// Experiment
do {
throw PrinterError.onToner
// throw PrinterError.onFire // I'll just put this over here, with the rest of the fire.
// throw PrinterError.outOfPaper // Printer error: outOfPaper.
} catch PrinterError.onFire {
print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
print("Printer error: \(printerError).")
} catch {
print(error)
}
// try?
let printerSuccess = try? send(job: 1989, printName: "Mergenthanler")
let printerFailure = try? send(job: 1989, printName: "Never Has Toner")
//print(printerSuccess, printerFailure)
// Defer
var fridgeIsOpen = false
let fridgeContent = ["milk", "eggs", "leftovers"]
func fridgeContains(_ food: String) -> Bool {
fridgeIsOpen = true
defer {
fridgeIsOpen = false
}
let result = fridgeContent.contains(food)
return result
}
if fridgeContains("banana") {
print("Found a banana")
}
//print(fridgeIsOpen)
// Generics
func makeArray<I>(repeating item: I, numberOfTimes: Int) -> [I] {
var result: [I] = []
for _ in 0..<numberOfTimes {
result.append(item)
}
return result
}
//print(makeArray(repeating: "Hello", numberOfTimes: 10))
// With types
enum OptionalValue<Wrapped> {
case none
case some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
//print(possibleInteger)
possibleInteger = .some(100)
//print(possibleInteger)
// where
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Element]
where T.Element: Equatable, T.Element == U.Element
{
var result: [T.Element] = []
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
result.append(lhsItem)
}
}
}
return result
}
print(anyCommonElements([1, 2, 3], [2, 3]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment