swift 기초 - 클로저 , 프로퍼티, 프로퍼티 감시자
[1]클로저
코드의 블럭
일급 시민
변수, 상수 등으로 저장, 전달인자로 전달이 가능
함수 : 이름이 있는 클로저
정의
{
(매개변수 목록) -> <반환타입> in <실행코드>
}
[1-1] 함수를 사용한다면
func sumFunction(a:Int , b:Int) -> Int {
return a+b
}
var sumResult: Int = sumFunction(a: 1, b: 2)
print(sumResult) //3
[1-2] 클로저 정의 및 할당
var sumCloser : (Int, Int) -> Int = {
//매개변수 목록 -> 반환타입
(a:Int , b:Int) -> Int in
//실행코드
return a + b
}
[1-3] 클로저의 사용
sumResult = sumCloser(1, 2)
print(sumResult) //3
[1-4] 함수는 클로저의 일종
//sumResult 변수에 함수도 할당가능하다.
sumCloser = sumFunction(a:b:)
sumResult = sumCloser(1,2)
print(sumResult) //3
[1-5] 함수의 전달인자로서의 클로저
//더하기 클로저
let add: (Int, Int) -> Int
add = {
(a:Int, b:Int) -> Int in
return a + b
}
//빼기 클로저
let substract : (Int, Int) -> Int
substract = {
(a:Int, b:Int) -> Int in
return a - b
}
//나누기 클로저
let divide:(Int, Int) -> Int
divide = {
(a:Int, b:Int) -> 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)
//빼기
calculated = calculate(a: 50, b: 10, method: substract)
print(calculated)
//나누기
calculated = calculate(a: 50, b: 10, method: divide)
print(calculated)
[2] 클로저 고급
[2-1] 후행 클로저
클로저가 함수의 마지막 전달인자라면
마지막 매개변수 이름을 생략한 후
함수의 소괄호 외부에 클로저를 구현할 수 있다.
calculated =
calculate(a: 50, b: 10){
(left:Int, right:Int) -> Int in
return left - right
}
print(calculated) //40
[2-2] 반환타입 생략
calculate 함수의 method 매개변수는
Int 타입을 반환할 것이라는 사실을 컴파일러도 알기때문에
굳이 클로저에서 반환타입을 명시해 주지 않아도 된다.
대신 in 키워드는 생략할 수 없다(!)
calculated =
calculate(a: 10, b: 10, method: {
(left:Int, right:Int) in
return left + right
})
print(calculated) //20
[2-3] 후행클로저와 함께 사용가능
calculated =
calculate(a: 10, b: 10){
(left:Int, right:Int) in
return left + right
}
[2-4] 단축인자 이름
클로저의 매개변수 이름이 굳이 불필요하다면
단축인자 이름을 사용할 수 있다.
단축인자 이름은 $0, $1 .. 처럼 표현가능하다.
calculated = calculate(a: 10, b: 10, method: {
return $0 + $1
})
print(calculated) //20
[2-5] 후행클로저와 함께 사용가능
calculated = calculate(a: 10, b: 10){
return $0 + $1
}
[2-6] 암시적 반환 표현
클로저가 반환하는 값이 있다면
클로저의 마지막 줄의 결과값은 암시적으로 반환값으로 취급한다.
calculated = calculate(a: 10, b: 10){
$0 + $1
}
[2-7] 축약하지 않은 클로저 문법과 축약 후의 문법 비교
calculated = calculate(a: 10, b: 10, method: { (left: Int, right: Int) -> Int in
return left + right
})
calculated = calculate(a: 10, b: 10) { $0 + $1 }
print(calculated) // 20
[3] 프로퍼티
프로퍼티는 구조체, 클래스, 열거형 내부에 구현가능하다.
다만 열거형 내부에는 연산 프로퍼티만 구현할 수 있다.
연산 프로퍼티는 var 로만 선언할 수 있다.
[3-1] 프로퍼티 , set, get 메소드 정의
//학생 구조체
struct Student {
//인스턴스 저장 프로퍼티
var name:String = ""
var className : String = "Swift"
var korAge : Int = 0 //한국나이
//인스턴스 연산프로퍼티
//미국 나이
var westenAge:Int {
get{
return korAge - 1
}
set(inputValue){
korAge = inputValue + 1
}
} //미국나이 끝
//타입 저장 프로퍼티
static var typeDescription:String = "학생"
//인스턴스 메소드
// func selfInstroduction() {
// print("저는 \(self.className)반 \(name)입니다.")
// }
//읽기전용 인스턴스 연산 프로퍼티 - 인스턴스 메소드의 역할과 같다.
var selfInstroduction:String {
get{
return "저는 \(self.className)반 \(name)입니다."
}
}
//타입 메서드
static func selfIntroduce(){
print("학생 타입입니다. - 타입메소드")
}
//읽기 전용 타입 연산 프로퍼티
//읽기 전용에서는 get을 생략할 수 있다.
static var selfIntroduction:String{
return "학생 타입입니다.(타입 연산 프로퍼티)"
}
}
[3-2] 프로퍼티 사용하기
//타입연산 프로퍼티 사용
print(Student.selfIntroduction) //학생 타입입니다.(타입 연산 프로퍼티)
//인스턴스 생성
var person : Student = Student()
person.korAge = 10
//인스턴스 저장 프로퍼티 사용
person.name = "ggg"
print(person.name) //ggg
//인스턴스 연산 프로퍼티
print(person.selfInstroduction) //저는 Swift반 ggg입니다.
print("제한국 나이는 \(person.korAge) 이고, 미국 나이는 \(person.westenAge) 입니다.")
//제한국 나이는 10 이고, 미국 나이는 9 입니다.
[3-3] 프로퍼티 응용하기
struct Money {
var currencyRate:Double = 1100
var dollar:Double = 0
var won : Double{
get{
return dollar * currencyRate
}
set{
dollar = newValue / currencyRate
}
}
}
var moneyInMyPocket = Money()
print(moneyInMyPocket.dollar)//0.0
moneyInMyPocket.won = 11000.0
print(moneyInMyPocket.won)//11000.0
print(moneyInMyPocket.dollar)//10.0
moneyInMyPocket.dollar = 10
print(moneyInMyPocket.won)//11000.0
// 지역변수, 전역변수
/*
저장프로퍼티와 연산프로퍼티의 기능은
함수, 메서드, 클로저, 타입 등의 외부에 위치한
지역/전역 변수에도 모두 사용가능하다.
*/
var aaa:Int = 100
var bbb:Int = 200
var sum:Int{
return aaa + bbb
}
print(sum) //300
[4] 프로퍼티 감시자
프로퍼티 감시자를 사용하면 프로퍼티 값이 변경될 때 원하는 동작을 수행할 수 있다.
[4-1] 프로퍼티 감시자 정의
struct MoneyAgain {
//프로퍼티 감시자 사용
var currencyRate:Double = 1100{
//변경 전
willSet(newRate){
print("환율이 \(currencyRate)에서 \(newRate)으로 변경될 예정입니다.")
}
//변경 후
didSet(oldRate){
print("환율이 \(oldRate)에서 \(currencyRate)으로 변경되었습니다.")
}
} // - end
//프로퍼티 감시자 사용
var dollar:Double = 0 {
//변경 전
willSet{
//willSet의 암시적 매개변수 이름 newValue
print("\(dollar) 달러에서 \(newValue)달러로 변경될 예정입니다.")
}
//변경 - 후
didSet{
//didSet의 암시적 매개변수 이름 oldValue
print("\(oldValue) 달러에서 \(dollar)로 변경되었습니다.")
}
}// -end
//연산 프로퍼티
var won:Double {
get{
return dollar * currencyRate
}
set{
dollar = newValue / currencyRate
}
/*
프로퍼티 감시자와 연산프로퍼티 기능을 동시에 사용할 수 없다.
*/
}
}// struct - end
[4-2] 프로퍼티 감시자 사용
var moneyInMyPocketAgain : MoneyAgain = MoneyAgain();
//환율이 1100.0에서 1150.0으로 변경될 예정입니다.
moneyInMyPocketAgain.currencyRate = 1150
//환율이 1100.0에서 1150.0으로 변경되었습니다.
//0.0 달러에서 10.0달러로 변경될 예정입니다.
moneyInMyPocketAgain.dollar = 10
//0.0 달러에서 10.0로 변경되었습니다.
print(moneyInMyPocketAgain.won) //11500.0
/*
프로퍼티 감시자 기능은 함수, 메서드, 클로저, 타입 등
외부에 위치한 지역/전역 변수에도 모두 사용가능하다.
*/
var ccc:Int = 100 {
willSet{
print("\(ccc)에서 \(newValue)로 변경될 예정입니다.")
}
didSet{
print("\(oldValue)에서 \(ccc)로 변경되 었습니다.")
}
}
//100에서 200로 변경될 예정입니다.
ccc = 200
//100에서 200로 변경되 었습니다.
참고
'아이폰 개발 > Swift' 카테고리의 다른 글
[스탠포드]Swift 강좌 - ios 구조 (0) | 2021.03.09 |
---|---|
swift 기초 - assert , guard , protocol (1) | 2021.03.05 |
swift 기초 - 옵셔널 체이닝, 타입캐스팅 (0) | 2021.03.05 |
swift 기초 - 상속, 인스턴스의 생성과 소멸 (0) | 2021.03.04 |
swift 기초 - 옵셔널, 구조체, 클래스, 열거형, 값타입 참조타입 (0) | 2021.03.03 |