옵서널 타입
: 값을 반환할 때 오류가 발생할 가능성이 있는 값을 옵서녈 타입 객체로 감싸서 반환
기본자료형 (Int, Double,String) nil값으로 저장 불가능 => 옵셔널 사용하면 된다.
선언하기 위해서는 타입 선언부 뒤에 “?” 문자를 씀
자료형 뒤 ?
var optionalValue: Int? = 5 // 값이 있을 때
var anotherOptionalValue: Int? // 값이 없을 때
* 증감 연산자(x++)와 감소연산자(x--)가 없다.
=> x+=1, x-=1이런 식으로 쓰면 된다.
Int 형 vs Optional Int 형
var x : Int = 10
print(x)
var y : Int? = 10
print(y,y!)
// Optional(10) 10
강제 언래핑(forced unwrapping)
: 옵셔널 변수에 값이 있으며 래핑되었다고 하는데 강제 언래핑을 통해 래핑된 값을 풀어준다.
변수명 뒤 !
let optionalValue: Int? = 42
let unwrappedValue = optionalValue! // 값이 확실히 존재하는 경우에만 사용
var x : Int? //옵셔널 정수형 변수 x 선언
var y : Int = 0
x = 10 // 주석처리하면?
print(x) // Optional(10)
print(x!) // forced unwrapping해서 10이 나옴
print(y)
var x : Int?
x = 10;
x = x! + 2
print(x)
// optional(12)
var x : Int?
var y : Int = 0
x = 10
y = x!
print(x) // Optional(10)
print(x!)// forced unwrapping해서 10이 나옴
print(y) 10
var x : Int?
x = 10
if x != nil {
print(x!)
}
else {
print("nil")
}
var x1 : Int?
if x1 != nil {
print(x1!)
}
else {
print("nil")
}
optional binding
:옵셔널에 할당된 값을 임시 변수 또는 상수에 할당
var x : Int?
x = 10
if let xx = x { //옵셔널 변수 x가 값(10)이 있으므로 언래핑해서 일반 상수 xx에 대입하고 if문 실행
print(x,xx)
}
else {
print("nil")
}
var x1 : Int?
if let xx = x1 { //옵셔널 변수 x1이 값이 없어서 if문의 조건이 거짓이 되어 if문 실행하지 않고 else로 감
print(xx)
}
else {
print("nil")
}
var x : Int?
x = 10
if let x = x {
print(x)
}
else {
print("nil")
}
var x1 : Int?
if let x1 = x1 {
print(x1)
}
else {
print("nil")
}
// 10 nil
여러 옵셔널 언래핑
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
if let firstPet = pet1, let secondPet = pet2 {
print( firstPet, secondPet)
} else {
print("nil")
}
// cat dog
var pet1: String?
var pet2: String?
pet1 = "cat"
if let firstPet = pet1, let secondPet = pet2 {
print( firstPet, secondPet)
} else {
print("nil")
}
// nil
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
if let pet1 = pet1, let pet2 = pet2 {
print( pet1, pet2)
} else {
print("nil")
}
// cat dog
두 가지 옵셔널 타입
: 옵셔널이 항상 유효한 값을 가질 경우 옵셔널이 암묵적인 언래핑(implicitly unwrapped)이 되도록 선언할 수도 있음
클래스의 아웃렛 변수 초기화에서 많이 사용(자동 생성되는 코드)
var x:Int! = 10
if let x{
x
}
var x:Int? = 10
if let x{
x
}
let x : Int? = 1
let y : Int = x!
let z = x
print(x,y,z) //Optional(1) 1 Optional(1)
print(type(of:x),type(of:y),type(of:z))
//Optional<Int> Int Optional<Int>
let a : Int! = 1 //Implicitly Unwrapped Optional
let b : Int = a //Optional로 사용되지 않으면 자동으로 unwrap함
let c : Int = a!
let d = a //Optional로 사용될 수 있으므로 Optional형임
let e = a + 1
print(a,b,c,d,e) //Optional(1) 1 1 Optional(1) 2
print(type(of:a),type(of:b),type(of:c),type(of:d), type(of:e))
//Optional<Int> Int Int Optional<Int> Int
Nil-Coalescing Operator (Nil합병연산자)
: 옵셔널변수 ?? nil일 때 할당되는 값
옵셔널 변수의 값이 nil이면 ?? 다음 값으로 할당됨
옵셔널 변수의 값이 nil이 아니면 언래핑된 값이 나옴
let defaultColor = "black"
var userDefinedColor: String? // defaults to nil
var myColor = userDefinedColor ?? defaultColor
//nil이므로 defaultColor인 black으로 할당됨
print(myColor) //black
userDefinedColor = "red"
myColor = userDefinedColor ?? defaultColor
//nil이 아니므로 언래핑된 red가 할당됨
print(myColor) //red, 주의 optional(red)가 아님
let defaultAge = 1
var age : Int?
age = 3
print(age) //과제:값은?
var myAge = age ?? defaultAge
//age가 nil이 아니므로 언래핑된 값이 나옴
print(myAge) //과제: 값은?
//Optional(3) 3
범위연산자
1) 닫힌 범위 연산자(closed range operator)
for i in 1...5{
print(i)
}
// 1 2 3 4 5
2) 반 열린 범위 연산자(half-open range operator)
for i in 1..<5{
print(i)
}
// 5 6 7
3) One-Sided Ranges
let names = ["A", "B", "C", "D"]
for name in names[..<2] {
print(name)
}
// A B
let names = ["A", "B", "C", "D"]
for name in names[2...]{
print(name)
}
//C D
let names = ["A", "B", "C", "D"]
for name in names[...2]{
print(name)
}
// A B C
_
for _ in 0..<10 {
print("seojiho")
}
// 출력결과
seojiho
seojiho
seojiho
seojiho
seojiho
seojiho
seojiho
seojiho
seojiho
seojiho
let names = ["A","b","C","D"];
for name in names{
print(name)
}
출력결과
A
b
C
D
let numberOfLegs = ["Spider": 8,"Ant":6, "Dog":4]
for(animalName, legCount) in numberOfLegs{
print("(animalName)s have\(legCount) leg");
}
출력결과
(animalName)s have8 leg
(animalName)s have4 leg
(animalName)s have6 leg
while
var myCount = 0
while myCount < 1000 {
myCount+=1
}
print(myCount)
//출력결과 1000
repeat {
//
} while 조건식
var i = 10
repeat {
i=i-1
print(i) //출력 결과
} while (i > 0)
//출력결과 1000
repeat {
//
} while 조건식
var i = 10
repeat {
i=i-1
print(i) //출력 결과
} while (i > 0)
//main.swift:3:9: error: cannot find '조건식' in scope
} while 조건식
//while 반복문의 몸체는 적어도 한번은 실행
break
for i in 1..<10{
if i>5{break}
print(i)
}
continue
for i in 1...10 {
if i % 2 == 0 {
continue
}
print(i)
}
//출력결과
1
3
5
7
9
조건부에서 , 의미
var a = 1
var b = 2
var c = 3
var d = 4
if a < b && d > c {
print("yes")
}
if a < b, d > c { ..if문에서 콤마는 and&&
}
출력결과
yes
yes
if문
var x = 3
if x % 2 == 0 {
print("짝수입니다")
}else{
print("홀수입니다")
}
// 홀수입니다.
다중 if-else
var num = 3
if (num == 1 || num == 3){
print("당신은 남성이군요!\n")
}else if (num == 2 || num == 4){
print("당신은 여성이군요!\n")
}else {
print("당신은 대한민국 사람이 아니군요!\n")
}
//출력결과
당신은 남성이군요
let weight = 60.0
let height = 170.0
let bmi = weight / (height*height*0.0001) // kg/m*m
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(bmi), 판정:\(body)")
// 출력결과
BMI:20.761245674740483, 판정:정상
switch-case문
switch 표현식
{
case match1:
구문
case match2:
구문
case match3, match4:
구문
default:
구문
}
//각 case문 마지막에 break가 자동으로 들어 있음
//첫 번째 case는 "a"로 설정되어 있지만, 해당 case에 아무런 실행문이 없기 때문에 유효하지 않다.
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a": // Invalid, the case has an empty body
case "A":
print("A글자")
default:
print("A글자 아님")
}
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a":
print("소문자 a")
case "A":
print("대문자 A")
default:
print("A글자 아님")
}
let weight = 60.0
let height = 170.0
let bmi = weight / (height * height * 0.0001) // kg/m*m
var body = ""
switch bmi {
case ..<18.5:
body = "저체중"
case 18.5..<25:
body = "정상"
case 25..<30:
body = "1단계 비만"
case 30..<40:
body = "2단계 비만"
default:
body = "3단계 비만"
}
print("BMI: \(bmi), 판정: \(body)")
switch-case에서 where 절 사용
: where절은 조건을 추가 해준다.
var temperature = 60
switch (temperature)
{
case 0...49 where temperature % 2 == 0:
print("Cold and even")
case 50...79 where temperature % 2 == 0:
print("Warm and even")
case 80...110 where temperature % 2 == 0:
print("Hot and even")
default:
print("Temperature out of range or odd")
}
let number = 15
switch number {
case let x where x % 2 == 0:
print("\(number) is even")
case let x where x % 2 != 0:
print("\(number) is odd")
default:
print("Number is out of range")
}
var numbers: [Int] = [1, 2, 3, 4, 5]
for num in numbers where num > 3 {
print(num)
}
출력
4
5
fallthrough
: case문 다음에 break 문을 포함할 필요가 없음
일치하는 case문을 만나면 자동으로 빠져나옴
case별로 빠져 나가지 않고 아래로 계속 내려가게 하려면 fallthrough 문 사용
var value = 4
switch (value)
{
case 4:
print("4")
fallthrough
case 3:
print("3")
fallthrough
case 2:
print("2")
fallthrough
default:
print("1")
}
형 변환
1) as로 upcasting : 자식인스턴스를 부모클래스로 변환
: 상속 관계가 있는 클래스들끼리만 타입 캐스팅 가능하다.
as 연산자로 타입 변환(type casting)
as 연산자
: 자식 인스턴스 as 부모 클래스이다.
upcasting 안전한 태스팅이 되어 자식이 추상화가 된다.
타입 캐스팅(Type Casting)
: 프로그래밍에서 한 데이터 타입을 다른 데이터 타입으로 변환하는 프로세스이다.
2) as! as?로 downcasting:부모인스턴스를 자식클래스로 변환
: 부모 인스턴스를 자식 클래스로 변환하는 데 사용
부모인스턴스 as! 자식클래스
: downcasting 일반 타입으로 반환
: 다운캐스팅이 반드시 성공할 것이라는 확신이 있을 때
부모인스턴스 as? 자식클래스
: downcasting 옵셔널 타입으로 반환.
: 확신이 없을 경우
타입 검사
: 객체의 타입을 확인하여 해당 타입에 따라 다른 작업을 수행하는 프로그래밍 작업
let x = 1
if x is Int {
print("Int!")
}
// Int!
'iOS' 카테고리의 다른 글
[iOS] 함수와 매서드 (0) | 2023.10.15 |
---|---|
[iOS] 클로저 알아보기 (0) | 2023.10.06 |
[iOS] 1급 객체(1급 시민) 알아보기 (0) | 2023.10.04 |
[iOS] 기초문법 (0) | 2023.09.25 |
[iOS 프로그래밍] 문법 (0) | 2023.09.11 |