Last active
August 3, 2018 19:29
-
-
Save igavrysh/bde82c9c0f6afa000bc822e6569b0dea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created by Ievgen Gavrysh on 7/30/18. | |
// http://github.com/igavrysh | |
// | |
// This gist is created to show down-to-basics way of handling | |
// Swift optionals. | |
// | |
// No syntax sugar is used and only common and basic Swift language structures | |
// are applied. That includes but not limited to generics and high order functions. | |
// I believe that starting learning Swift Optionals from this sample if far | |
// more correct and easier then with features Apple included into Swift in order to | |
// make it look 3S language: short, smart and sexy, but also sophisticated. | |
// | |
// When Swift novice tries to experiment with "?", "!", "if let", "guard" and "??" | |
// he scratches his head and asks why let t: Int? = 3 works great and wise versa | |
// e.g. let t2: Int = t does not, by droping vague error message: | |
// > Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'? | |
// (⭐️ this script to make me write another one gist explaing exact reason | |
// why does it happen?) | |
// | |
// Be ready to find out the truth about Optional Handling in Swift in lines below | |
// | |
// In the Stage 7 you can find a fast and sexy Swift. Definately the great | |
// way to write and handle Swift Optionals staff as long as you understand | |
// everything above line 133 and maybe even more | |
// | |
// ==================== STAGE 0 - Problem Setup ================================ | |
import Foundation | |
// Define Coin class | |
class Coin { | |
var name: String | |
var imageName: String | |
var country: Country | |
init(name: String, imageName: String, country: Country) { | |
self.name = name | |
self.imageName = imageName | |
self.country = country | |
} | |
} | |
// Define Country class | |
class Country { | |
var name: String | |
var flagImageName: String | |
init(name: String, flagImageName: String) { | |
self.name = name | |
self.flagImageName = flagImageName | |
} | |
} | |
// Make Country print more user-friendly | |
extension Country: CustomStringConvertible { | |
var description: String { | |
return "{country: \(self.name) flagImageName: \(self.flagImageName)}" | |
} | |
} | |
// Make Coin print more user-friendly | |
extension Coin: CustomStringConvertible { | |
var description: String { | |
return "{coin: \(self.name) imageName: \(self.imageName) country: \(country)}" | |
} | |
} | |
// Get Country by name from countries array passed as an argument | |
// If there is no matched country return nil | |
// Otherwise return optional wrapped country that matched | |
func getCountry(named name:String, from counries: Array<Country>) | |
-> Optional<Country> | |
{ | |
return counries | |
.filter({ (country: Country) -> Bool in | |
return country.name == name | |
}) | |
.first | |
} | |
// ==================== STAGE 1 - Create countries ============================= | |
// Create empty Array of countries that will store Country objects | |
var countries: Array<Country> = Array<Country>.init() | |
// Add Ukraine to countries array | |
countries.append(Country.init(name: "Ukraine", flagImageName: "ukraine_flag")) | |
// Add the USA to countries array | |
countries.append(Country.init(name: "USA", flagImageName: "usa_flag")) | |
// ==================== STAGE 2 - Create coins ================================= | |
// Create empty Array of coins that will store Coin objects | |
var coins: Array<Coin> = Array<Coin>.init() | |
// ==================== STAGE 3 - Get "USA"-named country ====================== | |
// Get a countryOptional with the USA name | |
var countryOptional: Optional<Country> = getCountry(named: "USA", from: countries) | |
// ==================== STAGE 4 - Create Empty coinOptional ==================== | |
// Create Optional wrapped Coin - coinOptional. Fill it with none value | |
var coinOptional: Optional<Coin> = Optional<Coin>.none | |
// ==================== STAGE 5 - Analyze countryOptional ====================== | |
// =========== if it is not empty, then create coin with that country ========== | |
// =========== if it is empty, then do nothing ================================= | |
// Check if we found a country with a name USA by checking countryOptional value | |
// * if yes, then unwrap it | |
// * if no go out of switch with a break statement | |
switch countryOptional { | |
// * if we fail to find country with a name of USA go out | |
case .none: | |
break | |
// * if we find country with a name of USA then | |
case .some(let unwrappedCountry): | |
// create 25 coint, use found unwrapped country for the name USA | |
// in coin initialization | |
coinOptional = Optional<Coin> | |
.some( | |
Coin.init( | |
name: "25_cents", | |
imageName: "25_cents_usa", | |
country: unwrappedCountry | |
) | |
) | |
} | |
// ======= STAGE 6 - Analyze coinOptional created with countryOptional ========= | |
// =========== if it is not empty, then add it to coins array ================== | |
// =========== if it is empty, then do nothing ================================= | |
// * if we managed to fill coinOptional witn a some Coin value, then add | |
// unwrapped coin to coins array | |
// * if we fail to fill coinOptional with a some Coin value, then do nothing | |
// with break statement | |
// e.g. just exit switch statement WITHOUT adding any coin to coins array | |
switch coinOptional { | |
case .none: | |
break | |
case .some(let unwrappedCoin): | |
coins.append(unwrappedCoin) | |
} | |
// ======== STAGE 7 - The fastest way of doing things ============================ | |
// ======== add new coin of America, using Swift syntax sugar ================== | |
_ = getCountry(named: "USA", from: countries) | |
.map { Coin(name: "1_cent", imageName: "1_cent_usa", country: $0) } | |
.map { coins.append($0) } | |
// ========= STAGE 8 - Print out all coins stored in coins array =============== | |
print(coins) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment