개발/swift

[swift] swift 언어 정리 (2) - 함수 & 클로저

iris3455 2025. 3. 14. 10:07

함수

  • 클래스, 구조체, 객체와 독립적으로 존재하는 코드 블록
  • 특정 작업을 수행하고 값을 반환할 수도 있음
  • 전역 함수 또는 지역 함수로 선언 가능

 

1. 형식

func <함수이름> (매개변수 : 타입) -> 출력타입 {

}

 

 

2. 메서드

메서드란 ?

클래스(class), 구조체(struct), 열거형(enum) 내부에 정의된 함수

특정 객체와 연관되어 있어, 객체가 있어야만 호출할 수 있음

인스턴스 메서드와 타입 메서드로 구분됨
class Car {
    var brand: String

    // 초기화 메서드 (Initializer)
    init(brand: String) {
        self.brand = brand
    }
    
    // 인스턴스 메서드
    func displayInfo() {
        print("My brand is \(brand)")
    }
}

let myCar = Car(brand: "Tesla") // 객체 생성
myCar.displayInfo() // ✅ 메서드 호출 → "My brand is Tesla"

 

 

인스턴스 메서드

  • 객체(인스턴스)가 생성된 후 사용되는 메서드
  • self를 사용하여 인스턴스 속성에 접근 가능
class Car {
    var brand: String

    init(brand: String) {
        self.brand = brand
    }

    func displayInfo() {
        print("My brand is \(brand)")
    }
}

let myCar = Car(brand "Tesla") // 객체 생성
myCar.displayInfo() // 이 처럼 객체 생성 후 호출가능

 

 

타입 메서드

 

  • 클래스, 구조체, 열거형 자체에서 호출하는 메서드
  • static 또는 class 키워드를 사용함

 

class Car {
    static func companyName() -> String {
        return "Tesla Inc."
    }
}

Car.companyName() //객체를 생성하지 않고 Car.companyName()처럼 클래스 자체에서 호출 가능

 

 

3. 매개 변수 vs 인자 

  • 매개 변수
    • 함수를 정의할때 사용 
    • 함수 내부에서 데이터를 받을 공간
    • 상수값
  • 인자
    • 함수를 호출할때 전달하는 값
    • 매개변수에서 실제로 할당되는 데이터
func greet (name: Stirng) -> Void{  // (name: Stirng) 매개변수
	print("my name is \(name)")
}

greet(name : "Iris") // (name : "Iris") 인자

 

 

4. 인자 레이블

 

함수 호출의 가독성을 높이기 위해 인자 레이블을 사용함.

  • 사용할때 
func setAge(for person: String, to age: Int) {
    print("\(person)의 나이를 \(age)로 설정했습니다.")
}

setAge(for: "Iris", to: 25)

 

  • 사용하지 않을때
func setAge(_ person: String, _ age: Int) {
    print("\(person)의 나이를 \(age)로 설정했습니다.")
}

setAge("Iris", 25)

 

 

5. 매개 변수 수정 

  • 매개변수는 기본적으로 상수이므로 수정 불가
// 수정 불가능

func switchValue(_ a: Int, _ b: Int)-> void {
	let temp = a
	// 매개변수는 기본적으로 상수이므로 매개변수 a 를 수정할수 없음
	a = b
	b = temp
}

var num_1 = 10
var num_2 = 5

switchValue(num_1, num_2)

 

  • 수정하려면 Inout 사용
func switchValue(_ a: inout Int, _ b: inout Int)-> void {
	let temp = a
	a = b
	b = temp
}

var num_1 = 10
var num_2 = 5

switchValue(&num_1, &num_2)

//출력

-> num_1 = 5 
-> num_2 = 10

 

 

6. 선택적 매개변수 (매개변수에 default값 추가)

class Person {
    var name: String
    var age: Int

    init(name: String = "Unknown", age: Int = 20) {
        self.name = name
        self.age = age
    }
}

let p1 = Person() // ✅ 기본값 사용
let p2 = Person(name: "Iris") // ✅ age는 기본값 20 사용
print(p1.name) // "Unknown"
print(p2.age) // 20

 

 

7. 가변 매개변수

  • 여러 개의 값을 하나의 매개변수로 받을 수 있도록 하는 기능.
  • 함수가 입력 개수를 특정할 수 없을 때 유용하며, 배열처럼 값을 받아서 활용할 수 있음.
func sum(_ numbers: Int...) -> Int{
	var total = 0
	for number in numbers{
    	total += number
    }
    return total
}

let result = sum(1,2,5,4,6,3,90)

 

 

8. 매개변수로 함수를 전달

func test (_ operation : (Int, Int) -> Int ,_ a : Int, _ b : Int) -> Int {
    return operation(a,b)
}

func add(_ a:Int, _b:Int) -> Int{ a+b }
func multiple(_ a:Int, _ b:Int) -> Int{ a*b }


let result = test(add, 10, 20)

 

 

고차 함수

함수를 매개변수로 받거나, 함수를 반환하는 함수

  • 함수를 매개변수로 받는 고차 함수
func test (operation : (Int, Int) -> Int ,_ a : Int, _ b : Int) -> Int {
    return operation(a,b)
}

func add(_ a:Int, _b:Int) -> Int{ a+b }
func multiple(_ a:Int, _ b:Int) -> Int{ a*b }


let result = test(operation : add, 10, 20)
  • 함수를 반환하는 고차 함수 예제
func makeMultiplier(factor: Int) -> (Int) -> Int {
    return { $0 * factor }
}

let double = makeMultiplier(factor: 2)
print(double(5)) //  10

// 풀어서 쓰면 아래처럼

func makeMultiplier(factor: Int) -> (Int) -> Int {
	func multiply(num: Int) -> Int {
		return num * factor
        
    return multiply
}

let double = makeMultiplier(factor: 2)
print(double(5)) //  10

 

 

map

  • 모든 요소를 변환.
  • 각 요소를 map의 클로저에 적용하여 새로운 배열을 반환함.
let numbers = [1, 2, 3, 4, 5]

let result = numbers.map{ $0 * $0 } // 1,4,9,16,25 출력

 

filter

  • 특정 조건을 만족하는 요소만 선택
let numbers = [1,2,3,4,5]

let result = numbers.filter {$0 % 2 == 0} // [2,4]

 

reduce

  • 배열의 모든 요소를 하나의 값으로 축약
let numbers = [1,2,3,4,5]

let result = numbers.reduce(0){$0 + $1} // 15

 

sorted

  • 정렬을 수행
let numbers = [5,3,2,4,1]

let result = numbers.sorted{ $0 < $1 } // [1,2,3,4,5]

 

forEach

  • for 반복문처럼 배열의 모든 요소를 반복하여 실행
let names = ["Alice", "Bob", "Charlie"]

let result = names.forEach{ print("Hello my name is \($0)") }

 

 

클로저

  • 익명 함수로 "이름이 없는 함수"처럼 동작하는 코드 블록.
  • 변수에 저장하거나, 다른 함수에 매개변수로 전달할 수 있음.
  • 일반적인 함수와 거의 동일한 기능을 하지만, 함수 이름이 없고 더 간결하게 표현할 수 있음.

 

1. 형식

// multiple의 타입은 함수
// multiple: (Int) -> Int → "Int 받아서 Int를 반환하는 함수 타입"

let multiple = {(_ num: Int) -> Int in 
	return num * num
}

print(multiple(20))

 

 

2. 고차 함수와 함께 활용

  • 배열 정렬 (sorted + 클로저)
// 기본

let numbers: [Int] = [3,5,2,4,1]

let sortedNumbers = numbers.sorted(by: {(a: Int, b: Int) -> Bool in
	return a < b
})

print(sortedNumbers) // 출력: [1, 2, 3, 4, 5]


// 간단히

let sortedNumbers = numbers.sorted(by: {a,b in return a < b})

let sortedNumbers = numbers.sorted(by: {a,b in a < b})

let sortedNumbers = numbers.sorted(by: {$0 < $1})

let sortedNumbers = numbers.sorted{$0 < $1}

let sortedNumbers = numbers.sorted(by : <)

let sortedNumbers = numbers.sorted(<)
  • map 정렬 (map + 클로저)
let numbers = [1,2,3,4,5]

let result =  numbers.map({(a: Int ) -> Int in
	return a * a
})  // [1,4,9,16,25]


// 간략히 하기
let result = numbers.map{( $0 * $0 )}
let result = numbers.map{ $0 * $0 }

 

 

 

3. 함수의 매개변수로 사용

func test (operation : (Int, Int) -> Int ,_ a : Int, _ b : Int) -> Int {
    return operation(a,b)
}

// func add(_ a:Int, _b:Int) -> Int{ a+b }
// func multiple(_ a:Int, _ b:Int) -> Int{ a*b }


let result = test(operation : {$0 + $1} , 10, 20)

 

 

4. 클로저 캡처

  • 외부 변수의 값을 캡처(저장)
  • 변수를 값(value)이 아니라 참조(reference)로 캡처해.
    즉, 클로저가 실행될 때마다 원래 변수의 변경 사항을 반영할 수 있음.
// counterFunction()은 Int를 반환하는 함수를 반환

func counterFunction() -> () -> Int{
	var count = 0
	return {
    	count += 1
        return count
    }
}

let result_1 = counterFunction(0)
let result_2 = counterFunction(0)

print(result_1()) // 1
print(result_1()) // 2
print(result_1()) // 3

print(result_2()) // 1
print(result_2()) // 2
print(result_2()) // 3