/*
Swift error represented by types that conform to Error protocol
*/
//example
enum VendingMachineErr: Error {
case invalidSelection
case insufficientMoney(coinsNeeded:Int)
case outOfStack
}
//throw VendingMachineErr.insufficientMoney(coinsNeeded: 5)
/*
functions with throws keyword throwing error
next time you call this function you have to put try keyword
*/
struct Snack{
var itemCount:Int
var itemPrice:Int
}
class VendingMachine{
var itemList=["WangLaoJi":Snack(itemCount:10,itemPrice:3),
"JiaDuoBao":Snack(itemCount:10,itemPrice:2),
"MiMi":Snack(itemCount:10,itemPrice:1)]
var coins=0
/*
var a:Snack{
get {
return itemList["MiMi"]! // remember dictionary returns optional
}
}*/
func vend(itemName:String) throws {
guard let item = itemList[itemName] else{
throw VendingMachineErr.invalidSelection
}
guard item.itemCount > 0 else{
throw VendingMachineErr.outOfStack
}
guard item.itemPrice <= coins else{
let gap = item.itemPrice - coins
throw VendingMachineErr.insufficientMoney(coinsNeeded: gap)
}
coins -= item.itemPrice
//item.itemCount -= 1 //it's value type, so doesn't count
itemList[itemName]?.itemCount -= 1// dictional returns optional
print("dispensing \(itemName)")
}
}
var machine1 = VendingMachine()
machine1.coins = 1
machine1.itemList["MiMi"]?.itemCount
//try machine1.vend(itemName: "MiMi")
machine1.itemList["MiMi"]?.itemCount
do {
try machine1.vend(itemName: "WangLaoJi")
}catch VendingMachineErr.invalidSelection{
print("Don't have the item you looking for")
}catch VendingMachineErr.insufficientMoney(var gap){
// var gap just like switch case in enum
print("insert \(gap) coins")
}
/*
try? try!
*/
func test() throws -> String?{
return "something"
}
func someTest() -> String?{
if let a = try? test() {
return a
}else if let b = try! test(){
return b
}
return nil
}
/*
defer statements ensure excution until current scope exited
*/
/*
func processFile(filename:String) throws {
if exists(filename) {
let file = open(filename)
defer{
close(file)
}
while let line = try file.readline(){
//actions
}
}
}
*/