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/
Swift Evolution
apple.github.io
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 |