옵셔널(optional)

OZA·2021년 2월 8일
0

Swift

목록 보기
4/4
post-thumbnail

This is created by taking the lecture below
iOS프로그래밍기초 - Smile Han


옵셔널(optional)



Int 형 vs. Optional Int 형

  • 10
    • Int
      → Int형 값을 저장
  • Optional(10)
    • Int?         [자료형]?
    • Int!          [자료형]!
      → Int형 값을 저장 or 값이 없음(nil)
Optional(12.1)
//(Optional Double형)
//(Optional Float형)

Optional("하하하")
//(Optional String형)
//(Optional Character형)

https://en.wikipedia.org/wiki/Option_type

  • JAVA8의 Optional 클래스, Kotlin의 Nullable 타입




옵셔널 타입 (매우중요)

  • 옵셔널(optional) 데이터 타입은 다른 프로그래밍 언어에는 없는 새로운 개념

  • 값을 반환할 때 오류가 발생할 가능성이 있는 값은 옵셔널 타입이라는 객체로 감싸서 반환함

    Int("100") 
    print(Int("100"))    // Optional(100)
    //자료형은 구조체로 되어있어서 괄호로 감싸게 되면 보통 initializer가 호출된다
    
    print(Int("100")**!**)   // 100
    
    Int("Hi")
    print(Int("Hi"))     // nil
    //정수 값을 반환할 수 없음, 아무런 값도 반환할 수 없다는 의미로 nil을 반환
    
    print(Int("Hi")!)    // 에러발생, 값이 없을때 강제로 언래핑하면 앱이 죽는다
                         // 강제 언래핑은 값이 nil이 아닐때만 사용
    • swift에서 기본 자료형(Int, Double, String 등)은 nil 값을 저장할 수 없음
    • nil 저장하려면 옵셔널 타입으로 선언해야 함
  • 옵셔널 타입은 변수 또는 상수에 아무런 값이 할당되지 않는 상황을 안전하게 처리하기 위한 방법 제공

  • 옵셔널 타입 변수를 선언하기 위해서는 타입 선언부 뒤에 '?' 문자를 씀

    • 주의 : 변수명 뒤에 '?' 하는 것 아님
var index: Int?
//index라는 이름의 옵셔널 Int변수를 선언
  • index 변수는 정수 값을 갖거나 아무 값도 갖지 않을 수 있음(nil)
var x: Int?       //옵셔널 정수형 변수x 선언 => 값을 할당하지 않으면 default값 nil이 들어감
var y: Int = 0
x = 10            // 주석처리(print)하면?
print(x)          // Optional(10)
print(x!)         // forced unwrapping해서 10이 나옴
print(y)
x = x! + 2        // 12
y = x!            // 12





옵셔널 타입 강제 언래핑 (forced unwrapping) _1

  • 옵셔널 변수에 값이 있으면 옵셔널로 '래핑되었다(wrapped)'고 함
  • 옵셔널에 래핑된 값은 강제 언래핑(forced unwrapping)으로 풀어줌
var x: Int?      //옵셔널 정수형 변수x 선언 => 값을 할당하지 않으면 default값 nil이 들어감
var y: Int = 0
x = 10           // 주석처리(print)하면?
print(x)         // Optional(10)
print(x!)        // forced unwrapping해서 10이 나옴
print(y)
x = x + 2        // 에러발생, 타입이 달라서 계산(X), 변수 x는 옵셔널 타입, 2는 Int 타입
// y = x

💡 옵셔널형 선언 : 자료형 뒤 ?
      옵셔널 언래핑 : 변수명 뒤 !


forced unwrapping

var x: int?
x = 10
if x != nil {
	print(x!)
}
else {
	print("nil")
}

var x1: Int?       //=> 값을 할당하지 않으면 default값 nil이 들어감
if x1 != nil {
	print(x1!)
}
else {
	print("nil")
}

주의 :
if x!=nil 이라고 쓰면 안됨        // 정확한 의도 전달 위해서 띄어쓰기 중요
if x! = nil                                 // nil 할당할 수 없다, x!는 강제 언래핑해서 옵셔널타입 아님
기본 자료형(Int, Double, String 등)은 nil 값을 저장할 수 없음





옵셔널 타입 강제 언래핑 (forced unwrapping) _2 : optional binding

  • 강제 언래핑하는 또 다른 방법으로, 옵셔널 바인딩 (optional binding)을 이용하여
    옵셔널에 할당된 값을 임시 변수 또는 상수에 할당
if let constantname = optionalName {

//옵셔널 변수가 값이 있다면 언래핑해서 일반 상수 constantname에 대입하고 if문 실행
//값이 없다(nil)면 if문의 조건이 거짓이 되어 if문 실행하지 않음

}

if var variablename = optionalName {

//옵셔널 변수가 값이 있다면 언래핑해서 일반 변수 variablename에 대입하고 if문 실행
//값이 없다(nil)면 if문의 조건이 거짓이 되어 if문 실행하지 않음

}

optional binding

var x: Int?
x = 10
if let xx = x {
	print(xx)         // 10  //옵셔널 변수 x가 일반 상수 xx에 대입되면서 optional 벗겨져서 일반 상수됨
}
else {
	print("nil")
}

var x: Int?
x = 10
if let xx = x {
	print(x, xx)      // Optional(10) 10
}
else {
	print("nil")
}

var x1: Int?              //=> 값을 할당하지 않으면 default값 nil이 들어감
if let xx = x1 { 
	print(xx)      
}
else {
	print("nil")      // nil
}





여러 옵셔널을 언래핑

  • 여러 옵셔널 변수를 한번에 언래핑하는 방법은 콤마(,) 사용
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
**if let** firstPet = pet1**,** **let** secondPet = pet2 {
	print(firstPet, secondPet)                          // cat dog
} else {
	print("nil")
}

optional binding (여러 옵셔널 값 동시에 언래핑)

var x: Int?
var y: Int?
x = 10
y = 20

if let xx = x {
	print(xx)        // 10  //옵셔널 변수 x가 일반 상수 xx에 대입되면서 optional 벗겨져서 일반 상수됨
}
else {
	print("nil")
}

if let yy = y {
	print(yy)        // 20
}
else {
	print("nil")
}
var x: Int?
var y: Int?
x = 10
y = 20

if let xx = x, let yy = y {
print(xx, yy)                  // 10 20
} else {
	print("nil")
}





두 가지 옵셔널 타입

  • 옵셔널이 항상 유효한 값을 가질 경우 옵셔널이 암묵적인 언래핑(implicity unwrapped)이 되도록 선언할 수도 있음

  • 클래스의 아웃렛 변수 초기화에서 많이 사용 (자동 생성되는 코드)

  • 이러한 방법으로 옵셔널이 선언된다면 강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근할 수 있음

  • 암묵적인 언래핑으로 옵셔널을 선언하기 위해서는 선언부에 물음표(?) 대신에 느낌표(!) 를 사용

    var x: Int?        //[옵셔널 변수 선언방법_1]
    var x: Int!         //[옵셔널 변수 선언방법_2]


두 가지 Optional 형 : Int? vs. Int!

let x: Int? = 1                             // Optional(1)
let y: Int = x!                             // forced unwrapping해서 일반 상수 1임
let z = x                                   // Optional(1)
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
let b: Int = a                 //Optional로 사용되지 않으면 자동으로 unwrap함
let c: Int = a!
let d = a                      //Optional로 사용될 수 있으므로 Optional형임
let e = a + 1                  //위에서 a 타입을 Int!로 줬기 때문에 optional 강제언래핑 또 할 필요 없이 풀림
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



Int!형을 property로 갖는 클래스

class MyAge {
	var age: Int!        //age: 옵셔널 변수
	init(age: Int) {
			self.age = age
	}
	func printAge() {
		print(age)            // Optional(1)
		print(age+1)          //2, [age! + 1 라고 쓰지 않아도 됨]
		let age1 : Int = age
		print(age1)           // 1
		let age2 = age + 2
		print(age2)           // 3
		}   
}
var ohh = MyAge(age:1)
ohh.printAge()



왜 옵셔널을 사용하나요?

  • 옵셔널 타입만이 값을 갖지 않는다는 의미의 nil 값을 가질 수 있음

  • You set an optional variable to a valueless state by assigning it the special value nil.

  • nil 값을 옵셔널이 아닌 변수나 상수에 할당할 수 없음

    var mtInt = nil              //에러발생, 일반 변수는 nil 할당할 수 없다
    var mtInt = Int? = nil       //OK
    var mtInt = Int?             //OK, 위와 같은 코드 => 옵셔널 변수는 초기화하지 않으면 자동으로 nil로 초기화
    var myString : String = nil  //유효하지 않은 코드, 일반 자료형에는 nil값이 저장 안된다
    var myConstant = nil         //유효하지 않은 코드, 일반 자료형에는 nil값이 저장 안된다



nil

  • You set an optional variable to a valueless state by assigning it the special value nil.

  • 옵셔널 변수에 nil을 할당하면 값이 없는 상태가 된다

    var serverResponseCode : Int? = 404
    // serverResponseCode contains an actual Int value of 404
    
    serverResponseCode = nil
    // serverResponseCode now contains no value
  • nil cannot be used with nonoptional constants and variable. If a constant or variable in your code needs to work with the absence of a value under certain conditions, always declare it as an optional value of the appropriate type.

  • 상수나 변수가 값이 없는 상태가 존재한다면 옵셔널 타입으로 선언해야 한다

profile
하하하 반갑습니다

0개의 댓글