1. 오전일정 : Swift Playground로 놀아보기
나도 몰랐는데 대학교 시절에 Swift에 대한 기초를 Playground로 배워본 경험이 있다는게 이걸 하면서 새록새록 기억이 났다.
그때는 뭔지도 모르고 그냥 명령어 누르라길래 잼 냠냠했던 것 같은데 지금 보니까 쉽고 귀엽네...
2. 오후일정 : 옵셔널 타입, Swift 연산자 등
[옵셔널 타입]
- 대부분의 다른 프로그래밍 언어에 없는 새로운 개념이다.
- 변수/상수의 값이 할당되지 않은 상황을 처리하기 위해 안전하고 일관된 접근 방식 제공
- 변수 선언 시, 데이터 타입 선언 + ? 문자를 붙여서 사용
- 어떤 값도 할단되지 않은 상태의 옵셔널 상수/변수는 실제로는 nil이라는 값을 가진다.(메모리 공석)
[강제 언래핑]
- 옵셔널 타입으로 만들어진 변수/상수에 값을 집어넣을 때 '래핑되었다", 값을 뺄 때는 '언래핑되었다.' 라고 표현한다.
- 옵셔널 안에 래핑된 값을 사용할 때는, 값을 확인한다는 의미의 '강제 언래핑'이라는 개념을 사용하게 된다.
- 옵셔널 + ! 를 사용하여 추출한다. (사용을 최대한 지양하는 것이 가이드)
- 옵셔널로 할당된 값을 강제언래핑하지 않고 직접 접근한다면 에러가 생긴다.
* 이 개념이 진짜 신기하다.....
// 에러코드 8줄 index 값을 가져오는 것에 에러가 남 -> 강제 언래핑 필요
var index: Int?
index = 2
var nameArray: Array<String> = ["hi", "hello", "how are you"]
if let index {
print(nameArray[index])
} else {
print("index does not contain vales")
}
// 정상 코드 : 강제 언패핑 사용
var index: Int?
index = 2
var nameArray: Array<String> = ["hi", "hello", "how are you"]
if let index {
print(nameArray[index!])
} else {
print("index does not contain vales")
}
- 옵셔널을 선언할 때 물음표(?) 대신 느낌표(!)를 사용하여 강제적으로 언래핑되도록 옵셔널을 선언할 수 있다.
- 이 방식으로 하면 코드 내부에서 강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근할 수 있느나, 사용을 하지 않는 것이 좋다.
var index: Int!
index = 2
var nameArray: Array<String> = ["hi", "hello", "how are you"]
if let index {
print(nameArray[index])
} else {
print("index does not contain vales")
}
[**옵셔널 바인딩]
- 강제 언래핑 대신, 옵셔널로 할당된 값은 옵셔널 바인딩을 이용해여 임시 변수나 상수에 할당할 수 있다.
- if let(var) a = b { b 사용하지 않음, a만 사용함 }
<코드 실행 작업>
- 지정된 옵셔널이 값을 가지고 있는지 확인(nil인지 값을 보유했는지)
- 옵셔널 변수/상수가 값을 가지고 있는 경우 선언된 상수 또는 변수에 그 값을 할당(copy)하고 코드가 실행된다.
var index: Int?
index = 2
var nameArray: Array<String> = ["hi", "hello", "how are you"]
if let checkOptional = index {
print(nameArray[checkOptional])
} else {
print("index does not contain vales")
}
** 임시상수 checkOptional은 if let 구문 안에서만 유효하며, if 구문 실행이 끝나면 이 상수는 더이상 존재하지 않는다. **
이런 이유 때문에, 옵셔널로 할당된 동일한 변수/상수명을 사용해도 충돌이 발생하지 않는 것이다. (하지만 바인딩 하는 변수와 바인딩 하는 변수명을 다르게 사용하는 것이 더 좋다.)
<옵셔널 바인딩 동시처리>
- if let(var) 구문 안에 If let(var) ... , let(var) ... 형식으로 반점을 찍어서 나열함
-> if 다음에 오는 "let(var) ..." 이부분이 Bool이 아니기 때문에 &&를 사용할 수는 없다.
var icecream: String?
var jelly: String?
icecream = "soft icecream"
jelly = "banana jelly"
if let checkIcecream = icecream, let checkJelly = jelly {
print(checkIcecream)
print(checkJelly)
} else {
print("index does not contain vales")
}
//둘중 하나라도 nil이라면
var icecream: String?
var jelly: String?
jelly = "banana jelly"
if let checkIcecream = icecream, let checkJelly = jelly {
print(checkIcecream)
print(checkJelly)
} else {
print("index does not contain vales")
}
//결과값 : index does not contain vales
2. if let(var) ..., let(var) ..., Bool형 {} 이렇게 작성도 가능하다.
var icecream: String?
var jelly: String?
icecream = "soft icecream"
jelly = "banana jelly"
let jellyCount = 15
if let checkIcecream = icecream, let checkJelly = jelly, jellyCount > 13 {
print(checkIcecream)
print(checkJelly)
} else {
print("index does not contain vales")
}
* 옵셔널 체이닝이라는 개념도 있다고 하는데,,, 가뜩이나 복잡한 옵셔널을 체인??? 연달해서 또 쓴다? 복잡하겠는걸요...
[옵셔널 주의점]
- 할당된 값이 없거나, nil을 할당할 수 있는 것은 옵셔널 타입(선언 시 ? 붙임 것)뿐이다.
- 옵셔널이 아닌 변수/상수에는 nil할당 불가능
[Any, AnyObject와 nil]
- Any, AnyObject는 가능한 사용하지 않는 것이 좋다. (타입은 최대한 명확하게 명시)
- 타입에 엄격한 Swift 언어 특성상 Any, AnyObject로 선언된 변수의 값을 가져가 쓰기 위해서는 매번 타입을 확인해야 하기에 오류 및 위험이 증가한다.
1. Any 타입
- 스위프트의 모든 데이터 타입을 사용할 수 있다는 뜻 -> 이렇게 사용하는 것에는 다 댓가가 따른다.(아래코드 마지막줄 참고)
var whatIsAny: Any = "Hello"
whatIsAny = 50
whatIsAny = 123.456
//어떤 타입을 넣든지 에러가 나지 않는다.
let iAmDouble: Double = whatIsAny //컴파일 오류(타입에러) 발생
마지막 코드가 오류가 나는 이유는 Double 타입 입장에서는 "Any타입이 뭐를 받아올 줄 알고 내가 Any를 받아줘?!???" 이런 의미라고 한다.
2. AnyObject
- Any보다는 조금 한정된 의미로, 클래스의 인스턴스만 할당할 수 있다.
-> 기존 사용하던 Int, String, Float 등은 모두 클래스가 아닌 구조체 형식으로 만들어진 인스턴스다.
3. nill
- 특정 타입이 아니라 '없음'을 나타내는 Swift의 키워드로 값이 들어있지 않고 비어있음을 나타낸다.
- nil이면 변수/상수에 접근했을 때 잘못된 메모리 접근으로 런타임 오류가 발생한다.
var testVar: Int
testVar = nil //컴파일 오류발생
[타입 캐스팅]
1. 타입 캐스팅 = 형 변환
- Swift 코드 작성 시 컴파일러가 어떤 값의 특정 타입을 식별하지 못하는 경우 발생
- 이 경우 메서드나 함수가 반환하는 값이 불분명하거나 예상되지 않는 타입의 값일 때 발생
- as 키워드를 사용하여 코드가 의도하는 값의 타입을 컴파일러가 알 수 있게 해야 한다.
let value = a as! String
// A 메서드의 반환하는 값을 String 타입으로 처리해야 한다고 컴파일러에게 알려주는 코드이다.
2. 업 캐스팅
- 타입캐스팅의 두가지 형태 중 하나
- 하위 클래스를 상위 클래스 인 것처럼 기능 및 권한 부여하는 것처럼 변경하는 것이다.
3. 다운 캐스팅
- 타입캐스팅의 두가지 형태 중 하나
- 문제를 일으킬 경우 컴파일러가 잡아낼 것이라는 보장은 불가하다. (안정성 보장할 수 없다.)
- 컴파일러가 발견하지 못하면 대부분의 경우 런타임에서 에러가 발생할 것이다.
- as!를 사용하여 하위 클래스의 기능을 부여하는 것으로 변환하는 것이다. - 강제 변환
- 옵셔널 바인딩(as?)을 사용할 수 있고 as?를 사용해서 다운 캐스팅을 사용하면 더 안전하다.
[타입 검사]
- is 키워드를 사용하여 타입 검사 할 수 있다.
let name: String = "길동"
let hongHouse: String = "홍"
if name is hongHouse {
print("\(name)이는 \(honghouse)씨 집안의 자식이다.")
}
[Swift 표현식 구문]
var test = 1 + 2
// 위 내용에서 표현식을 찾아보자
/*
하나의 연산자 = operator = '+'
두 개의 피연산자 = operand = '1', '2'
할당자 = assignment = '=' //call by value, '=' 기준으로 오른쪽 값을 왼쪽으로 복제하는 것
*/
[기본 할당 연산자]
- 할당 연산자('=')는 표현식의 결과를 변수에 저장하는 역할을 한다.
- 기본적으로 = 할당 연산자는 = 기준 왼쪽, 오른쪽에 1개씩 총 2개의 피 연산자를 받는다.
[산술 연산자]
- Swift는 수학적 표현식을 생성하기 위하여 다양한 연산자 제공
- 산술 연산자의 대부분은 2개의 피연산자를 받는 이항 연산자이다.
-> 예외) 양수를 음수로 만들어주는 단항 음수 연산자는 하나의 피연산자를 받는다. -10, -5
[복합 할당 연산자]
- 산술 또는 논리 연산과 하당 연산자를 결합하기 위해서 사용
x += y
x = x + y //두 식 모두 같은 결과를 가진다
//산술 연산자
x += y
x -= y
x *= y
x /= y
x %= y
[비교 연산자]
- Swift는 비교를 수행하는 데 유용한 논리 연산자를 가짐
- 비교 연산자('==')는 모두 비교 결과에 따라 Bool타입의(참/거짓) 결과를 반환
- 비교 연산자는 모두 두 개의 피연산자를 가지고 작업하기에 이항연산자라고 함
- 비교 연산자는 프로그램 흐름 제어 로직을 만드는 데 가장 많이 사용
let condition: Bool = (x == y)
let condition: Bool = x == y //괄호는 사용여부 상관 없음
// 비교 연산자 예시
var result: Bool?
var x = 10
var y = 20
result = x < y
print("\(result)") // 출력값 : True
[불리언 논리 연산자]
- Bool형 결과를 반환함
1. NOT(!) 연산자
- 단순히 불리언 변수의 현재 값 또는 표현식의 결과를 반전시킨다.
- 변수/상수 이름 앞에 ! 문자를 두면 값이 false로 바뀐다.
2. OR(||) 연산자
- 연산자(||) 기준 왼쪽, 오른쪽 두 개의 피연산자 중 하나 이상이 ture이면 true반환
- 연산자(||) 기준 왼쪽, 오른쪽 두 개의 피연산자 모두 flase이면 flase반환
3. AND(&&) 연산자
- 연산자(&&) 기준 왼쪽, 오른쪽 두 개의 피연산자 모두 ture이면 true반환
- 연산자(&&) 기준 왼쪽, 오른쪽 두 개의 피연산자 중 하나 이상이 false이면 false반환
[범위 연산자]
- 값이 범위를 선언할 수 있도록 하는 연산자이다.
- 프로그램에서 반복 작업을 할 때 매우 중요하게 사용한다.
<닫힌 범위 연산자>
- x ... y -> x로 시작해서 y로 끝나는 숫자 범위(x, y 모두 포함)
- 5 ... 8 -> 5,6,7,8
<반 개방 범위 연산자>
- x ..< y -> x로 시작해서 y-1로 끝나는 숫자 범위(x만 포함)
- 5 ..< 8 -> 5,6,7
<단방향 범위 연산자>
- 그 범위 앞의 시작 또는 끝에 도달할 때까지(또는 다른 조건이 충족할 때까지) 지정된 범위 방향으로 최대한 확장할 수 있는 범위 지정
- 범위 선언부의 한쪽 부분을 생략
- x ...
- ... y
- 2 ... -> 문자열의 길이와는 상관없이 문자열의 세번째 문제(인덱스2)부터 시작해서 마지막 문자들을 지정하는 범위
- ... 6 -> 첫번째 위치의 문자부터 7번째 문자(인덱스6)까지의 범위
[삼항 연산자]
- Swift는 코드 내에서 판단을 간단히 하기 위한 방법으로 삼항 연산자(삼항식)를 지원한다.
조건문 ? 참(true)인 경우의 표현식 : 거짓(false)인 경우의 표현식
let x: Int = 10
let y: Int = 20
print("무엇이 더 클까요? \(x > y ? x : y)") //출력값 : 무엇이 더 클까요? 20
PS.
Apple에게 기술을 제안하는 사이트고, 사람들이 제안을 하면 해당 기술이 도입이 되기도 하고 거절이 되기도 한다고 한다.
https://apple.github.io/swift-evolution/
3. 오늘의 리뷰
오늘을 하나로 표현하자면 Playground가 메인이다.
Swift Playgoround 단계가 올라갈수록 한번에 알고리즘이 생각나지 않다보니 아주 집중하게 된다ㅋㅋㅋ
아이패드 얼른 사서 플레이그라운드 게임할 예정!
'멋쟁이사자처럼 앱스쿨 1기' 카테고리의 다른 글
[멋쟁이사자처럼] 앱스쿨 1기 - Swift 함수&클로저 표현식(closure expression) (9일차 22.09.26) (2) | 2022.09.26 |
---|---|
[멋쟁이사자처럼] 앱스쿨 1기 - Playgorund 문제풀이&Swift 제어흐름 (8일차 22.09.23) (0) | 2022.09.23 |
[멋쟁이사자처럼] 앱스쿨 1기 - 컴퓨터 기본지식&데이터타입 (6일차 22.09.21) (2) | 2022.09.21 |
[멋쟁이사자처럼] 앱스쿨 1기 - 정렬 알고리즘&Swift 기초(5일차 22.09.20) (2) | 2022.09.20 |
[멋쟁이사자처럼] 앱스쿨 1기 - 스프린트회고&Swift 둘러보기(4일차 22.09.19) (0) | 2022.09.19 |