Skip to content

Latest commit

ย 

History

History
396 lines (282 loc) ยท 9.59 KB

Optional.md

File metadata and controls

396 lines (282 loc) ยท 9.59 KB

Optional

Optional Type Declaration

๊ธฐ๋ณธํ˜•

 var ๋ณ€๋™์ด๋ฆ„ : ํƒ€์ž…
 var ๋ณ€๋™์ด๋ฆ„ : ์˜ต์…”๋„<ํƒ€์ž…>

//ํ‘œํ˜„ํ•˜๋Š”๋ฐ์— 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Œ.
var optionalType1: String?   // ์ž๋™ ์ดˆ๊ธฐํ™” nil //๊ฐ’์ด ์—†๋Š” ๊ฒƒ์œผ๋กœ ์ดˆ๊ธฐํ™”๋จ var optionalType1: String = nil ๊ณผ ๋™์ผ
var optionalType2: Optional<Int> = nil   // ์ˆ˜๋™ ์ดˆ๊ธฐํ™”. (๊ฐ’ ๋˜๋Š” nil)

optionalType1
type(of: optionalType1)
type(of: optionalType2)


// Valueless state - nil

var optionalIntInit = Optional<Int>(0)
var optionalInt: Int? = 0
type(of: optionalInt)

optionalInt = nil
optionalInt


// Optional -> NonOptional

//var nonOptional1 = nil
//var nonOptional2: Int = nil
//var nonOptionalType: Int = optionalInt



// Optional <- NonOptional

let nonOptional = 1
optionalInt = nonOptional
optionalInt = 100


// Optional -> NonOptional (X)
// Optional <- NonOptional (O)
// ์˜ต์…” -> ๋…ผ๋ถˆ๊ฐ€.
//๋…ผ์˜ต์…”๋„์„ ์˜ต์…”๋„์— ๋„ฃ๋Š”๊ฒƒ์€ ๊ดœ์ฐฎ

// ๊ฐ ํƒ€์ž…์ด ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ’์˜ ๋ฒ”์œ„
// var nonOptionalNumber: Int    // ์ •์ˆ˜ ๊ฐ€๋Šฅ
// var optionalNumber: Int?      // ์ •์ˆ˜ or nil ๊ฐ€๋Šฅ

Optional Biding and Forced Unwrapping

var convertedNumber: Int? = 123

if convertedNumber != nil {
  // warning + Optional(123)
  print("convertedNumber has an integer value of \(convertedNumber).")
}

Optional Binding

  • ์›Œ๋‹์ œ๊ฑฐ, ์˜ต์…”๋„ ์“ฐ์ง€์•Š๊ณ  if๋ฌธ ์•ˆ์—์„œ ๋‹ค๋ฃฐ์ˆ˜ ์žˆ๊ฒŒ

๊ธฐ๋ณธํ˜•

 if let ๋…ผ์˜ต์…”๋„ = ์˜ต์…”๋„ํ‘œํ˜„ {
   ์‹คํ–‰์ฝ”๋“œ
 //} else {
 //print("nill") ์ด๋Ÿฐ์‹์œผ๋กœ
 
 while let ๋…ผ์˜ต์…”๋„ = ์˜ต์…”๋„ํ‘œํ˜„ {
   ์‹คํ–‰์ฝ”๋“œ
 }
 guard let ๋…ผ์˜ต์…”๋„ = ์˜ต์…”๋„ํ‘œํ˜„  else {
   ์‹คํ–‰์ฝ”๋“œ 
 }
let someValue = "100"

if let number = Int(someValue) {
  print("\"\(someValue)\" has an integer value of \(number)")
} else {
  print("Could not be converted to an integer")
}
//์˜ต์…”๋„ 100 //๊ฐ’์ด ์—†์œผ๋ฉด else, ๊ฐ’์ด ์žˆ์œผ๋ฉด number์— ๋‹ด๊ฒจ์„œ ์‹คํ–‰
//"100" has an integer value of 100

Optional Binding

var optionalStr: String? = "Hello, Optional"
print(optionalStr)

if let optionalStr = optionalStr {
  print(optionalStr)
} else {
  print("valueless string")
}



// ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ๊ณผ ๋ถˆ๋ฆฌ์–ธ ์กฐ๊ฑด์„ ํ•จ๊ป˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
if let firstNumber = Int("4"),
  let secondNumber = Int("42"),
  firstNumber < secondNumber,
  secondNumber < 100 {
  print("\(firstNumber) < \(secondNumber) < 100")
}
//๋ชจ๋“  ์กฐ๊ฑด์„ ๋งŒ์กฑํ–ˆ์„ ๋•Œ, ์‹คํ–‰


// ์œ„์™€ ๋™์ผํ•œ ๋™์ž‘
if let firstNumber = Int("4") {
  if let secondNumber = Int("42") {
    if firstNumber < secondNumber, secondNumber < 100 {
      print("\(firstNumber) < \(secondNumber) < 100")
    }
  }
}

Forced Unwrapping

 let ๋…ผ์˜ต์…”๋„ = ์˜ต์…”๋„ํ‘œํ˜„!
 
 // !๋Š” ๋ฐ˜๋“œ์‹œ๊ฐ’์ด ์žˆ๋‹ค! ๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ
if convertedNumber != nil {
//  print("convertedNumber has an integer value of \(convertedNumber).")
  print("convertedNumber has an integer value of \(convertedNumber!).")
}

print(convertedNumber)
print(convertedNumber!)


// Forced unwrap of nil value
//nil์ผ๋•Œ !๋ฅผ ๋ถ™์ด๊ณ  ์‹คํ–‰ํ•˜๋ฉด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ. :๊ฐ’์ด ์žˆ๋‹ค๊ณ  ํ•ด๋†“๊ณ ๋Š”, ๊ฐ’์ด ์—†์–ด์„œ ์—๋Ÿฌ๋‚จ. (ํ™•์‹คํ•  ๋•Œ๋งŒ !๋ฅผ ์“ฐ๊ณ , ํ™•์‹คํ•˜์ง€์•Š์„๋•Œ๋Š” ์˜ต์…”๋„์„ ๋‹ค๋ค„์•ผํ•จ)
convertedNumber = nil
convertedNumber
//convertedNumber!

IUO (Implicitly Unwrapped Optionals)

// Optional
let possibleString: String? = "An optional string."
//let forcedString: String = possibleString  // Error
let forcedString: String = possibleString!
type(of: possibleString)
type(of: forcedString)


// Implicitly Unwrapped Optional
// Non Optional ํƒ€์ž…์ธ ๊ฒƒ์ฒ˜๋Ÿผ ํ•จ๊ป˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
var assumedString: String! = "An implicitly unwrapped optional string."
let stillOptionalString = assumedString
type(of: assumedString)
type(of: stillOptionalString)
print(assumedString)
print(assumedString!)

//?์ผ๋•Œ๋Š” ๋„ฃ์ง€ ๋ชปํ–ˆ๋Š”๋ฐ !์ผ๋•Œ๋Š” ๋„ฃ์„ ์ˆ˜ ์žˆ์Œ. ๋ฐ˜๋“œ์‹œ ๊ฐ’์ด ์žˆ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ.
//Optional - >nonOptional(x)
//String? - > String(x)
//String! -> String(o)

let implicitString: String = assumedString
type(of: implicitString)

//assumedString = nil
//print(assumedString!)


/*
 - ์ถ”ํ›„ ์–ด๋Š ์ˆœ๊ฐ„์—์„œ๋ผ๋„ nil ์ด ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ์ด ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•จ
 - nil value ๋ฅผ ์ฒดํฌํ•ด์•ผ ํ•  ์ผ์ด ์ƒ๊ธธ ๊ฒฝ์šฐ๋Š” ์ผ๋ฐ˜์ ์ธ ์˜ต์…”๋„ ํƒ€์ž… ์‚ฌ์šฉ
 - ํ”„๋กœํผํ‹ฐ ์ง€์—ฐ ์ดˆ๊ธฐํ™”์— ๋งŽ์ด ์‚ฌ์šฉ//์ผ๋‹จ ํ”„๋กœํผํ‹ฐ๋Š” ๋งŒ๋“ค์–ด๋‘๋Š”๋ฐ, ๋’ค ๋Šฆ๊ฒŒ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„๋–„?
 */

Nil-coalescing Operator

optionalStr = nil

var result = ""
if optionalStr != nil {
   result = optionalStr!
} else {
   result = "This is a nil value"
}
print(optionalStr)
print(result)
//optionalStr์ด nil์ผ๋•Œ ์‹คํ–‰.


//๊ฐ„์†Œํ™” ์‹คํ–‰. nil์ผ์ˆ˜๋„, ๊ฐ’์ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๋Š” ์ƒํ™ฉ์— ??์„ ๋„ฃ์œผ๋ฉด ๋’ค์—๊ฒƒ์„ ๋ฌด์‹œํ•˜๊ณ  ์‹คํ–‰.
let anotherExpression = optionalStr ?? "This is a nil value"
print(optionalStr)
print(anotherExpression)// nill์ธ์ง€ ์•„๋‹Œ์ง€ ์ฒดํฌ ์ด๋ฏธ ํ–ˆ๊ธฐ๋•Œ๋ฌธ์— ์˜ต์…”๋„๋ฐ”์ธ๋”ฉ ํ•˜์ง€ ์•Š์Œ.


let optionalInteger: Int? = 100
let anotherExpression2 = optionalInteger ?? -1 //??=100
print(anotherExpression2)


// ์–ด๋””์— ์“ฐ์ผ ์ˆ˜ ์žˆ์„๊นŒ์š”?
// Example

let defaultColorName = "red"//๊ธฐ๋ณธ์ปฌ๋Ÿฌ์ƒ‰
var userDefinedColorName: String?//์˜ต์…”๋„ : ์œ ์ €๊ฐ€ ์ •์˜ํ•œ ์ปฌ๋Ÿฌ๊ฐ€ ์—†์œผ๋ฉด ๊ธฐ๋ณธ ์ƒ‰์ƒ์„ ์“ฐ๋„๋ก.

var colorNameToUse = userDefinedColorName ?? defaultColorName
print(colorNameToUse)

userDefinedColorName = "green"
colorNameToUse = userDefinedColorName ?? defaultColorName
print(colorNameToUse)


//0 > 2 ? a: b
//isTrue a:b

//?://์ฐธ๊ณผ ๊ฑฐ์ง“
//??//์˜ต์…”๋„์„ ๋‹ค๋ฃจ๊ธฐ์œ„ํ•œ ๊ฒƒ.

Question

  • isTrue ? a : b ์™€์˜ ์ฐจ์ด
  • optionalStr ?? "This is a nil value" ๋ฅผ 3ํ•ญ ์—ฐ์‚ฐ์ž๋กœ ๋ฐ”๊ฟ”๋ณด๊ธฐ
let answer1 = optionalStr ?? "This is a nil value"
//->3ํ•ญ์—ฐ์‚ฐ์ž๋กœ

let answer2 = optionalStr != nil ? optionalStr! : "This is a nil value"
                         //nil์ด ์žˆ๋Š”์ง€ ์•„๋‹Œ์ง€ ์ฒดํฌ
let answer3 = optionalStr == nil ? "This is a nil value" : optionalStr!

//ํŠธ๋ฃจ์ผ๋•Œ ์•ž, ํŽ„์Šค์ผ๋•Œ ๋’ค


//nil์ผ๋•Œ ~์„ ํ•˜๊ฒ ๋‹ค.

if let binding = optionalStr {
    
}

// Oprional - > nonOprional

let str1: String = "A" // nil ๋„ฃ์„ ์ˆ˜ ์—†์Œ
let str2: String! = "A" //nil์„ ๋„ฃ์„ ์ˆ˜๋Š” ์žˆ๋Š”๋ฐ ํŠน์ •๊ฐ’์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ  ์”€
type(of: str1)
type(of: str2)

Optional Chaining

let greeting: [String: String] = [
  "John": "Wassup",
  "Jane": "Morning",
  "Edward": "Yo",
  "Tom": "Howdy",
  "James": "Sup"
]

print(greeting["John"])
print(greeting["John"]?.count)//๋ฐ˜๋“œ์‹œ ?๋ฅผ ์จ์•ผํ•จ
print(greeting["NoName"]) //nil

// Optional Chaining
print(greeting["John"]?.lowercased().uppercased()) //์˜ต์…”๋„ ์•„๋‹ˆ๋ฉด nil
print(greeting["Alice"]?.lowercased().uppercased())//nil //Alice๋Š” ์—†๊ธฐ ๋–„๋ฌธ์—
//print(greeting["Alice"]!.lowercased().uppercased())// nil์ผ๋–„ !ํ•˜๋ฉด ์˜ค๋ฅ˜๋‚จ. // ๋ฐ˜๋“œ์‹œ ๊ฐ’์ด ์žˆ์„๋–„๋งŒ !๋ฅผ ์”€

// Optional Binding
if let greetingValue = greeting["John"] {
  print(greetingValue.lowercased().uppercased())
}

Question

  • ์•„๋ž˜ ๋‘ ์ข…๋ฅ˜ ์˜ต์…”๋„์˜ ์ฐจ์ด์ ์ด ๋ฌด์—‡์ผ๊นŒ์š”?
var optionalArr1: [Int]? = [1,2,3] //๋ฐฐ์—ด ์˜ต์…”๋„
var optionalArr2: [Int?] = [1,2,3] //


var arr1: [Int]? = [1,2,3] //๊ฐ’์€ ์˜ต์…”๋„์ด์•„๋‹ˆ๊ณ  ๋ฐ˜๋“œ์‹œ ์ธํŠธํƒ€์ž…. ํ•˜์ง€๋งŒ ๋ฐฐ์—ด์ž์ฒด๊ฐ€ nil์ผ์ˆ˜๋„ ์žˆ๊ณ  ๊ฐ’์ด ์žˆ์„์ˆ˜๋„ ์žˆ๊ณ ์˜ ๋œป.
//arr1.append(nil)
//arr1 = nil

print(arr1?.count)//Optional(3)
print(arr1?[1]) //Optional(2)


var arr2: [Int?] = [1,2,3] //๋ฐฐ์—ด์€ ์žˆ๋Š”๋ฐ, ๋ฐฐ์—ด ์•ˆ์— nil์ด ์žˆ์„ ์ˆ˜๋„ ์žˆ์Œ.
arr2.append(nil) //[1, 2, 3, nil]
//arr2 = nil //๋นˆ ๋ฐฐ์—ด์„ ์ง‘์–ด๋„ฃ๋Š” ๊ฒƒ์€ ๋˜๋Š”๋ฐ, nil์€ ๋„ฃ์„ ์ˆ˜ ์—†์Œ.

print(arr2.count)
//print(arr2[1])
print(arr2.last) //"Optional(nil)

Optional Function Types

//input parameter, output return type

func voidFunction() {//func voidFunction() -> () {
    print("voidFunction is called")
}

//var functionVariable: () -> () = voidFunction
var functionVariable: (() -> ())? = voidFunction //๋ณด์ด๋“œ ํŽ‘์…˜์„ ์˜ต์…”๋„์— ์ง‘์–ด ๋„ฃ์Œ.
functionVariable?()
//functionVariable = nil
//functionVariable()

functionVariable = nil
functionVariable?()
func sum(a: Int, b: Int) -> Int {
  a + b
}
sum(a: 2, b: 3)

//var sumFunction: (Int, Int) -> Int = sum(a:b:)
var sumFunction: ((Int, Int) -> Int)? = sum(a:b:) //sum์ด๋ผ๋Š” ํ•จ์ˆ˜์— a์™€ b๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๋ณ€์ˆ˜์— ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค..
type(of: sumFunction)

print(sumFunction?(1, 2))//Optional(3)
//print(sumFunction!(1, 2)) //3

//sumFunction = nil
//sumFunction?(1, 2) //nil์˜ฌ ์ˆ˜๋„ ์žˆ๊ณ  ์•ˆ์˜ฌ์ˆ˜๋„ ์žˆ๊ณ 
//sumFunction!(1, 2) //!์˜ '๋ฐ˜๋“œ์‹œ ๊ฐ’์ด ์žˆ๋‹ค' ์™€ ๋งž์ง€์•Š์•„ ์˜ค๋ฅ˜๋ฐœ์ƒ

//
var dict1: [String:String?] = [:]
 //       a : b
//?๋„ฃ์œผ๋ฉด b์— nil์“ธ์ˆ˜ ์žˆ์Œ

Question

  • 2๊ฐœ์˜ ์ •์ˆ˜๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ Modulo ์—ฐ์‚ฐ(%)์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๋˜, 2๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๊ฒฐ๊ณผ๊ฐ’์˜ ํƒ€์ž…์€ ์˜ต์…”๋„๋กœ ์ •์˜.
  • ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ ์ž…๋ ฅ๊ฐ’์œผ๋กœ nil ์ด๋‚˜ 0์ด ๋“ค์–ด์˜ค๋ฉด ๊ฒฐ๊ณผ๋กœ nil์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ ์™ธ์—๋Š” ๊ณ„์‚ฐ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
 }
// OptionalStr ?? "This is a nil value" ๋ฅผ 3ํ•ญ ์—ฐ์‚ฐ์ž๋กœ ๋ฐ”๊ฟ”๋ณด๊ธฐ
let answer = optionalStr != nil ? optionalStr! : "This is a nil value"




// 2๊ฐœ์˜ ์ •์ˆ˜๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ Modulo ์—ฐ์‚ฐ(%)์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
func calculateModulo(op1: Int, op2: Int?) -> Int? {
  guard let op2 = op2, op2 != 0/*0์ด ์•„๋‹Œ๊ฒฝ์šฐ*/ else { return nil }
  return op1 % op2
}

calculateModulo(op1: 10, op2: 4)
calculateModulo(op1: 39, op2: 5)