
기본
⎮ 클로저
1. 클로저 : 코드에서 독립적으로 전달 및 사용할 수 있는 기능을 가진 코드 블록
- 변수나 상수에 저장 가능
- 함수의 인자로 전달 가능
// Closure 문법
{ (매개변수) -> 반환타입 in
실행코드
}
* 외부 변수나 상수의 값을 캡처하여 저장할 수 있음(클로저 선언 이후에 값이 변하면 최신의 값을 불러오기는 함.)
var number = 10
// 클로저 정의, number 변수 캡처
let captureClosure = {
print(number)
}
number = 20
// 클로저를 실행하면, number 값은 20으로 출력.
captureClosure() // 출력: 20
// 기본 클로저 형태
let greet = { (name: String) -> String in
return "Hello, \(name)!"
}
print(greet("Uddt"))
// "Hello, Uddt!"
// 함수의 인자로 클로저 전달 가능
func performAction(action: () -> Void) {
action()
}
performAction {
print("Action performed!")
}
⎮ 함수를 클로저로 바꾸는 방법(문법 최적화)
// 함수
func name(parameters) -> Type {
code
}
// 최적화1 : func 키워드 삭제
name(parameters) -> Type {
code
}
// 최적화2 : 함수 이름(여기서는 name) 삭제
(parameters) -> Type {
code
}
// 최적화3 : { } 위치 조정, in 추가
{ (parameters) -> Type in
code
}
// 최적화4 : parameter, Return 값이 없으면 생략 가능
{ () in
code
}
// 최적화5 : (), in 키워드도 생략 가능
{
code
}
// 최적화6 : 줄바꿈 삭제 (가장 단순한 형태의 Closure)
{ code }
⎮ 객체지향 프로그래밍(OOP, Object - Oriented Programming)
1. 객체지향 프로그래밍(OOP): 객체(Object)를 기반으로 프로그램을 설계하는 방식
* 주요 원칙
- 캡슐화(Encapsulation) : 데이터를 숨기고 외부에는 필요한 인터페이스만 제공.
- 상속(Inheritance) : 기존 클래스를 확장하여 새로운 클래스를 생성.
- 다형성(Polymorphism) : 같은 메서드를 다양한 방식으로 동작하게 함.
- 추상화(Abstrcation) : 불필요한 세부 사항을 숨기고 중요한 부분만 표현.
2. 클래스와 객체
- 클래스(Class) : 객체를 정의하기 위한 청사진
- 객체(Object) : 클래스에서 생성된 실제 인스턴스
// OOP 기본 예제
class Animal {
var name: String
init(name: String) {
self.name = name
}
func makeSound() {
print("Some generic sound")
}
}
class Dog: Animal {
override func makeSound() {
print("Bark!")
}
}
let dog = Dog(name: "Buddy")
dog.makeSound()
// "Bark!"
실습
⎮ 클로저 구현하기
1. 간단한 클로저 구현
숫자 배열 [1, 2, 3, 4, 5]를 생성하고, 클로저를 사용해 배열의 모든 값을 2배로 만든 결과를 출력하세요.
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { $0 * 2 }
print(doubled)
// [2, 4, 6, 8, 10]
let doubled = numbers.map { $0 * 2 } 코드는 문법 최적화가 적용된 상태다.
최적화 전에는 어떤 코드였을까?
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map({ (number: Int) -> Int in
return number * 2
})
// 문법 최적화1 : parameter Type은 컴파일러가 인식할 수 있으므로 생략 가능
let doubled = numbers.map({ (number) -> Int in
return number * 2
})
// 문법 최적화2 : return Type도 인식할 수 있으므로 생략 가능
let doubled = numbers.map({ (number) in
return number * 2
})
// 문법 최적화3 : closure body에서 parameter 이름을 사용하고 있다면, parameter 이름과 in 생략 가능
let doubled = numbers.map({
return number * 2
})
// 문법 최적화4 : number라는 이름으로 더이상 접근 불가. index parameter인 $n를 사용
let doubled = numbers.map({
return $0 * 2
})
// 문법 최적화5 : closure body에 return문 하나만 사용하고 있다면 생략 가능
let doubled = numbers.map({
$0 * 2
})
// 문법 최적화6 : 코드가 짧으면 이어쓰기 가능
let doubled = numbers.map({ $0 * 2 })
// 문법 최적화7 : closure가 유일한 parameter이면서 마지막 parameter일 때는 잘라내서 () 뒤에 작성
let doubled = numbers.map() { $0 * 2 }
// 문법 최적화8 : ()도 생략 가능
let doubled = numbers.map { $0 * 2 }
2. 클로저 캡처 이해하기
var counter = 0
let incrementCounter = {
counter += 1
}
incrementCounter()
incrementCounter()
print(counter) // 출력: 2
⎮ 객체지향 프로그래밍 구현하기
1. 동물 클래스 설계
Animal 클래스: name 속성과 makeSound() 메서드를 포함.
Dog 클래스: Animal을 상속받고 makeSound() 메서드를 오버라이드하여 "Bark!" 출력.
Cat 클래스: Animal을 상속받고 makeSound() 메서드를 오버라이드하여 "Meow!" 출력.
class Animal {
var name: String
func makeSound() {
print("Sound is default")
}
init(name: String) {
self.name = name
}
}
class Dog: Animal {
override func makeSound() {
print("Bark!")
}
}
class Cat: Animal {
override func makeSound() {
print("Meow!")
}
}
let dog = Dog(name: "Woody")
dog.makeSound()
// Bark!
let cat = Cat(name: "Tosi")
cat.makeSound()
// Meow!
심화
⎮ 클로저 Capture
보통 우리가 'Capture'라고 하면 스크린샷처럼, 그 장면을 기억하는 것으로 생각하게 된다.
var number = 10
// 클로저 정의, number 변수 캡처
let captureClosure = {
print(number)
}
number = 20
// 클로저를 실행하면, number 값은 20으로 출력.
captureClosure() // 출력: 20
number가 10인 상태로 캡처를 했으면,
number가 20으로 바뀌어도 captureClosure를 불러오면 10이 나와야하는거 아닌가?!
⎮ Closure Capture의 종류(값 캡처, 참조 캡처)
1. 값 캡처(Default Capture) : 외부 변수의 현재 값을 캡처하는 것.
let captureClosure = { print(number) }로 정의된 클로저는 number의 현재 값인 10을 캡처한 것이 맞음.
2. 참조 캡처(Explicit Capture) : 클로저가 외부 변수에 참조를 캡처하도록 명시할 수 있음.
이 경우 number를 변경할 때마다 클로저 내에서 참조하는 값이 바뀜.
var number = 10
// 클로저 정의, number 변수 캡처 (사실상 이것도 참조캡처지만, 편의상 값 캡처처럼 이해)
let captureClosure = { print(number) }
captureClosure() // 출력: 10
number = 20
captureClosure() // 출력: 20
위의 코드에서는 변수의 참조가 캡처된 것으로, number의 값이 변경된 이후 클로저를 호출했기 때문에,
클로저가 최신 상태의 number 값을 참조한 것.
'스파르타코딩 클럽 > 사전 캠프' 카테고리의 다른 글
| 15. 스파르타 코딩클럽 [사전캠프 - Combine] (0) | 2025.02.25 |
|---|---|
| 14. 스파르타 코딩클럽 [사전캠프 - 비동기 프로그래밍 / 제네릭] (0) | 2025.02.20 |
| 12. 스파르타 코딩클럽 [사전캠프 - 자료구조/메모리 구조 및 ARC] (0) | 2025.02.09 |
| 11. 스파르타 코딩클럽 [사전캠프 - Struct와 Class/Protocol] (1) | 2025.02.08 |
| 10. 스파르타 코딩클럽 [사전캠프 - 가위바위보 게임 만들기] (1) | 2025.02.07 |