반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- IOS
- MySQL
- 네트워크
- 리눅스
- 인공지능
- 데이터베이스
- 스프링
- DBMS
- 스프링부트
- sql
- 오라클
- 프로그래밍언어론
- libasm
- AI
- 42seoul
- 아이패드다이어리
- Spring
- JPA
- javascript
- CI
- 밥먹는 철학자
- 스프링부트 웹 소켓
- CD
- 소켓
- jenkins
- Xcode
- springboot
- 다이어리
- swift
- Dining philosopher problem
Archives
- Today
- Total
Hi yoahn 개발블로그
[Swift] #4 다양한 표현 및 확장 2 (클로저/프로퍼티) 본문
반응형
1. 클로저
- 클로저는 실행가능한 코드 블럭입니다.
- 함수와 다르게 이름정의는 필요하지는 않지만, 매개변수 전달과 반환 값이 존재 할 수 있다는 점이 동일합니다.
- 함수는 이름이 있는 클로저입니다.
- 일급객체로 전달인자, 변수, 상수 등에 저장 및 전달이 가능합니다.
1.1 클로저 문법
- 클로저는 중괄호 { }로 감싸져있습니다.
- 괄호를 이용해 파라미터를 정의합니다. (매개변수 필요 없으면 빈칸)
- -> 을 이용해 반환 타입을 명시합니다. (없으면 Void)
- "in" 키워드를 이용해 실행 코드와 분리합니다.
{ (매개변수 목록) -> 반환타입 in
실행 코드
}
1.2 클로저 사용
// sum이라는 상수에 클로저를 할당
let sum: (Int, Int) -> Int = { (a: Int, b: Int) in
return a + b
}
let sumResult: Int = sum(1, 2)
print(sumResult) // 3
1.3 함수 전달인자로서의 클로저
- 클로저는 함수의 전달인자로 많이 사용
let add: (Int, Int) -> Int
add = { (a: Int, b: Int) in
return a + b
}
let substract: (Int, Int) -> Int
substract = { (a: Int, b: Int) in
return a - b
}
let divide: (Int, Int) -> Int
divide = { (a: Int, b: Int) in
return a / b
}
func calculate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int {
return method(a, b)
}
var calculated: Int
calculated = calculate(a: 50, b: 10, method: add)
print(calculated) // 60
calculated = calculate(a: 50, b: 10, method: substract)
print(calculated) // 40
calculated = calculate(a: 50, b: 10, method: divide)
print(calculated) // 5
//따로 클로저를 상수/변수에 넣어 전달하지 않고,
//함수를 호출할 때 클로저를 작성하여 전달할 수도 있습니다.
calculated = calculate(a: 50, b: 10, method: { (left: Int, right: Int) -> Int in
return left * right
})
print(calculated) // 500
1.4 다양한 클로저 표현
1) 후행 클로저
클로저가 함수의 마지막 전달인자일때, 마지막 매개변수 이름을 생략한 후 함수 소괄호 외부에 클로저를 구현할 수 있습니다.
result = calculate(a: 10, b: 10) { (left: Int, right: Int) -> Int in
return left + right
}
print(result) // 20
// 반환타입 생략
result = calculate(a: 10, b: 10) { (left: Int, right: Int) -> Int in
return left + right
}
2) 반환타입 생략
calculate(a: b: method: ) 함수의 method 매개변수는 Int 타입을 반환할 것이라고 컴파일러가 알기 때문에 반환타입 안써도 됨
BUT, in 키워드 생략 불가
3) 단축 인자 이름
클로저의 매개변수 이름이 굳이 불필요하다면 단축 인자이름을 활용할 수 있습니다.
단축 인자이름은 클로저의 매개변수의 순서대로 $0, $1, $2... 처럼 표현합니다.
result = calculate(a: 10, b: 10, method: {
return $0 + $1
})
print(result) // 20
// 당연히 후행 클로저와 함께 사용할 수 있습니다
result = calculate(a: 10, b: 10) {
return $0 + $1
}
print(result) // 20
4) 암시적 반환 표현
클로저가 반환하는 값이 있다면 클로저의 마지막 줄의 결과값은 암시적으로 반환값으로 취급합니다.
result = calculate(a: 10, b: 10) {
$0 + $1
}
print(result) // 20
// 간결하게 한 줄로 표현해 줄 수도 있습니다
result = calculate(a: 10, b: 10) { $0 + $1 }
print(result) // 20
2. 프로퍼티
- 인스턴스 저장 프로퍼티
일반 인스턴스 프로퍼티 - 타입 저장 프로퍼티
- 인스턴스 연산 프로퍼티
연산을 통해 값 저장 - 타입 연산 프로퍼티
- 지연 저장 프로퍼티
인스턴스 연산 프로퍼티
struct Student {
// 인스턴스 저장 프로퍼티
var name: String = ""
var `class`: String = "Swift"
var koreanAge: Int = 0
// 인스턴스 연산 프로퍼티
var westernAge: Int {
get {
return koreanAge - 1
}
set(inputValue) {
koreanAge = inputValue + 1
}
}
// 타입 저장 프로퍼티
static var typeDescription: String = "학생"
/*
// 인스턴스 메서드
func selfIntroduce() {
print("저는 \(self.class)반 \(name)입니다")
}
*/
// 읽기전용 인스턴스 연산 프로퍼티
// 간단히 위의 selfIntroduce() 메서드를 대체할 수 있습니다
var selfIntroduction: String {
get {
return "저는 \(self.class)반 \(name)입니다"
}
}
/*
// 타입 메서드
static func selfIntroduce() {
print("학생타입입니다")
}
*/
// 읽기전용 타입 연산 프로퍼티
// 읽기전용에서는 get을 생략할 수 있습니다
static var selfIntroduction: String {
return "학생타입입니다"
}
}
// 타입 연산 프로퍼티 사용
print(Student.selfIntroduction)
// 학생타입입니다
// 인스턴스 생성
var yagom: Student = Student()
yagom.koreanAge = 10
// 인스턴스 저장 프로퍼티 사용
yagom.name = "yagom"
print(yagom.name)
// yagom
// 인스턴스 연산 프로퍼티 사용
print(yagom.selfIntroduction)
// 저는 Swift반 yagom입니다
print("제 한국나이는 \(yagom.koreanAge)살이고, 미쿡나이는 \(yagom.westernAge)살입니다.")
응용
struct Money {
var currencyRate: Double = 1100
var dollar: Double = 0
var won: Double {
get {
return dollar * currencyRate
}
set {
dollar = newValue / currencyRate
// 매개변수 이름을 써주지 않으면 newValue 라고 암시적으로 들어감
}
}
}
var moneyInMyPocket = Money()
moneyInMyPocket.won = 11000
print(moneyInMyPocket.won) // 11000
지역변수 및 전역 변수
저장 프로퍼티와 연산 프로퍼티의 기능은 함수, 메서드, 클로저, 타입 등의 외부에 위치한 지역/전역 변수에도 모두 사용 가능합니다.
var a: Int = 100
var b: Int = 200
var sum: Int {
return a + b
}
print(sum) // 300
3. 프로퍼티 감시자
- 프로퍼티 감시자를 사용하면 프로퍼티의 값이 변경될 때 원하는 동작을 수행할 수 있습니다.
- 값이 변경되기 직전에 willSet블럭이, 값이 변경된 직후에 didSet블럭이 호출됩니다.
- 둘 중 필요한 하나만 구현해 주어도 무관합니다.
- 변경되려는 값이 기존 값과 똑같더라도 프로퍼티 감시자는 항상 동작합니다.
- willSet 블럭에서는 암시적 매개변수 newValue를, didSet 블럭에서는 oldValue를 사용할 수 있습니다.
- 프로퍼티 감시자는 연산 프로퍼티에는 사용할 수 없습니다.
- 프로퍼티 감시자는 함수, 메서드, 클로저, 타입 등의 지역/전역 변수에 모두 사용 가능합니다.
반응형
'프로그래밍 언어 > swift' 카테고리의 다른 글
[Swift] #6 다양한 표현 및 확장 4 (옵셔널체이닝/nil 병합/타입캐스팅) (0) | 2021.01.21 |
---|---|
[Swift] #5 다양한 표현 및 확장 3 (상속 / 인스턴스 생성 / 소멸) (0) | 2021.01.20 |
[Swift] #3 다양한 표현 및 확장1 (구조체 / 클래스 / 열거형) (0) | 2021.01.20 |
[Swift] #2 Swift 기초 문법 2 (0) | 2021.01.19 |
[Swift] #1 Swift 기초 문법 1 (0) | 2021.01.19 |
Comments