iOS

[iOS] 문법 - 옵서널 타입

코딩하는둥이 2023. 9. 18. 15:40

옵서널 타입

 : 값을 반환할 때 오류가 발생할 가능성이 있는 값을 옵서녈 타입 객체로 감싸서 반환

   기본자료형 (Int, Double,String) nil값으로 저장 불가능 => 옵셔널 사용하면 된다.

    선언하기 위해서는 타입 선언부 뒤에 “?” 문자를 씀

    자료형 뒤 ?

var optionalValue: Int? = 5 // 값이 있을 때
var anotherOptionalValue: Int? // 값이 없을 때

* 증감 연산자(x++)와 감소연산자(x--)가 없다.

   => x+=1, x-=1이런 식으로 쓰면 된다.

더보기
더보기

nil 

옵셔널 변수에 초깃값을 할당하지 않으면 자동으로 nil이 할당됨

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")
}
더보기
더보기

주의 : if x!=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
더보기
더보기

참고: Swift 5.7부터는 if let x 라고 써도 됨

          if let x = x 라고 써도 됨

 

여러 옵셔널 언래핑

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