๐Ÿฆ… ํ˜ผ์žํ•˜๋Š” Swift ๊ณต๋ถ€ -2-

๐Ÿฆ… ํ˜ผ์žํ•˜๋Š” Swift ๊ณต๋ถ€ -2-

๐Ÿ‘€ Swift

์• ํ”Œ ๋„์„œ์•ฑ The Swift Programming Language (Swift 5.1)๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉฐ ๊ณต๋ถ€ํ–ˆ๋‹ค.
์ด์ „ ๊ธ€ ๐Ÿ“š ํ˜ผ์žํ•˜๋Š” Swift ๊ณต๋ถ€ -1- ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

Inner function

func func1() -> Int{
    let a = 10
    func func2() -> Int{
        return a + 5
    }
    return func2()
}

print(func1())

15

ํ•จ์ˆ˜ ์•ˆ์— ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•ด์„œ ์“ธ ์ˆ˜๋„ ์žˆ๋‹ค.

## Inner function return

 func makeIncrement() -> ((Int) -> Int){
     func addOne(number : Int) -> Int{
         return 1 + number
     }
     return addOne
 }

 var increment = makeIncrement()
 print(increment(7))

8

makeIncrement()ํ•จ์ˆ˜๊ฐ€ addOne()ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฐ˜ํ™˜ํ˜•์„ ๋ณด๋ฉด -> ((Int) -> Int) ์ธ๋ฐ ์ด๋Š” ์ธ์ž๋กœ Int๋ฅผ ๋ฐ›์•„ Int๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๋œป์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋ณ€์ˆ˜ increment๋Š” makeIncrement()ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด addOne()ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌ๋ฐ›์•˜๊ณ , ์ด๋ฅผ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๊ฒƒ. ์˜ˆ์ œ์—์„œ๋Š” ์ธ์ž๋กœ 7์„ ๋„ฃ์–ด์คฌ๊ธฐ ๋•Œ๋ฌธ์— 8์ด ๋ฐ˜ํ™˜๋˜์—ˆ๋‹ค.

Hand over function as argument

func hasMatch(givenList: [Int], condition: ((Int) -> Bool)) -> Bool{
    for number in givenList{
        if condition(number){
            return true
        }
    }
    return false
}

func lessThanTen(number: Int) -> Bool{
    if number < 11{
        return true
    }
    return false
}

func equalsTen(number: Int) -> Bool{
    if number == 10{
        return true
    }
    return false
}

var list = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]

print(hasMatch(givenList: list, condition: lessThanTen))
print(hasMatch(givenList: list, condition: equalsTen))

true
false

ํ•จ์ˆ˜ hasMatch()์˜ ๋‘๋ฒˆ์งธ ์ธ์ž condition์˜ ํƒ€์ž…์ด ์œ„์—์„œ ๋ฐ˜ํ™˜ํ˜•์„ ๋‚˜ํƒ€๋‚ผ ๋•Œ ์ฒ˜๋Ÿผ ((Int) -> Bool) ๋ฐฉ์‹์œผ๋กœ ๋˜์–ด์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” condition์ด Int๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ Bool์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์—ฌ์•ผํ•œ๋‹ค๋Š”๊ฑธ ๋‚˜ํƒ€๋‚ด๋Š”๊ฒƒ. ์ฆ‰ Int๋ฅผ ๋ฐ›์•„ Bool์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ condition์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ์œ„์˜ ์˜ˆ์ œ์—์„œ ์ฒซ๋ฒˆ์งธ ์ถœ๋ ฅ์€ lessThanTen์„ ์กฐ๊ฑด์œผ๋กœ list์— ์ผ์น˜ํ•˜๋Š”๊ฒƒ์ด ์žˆ๋Š”๊ฐ€๋ฅผ ์ถœ๋ ฅํ•œ ๊ฒƒ์ด๊ณ , ๋‘๋ฒˆ์งธ ์ถœ๋ ฅ์€ equalsTen()์„ ์กฐ๊ฑด์œผ๋กœ list์— ์ผ์น˜ํ•˜๋Š”๊ฒƒ์ด ์žˆ๋Š”๊ฐ€๋ฅผ ์ถœ๋ ฅํ•œ ๊ฒƒ์ด๋‹ค.

Closure

var list2 = list.map{(number: Int) -> Int in
    let result = 2 * number
    return result
}

var list3 = list.map{number in 3 * number}

var list4 = list.map{4 * $0}

var list5 = list.sorted{$0 > $1}

var list6 = list.sorted{$0 < $1}

print(list2)
print(list3)
print(list4)
print(list5)
print(list6)

[42, 2, 22, 26, 30, 6, 38, 10, 14, 18, 34]
[63, 3, 33, 39, 45, 9, 57, 15, 21, 27, 51]
[84, 4, 44, 52, 60, 12, 76, 20, 28, 36, 68]
[21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]

์‚ฌ์‹ค swift์—์„œ ํ•จ์ˆ˜๋Š” ํŠน๋ณ„ํ•œ ํ˜•ํƒœ์˜ closure๋‹ค. ํ•จ์ˆ˜๊ฐ€ ์ต์ˆ™ํ•œ ์šฐ๋ฆฌ๋Š” ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•จ์ˆ˜๋ช…์ด ์—†์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋จ. closure๋ฅผ ํ†ตํ•ด ๋งŽ์€ ๋ถ€๋ถ„๋“ค์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์ธ์ž์™€ ๋ฐ˜ํ™˜ํ˜•์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๊ณ , statement์—์„œ ์‚ฌ์šฉํ•  ๋ณ€์ˆ˜๋„ ๊ทธ๋ƒฅ ๊ฐ„๋‹จํ•˜๊ฒŒ $0, $1, $2 โ€ฆ๋กœ ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Class, Instantiation

class shape{
    var name = ""
    var height = 0
    var width = 0

    init(height: Int, width: Int){
        self.name = self.toString()
        self.heightGetterSetter = height
        self.widthGetterSetter = width
    }
    
    init(name: String, height: Int, width: Int){
        self.name = name
        self.heightGetterSetter = height
        self.widthGetterSetter = width
    }
    
    var heightGetterSetter: Int{
        get{
            return self.height
        }
        set{
            if newValue < 1{
                print("height must higher than 0")
            }
            else{
                self.height = newValue
            }
        }
    }
    
    var widthGetterSetter: Int{
        get{
            return self.width
        }
        set{
            if newValue < 1{
                print("width must longer than 0")
            }
            else{
                self.width = newValue
            }
        }
    }
    
    deinit{
        print("\(name) is deinited")
    }
    
    func toString() -> String{
        return "Shape"
    }
    
    func area() -> Int{
        return 0
    }
    
    func introduce(){
        print("\(self.name)'s height is \(self.heightGetterSetter), and width is \(self.widthGetterSetter) and area is \(self.area())")
    }
}

class square: shape{
    override func toString() -> String{
        return "Square"
    }
    
    override func area() -> Int{
        return self.height * self.width
    }
}

class triangle: shape{
    override func toString() -> String{
        return "Triangle"
    }
    
    override func area() -> Int{
        return (self.height * self.width) / 2
    }
}

let shape1 = square(height: 12, width: 8)
let shape2 = triangle(name: "Semo", height: 9, width: 14)
shape1.introduce()
shape2.introduce()

Squareโ€™s height is 12, and width is 8 and area is 96
Semoโ€™s height is 9, and width is 14 and area is 63

  • ๋‹น์—ฐํ•˜๊ฒŒ๋„ class์˜ ์ƒ์„ฑ์ž๋Š” ์—ฌ๋Ÿฌ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ถ”์ƒ ํ•จ์ˆ˜๋Š” ๋”ฐ๋กœ ์กด์ œํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • override๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜์˜ ์žฌ ์ •์˜๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • :์„ ํ†ตํ•ด class๊ฐ„์˜ ์ƒ์†์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • python์ฒ˜๋Ÿผ this๋Œ€์‹  self๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์ƒ์„ฑ์ž๋Š” init()์œผ๋กœ, ์†Œ๋ฉธ์ž๋Š” deinit()์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ์†Œ๋ฉธ์ž์˜ ๊ฒฝ์šฐ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ reference count๊ฐ€ 0์ด๋˜๋ฉด ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰๋œ๋‹ค.
  • getter์™€ setter๋Š” ๋ฉค๋ฒ„๋ณ€์ˆ˜์˜ ์ž„์‹œ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ด closure์†์—์„œ get, set์„ ํ†ตํ•ด์„œ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ์ œ์–ดํ•˜๋ฉด get, set์— ์ •์˜๋œ๋Œ€๋กœ ์ˆ˜ํ–‰๋œ๋‹ค.

Observer

class observerTest{
    var name = ""{
        didSet{
            print("[didSet] name old value \(oldValue), currentValue \(self._name)")
        }
        willSet{
            print("[willSet] name new value \(newValue), currentValue \(self._name)")
        }
    }
        
    var age = 0 {
        didSet{
            print("[didSet] age old value \(oldValue), currentValue \(self._age)")
        }
        willSet{
            print("[willSet] age new value \(newValue), currentValue \(self._age)")
        }
    }

    init(name: String, age: Int){
        self._age = age
        self._name = name
    }
    
    var _name: String{
        get{
            return self.name
        }
        set{
            self.name = newValue
        }
    }
    
    var _age: Int{
        get{
            return self.age
        }
        set{
            self.age = newValue
        }
    }
    
    func toString(){
        print("\(self._name) is age of \(self._age)")
    }
}

var tester = observerTest(name: "seunghun", age: 23)
tester.toString()
print()
tester._age = 24
tester._name = "Seunghun Yang"
tester.toString()

[willSet] age new value 24, currentValue 23
[didSet] age old value 23, currentValue 24
[willSet] name new value Seunghun Yang, currentValue seunghun
[didSet] name old value seunghun, currentValue Seunghun Yang
Seunghun Yang is age of 24

Class, Instantiation์—์„œ ๋ณธ getter, setter์ฒ˜๋Ÿผ ๋ณ€์ˆ˜์— closure๋กœ didSet, willSet์„ ์‚ฌ์šฉํ•ด ํ–‰์œ„๋ฅผ ์ •์˜ํ•ด์ฃผ๋ฉด observer๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. observer๋Š” ๊ฐ’์˜ ๋ณ€ํ™”๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ˆ˜ํ–‰๋˜๋Š”๋ฐ, didSet์€ ๊ฐ’์ด ๋ณ€ํ•œ ์งํ›„์—, willSet์€ ๊ฐ’์ด ๋ณ€ํ•˜๊ธฐ ์ง์ „์— ์ˆ˜ํ–‰๋œ๋‹ค.

Enum

print()
enum Rank: Int{
    case ace = 1;                                                                           //explicitly set Integer value of enum element
    case two, three, four, five, six, seven, eight, nine, ten, jack, queen, king
    
    func description() -> String{
        switch self{
        case .ace:
            return "ace"
        case .jack:
            return "jack"
        case .queen:
            return "queen"
        case .king:
            return "king"
        default:
            return String(self.rawValue)
        }
    }
    
    func isSpecial() -> String{
        switch self{
        case .ace, .jack, .queen, .king:
            return "special"
        default:
            return "not special"
        }
    }
}

let card1 = Rank.three
    print("\(card1.description()) and it is \(card1.isSpecial())")

if let card2 = Rank(rawValue: 11) {                                                             //rawValue is naive value of element in enum, it returns optional
    print("\(card2.description()) and it is \(card2.isSpecial())")
}
else{
    print("value is nil!!")
}

if let card3 = Rank(rawValue: 14){
    print("\(card3.description()) and it is \(card3.isSpecial())")
}
else{
    print("value is nil!!")
}

let card4: Rank? = Rank(rawValue: 12)
print("\(card4!.description()) and it is \(card4!.isSpecial())")                                  //it may be nil and if it is, it occurs fatal error

3 and it is not special
jack and it is special
value is nil!!
queen and it is special

swift์—์„œ ์—ด๊ฑฐํ˜•์€ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค. ์œ„์˜ ace์˜ ๊ฒฝ์šฐ์ฒ˜๋Ÿผ ๋ช…์‹œ์ ์œผ๋กœ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋„๋ก ํ•ด ์ค„ ์ˆ˜๋„ ์žˆ๋‹ค. enum์˜ ์ธ์ž๋กœ rawValue๋ฅผ ์ฃผ๋ฉด ๊ทธ ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” nil์ผ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— optionalํ•œ ๊ฐ’์ด๋‹ค.

Value associated Enum

enum ServerResponse{
    case onoffTime(Int, Int)
    case serverFailed(String)
    case broadCast(String)
    
    func toString() -> String{
        switch self{
        case let .onoffTime(onTime, offTime):
            return "server on at \(onTime) and it offs at \(offTime)"
        case let .serverFailed(message):
            return "server failed because of \(message)"
        case let .broadCast(message):
            return "[BroadCast] \(message)"
        }
    }
}

let serverMessage1 = ServerResponse.onoffTime(6, 23)
let serverMessage2 = ServerResponse.serverFailed("out of memory")
let serverMessage3 = ServerResponse.broadCast("Hello")

print(serverMessage1.toString())
print(serverMessage2.toString())
print(serverMessage3.toString())

server on at 6 and it offs at 23
server failed because of out of memory
[BroadCast] Hello

๊ฐ’๊ณผ ์—ฐ๊ด€๋˜๋„๋ก enum์„ ์ •์˜ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค. ์ธ์ž์— ๋งค์นญ๋˜๋Š” ๊ฒƒ์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์งค ์ˆ˜ ์žˆ๋‹ค.

Struct

struct structTest{
    var count = 0{
        didSet{
            print("changed from \(oldValue) to \(self.count)")
        }
    }
    
    init(givenCount: Int){
        self.count = givenCount
    }
}

class classTest{
    var count = 0{
        didSet{
            print("changed from \(oldValue) to \(self.count)")
        }
    }
    
    init(givenCount: Int){
        self.count = givenCount
    }
}

//func incrementStruct(target: structTest){
//    target.count += 1
//}

func incrementClass(target: classTest){
    target.count += 1
}

var test1 = structTest(givenCount: 0)
var test2 = classTest(givenCount: 0)
//incrementStruct(target: test1)
incrementClass(target: test2)

changed from 0 to 1

struct๋Š” class์™€ ๋™์ผํ•˜๊ฒŒ ์ƒ์„ฑ, ์„ค์ •๋˜์ง€๋งŒ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. class๋Š” ์ฐธ์กฐ๋ฅผ ์ „๋‹ฌํ•˜์ง€๋งŒ struct๋Š” ๋ณต์‚ฌํ•˜์—ฌ ์ „๋‹ฌ๋œ๋‹ค(C++์—์„œ ์–•์€๋ณต์‚ฌ์™€ ์œ ์‚ฌํ•จ). ์œ„์˜ ์ฝ”๋“œ์—์„œ class ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ count๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๊ฒƒ์ด struct์—๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

Protocol

protocol animal{
    var name: String{get set}
    func speak()
}

class dog: animal{
    var name: String = ""
    
    init(givenName: String){
        self.name = givenName;
    }
    
    func speak(){
        print("\(self.name) : bark bark")
    }
}

class cat: animal{
    var name: String = ""
    
    init(givenName: String){
        self.name = givenName;
    }
    
    func speak(){
        print("\(self.name) : meow")
    }
}

var doggy = dog(givenName: "Peter")
var kitty = cat(givenName: "Tom")
doggy.speak()
kitty.speak()

Peter : bark bark
Tom : meow

protocol์€ ์ƒ์†๋ฐ›์•„ ๊ตฌํ˜„๋˜์–ด์•ผ ํ•˜๋Š”๊ฒƒ์„ ์—ด๊ฑฐํ•œ๋‹ค. ์ผ์ข…์˜ ์ถ”์ƒ ํด๋ž˜์Šค์™€ ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค . struct๋‚˜ class๊ฐ€ ๊ทธ๊ฑธ ์ƒ์†๋ฐ›์•„ protocol๋กœ ๋ช…์‹œ๋œ๊ฑธ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Extension

protocol speak{
    func toString()
}

extension Int: speak{
    func toString(){
        print("I am \(self)")
    }
}

extension dog: speak{
    func toString(){
        print("Hi, my name is \(self.name)")
    }
}

var number = 3
number.toString()
5.toString()
doggy.toString()

I am 3
I am 5
Hi, my name is Peter

protocol์„ ๋งŒ๋“ค๊ณ  extension์„ ํ†ตํ•ด ๊ทธ๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” Int์™€ dog๊ฐ€ speak๋ฅผ extensionํ•˜์—ฌ toString()ํ•จ์ˆ˜์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ด๋‹ค.

Protocol type variables

var doggyProtocol: animal = doggy
doggyProtocol.speak()

Peter : bark bark

protocol์ธ animal๊ฐ์ฒด doggyProtocol์„ doggy๋กœ ๋ณต์‚ฌ์ƒ์„ฑํ•˜๊ณ  speak()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด extension์œผ๋กœ ์ •์˜๋œ speak()ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ์›๋ž˜์˜ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

Error Handling

enum errorList: Error{
    case errorTwo
    case errorThree
}

func errorChecker(inputNumber: Int) throws -> String{
    if inputNumber % 2 != 0{
        throw errorList.errorTwo
    }
    else if inputNumber % 3 != 0{
        throw errorList.errorThree
    }
    return "your input handled normally"
}

do{
    let errorCheck1 = try errorChecker(inputNumber: 6)
    print(errorCheck1)
    
    let errorCheck2 = try errorChecker(inputNumber: 133)
    print(errorCheck2)
}
catch errorList.errorTwo{
    print("errorTwo raised")
}
catch errorList.errorThree{
    print("errorThree raised")
}

your input handled normally
errorTwo raised

Error๋ฅผ ์ƒ์†๋ฐ›๋Š” enum์„ ๋งŒ๋“ค์–ด ์—๋Ÿฌ๋ฅผ ์ •์˜ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค. error๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ํ•จ์ˆ˜๋Š” Java์—์„œ์ฒ˜๋Ÿผ throws๋ฅผ ํ†ตํ•ด ๋ช…์‹œํ•ด์ค€๋‹ค. ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ๋ถ€๋ถ„์—์„œ throw๋ฅผ ํ†ตํ•ด ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์–ด error๋ฅผ handlingํ•  ๋•Œ์—๋Š” error๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ ๊ตฌ๋ฌธ์„ do๋กœ ๊ฐ์‹ธ๊ณ  ๊ทธ ์•ˆ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ค„์„ try๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•œ๋‹ค. do ๋ฐ–์—์„œ๋Š” catch๋ฅผ ํ†ตํ•ด ๊ฐ๊ฐ์˜ error์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์ •์˜ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

Deffer

func testingDeffer(){
    print("first sentence")
    defer{
        print("last sentence")
    }
    print("second sentence")
    print("third sentence")
}

testingDeffer()

first sentence
second sentence
third sentence
last sentence

deffer๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ scope์•ˆ์ชฝ์˜ ์ฝ”๋“œ๊ฐ€ ๋งจ ๋งˆ์ง€๋ง‰์— ์ˆ˜ํ–‰๋˜๋Š”๊ฒƒ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. error๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋งˆ์ง€๋ง‰์— ์ˆ˜ํ–‰๋œ๋‹ค.

Generic

func bulletBelt<Bullet>(bullet: Bullet, numberOfBullets: Int) -> [Bullet]{
    var beltOfBullets = [Bullet]()
    for _ in 0..<numberOfBullets{
        beltOfBullets.append(bullet)
    }
    return beltOfBullets
}

func fireAllBullets<Bullet>(bulletBelt: [Bullet]){
    for _ in 0..<bulletBelt.endIndex{
        print("Bang!!")
    }
}

var beltOfBullets = bulletBelt(bullet: "5.56mm", numberOfBullets: 15)
fireAllBullets(bulletBelt: beltOfBullets)

Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!
Bang!!

Java์˜ Generic, C++์˜ Template๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Where

func commonElements<T: Sequence>(_ left: T,_ right: T) -> [T.Element] where T.Element: Equatable{
    var found = [T.Element]()
    for leftElement in left{
        for rightElement in right{
            if leftElement == rightElement{
                found.append(leftElement)
                print("found common element \(leftElement)")
            }
        }
    }
    return found
}

commonElements([1, 3, 5, 7, 9, 11, 13], [1, 1, 2, 3, 5, 8, 13])
print()
commonElements("strawberry", "tangerine")

found common element 1
found common element 1
found common element 3
found common element 5
found common element 13

found common element t
found common element r
found common element a
found common element e
found common element e
found common element r
found common element r

where๋ฅผ ํ†ตํ•ด ์š”๊ตฌ์‚ฌํ•ญ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. commonElement<T: Sequence>์—์„œ : Sequence๋ถ€๋ถ„๋„ ์š”๊ตฌ์‚ฌํ•ญ ์ค‘ ํ•˜๋‚˜๋กœ, ๋“ค์–ด์˜ฌ type์ธ T๊ฐ€ ์—ฐ์†์ ์ด๋ฉฐ ์ˆœํšŒ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด์–ด์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. where๋’ค์— ๋‚˜์˜ค๋Š” T.Element: Equatable์€ T์˜ ์š”์†Œ๊ฐ€ ๋น„๊ต๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. ์ข…ํ•ฉํ•ด๋ณด๋ฉด T๋Š” ์—ฐ์†์ ์ด์–ด์•ผํ•˜๊ณ , ๊ทธ ์š”์†Œ๋“ค์€ ๋น„๊ต๊ฐ€๋Šฅํ•œ ๊ฒƒ๋“ค์ด์–ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.

Share: Twitter Facebook
Seunghun Yang's Picture

About Seunghun Yang

Seunghun is undergraduate student at Computer Science Engineering in CNU(Chungnam National University).

Daejeon, South Korea

Comments