Swift 데이터타입, 상수, 그리고 변수

5 분 소요

데이터 타입


정수형 데이터 타입

부호있는(signed) 정수(양수, 음수, 0): Int8, Int16, Int32, Int64
부호없는(unsigned) 정수(양수, 0): UInt8, UInt16, UInt32, UInt64
입력
print("Int32 Min = \(Int32.min) Int32 Max = \(Int32.max)")
출력
Int32 Min = -2147483648 Int32 Max = 2147483647
애플은 특정 크기의 데이터 타입을 사용하기보다 Int 데이터 타입을 사용하라고 권장
print("Int Min = \(Int.min) Int Max = \(Int.max)")

부동소수점 데이터 타입

Double: 최대 64bit의 부동소수점 수 저장, 15자리까지 표현
Float: 최대 32bit의 부동소수점 수 저장, 6자리까지 표현

불리언 데이터 타입

참/거짓(또는 1과 0)을 처리하는 목적
True/False

문자 데이터 타입

Swift에서 문자는 내부적으로 그래핌 클러스터(grapheme cluster) 의 형태로 저장
그래핌 클러스터: 눈에 보이는 하나의 문자를 표현하기 위해 결합된 둘 이상의 유니코드 스칼라

  var myChar1 = "f"
  var myChar2 = ":"
  var myChar3 = "X"

유니코드의 코드 포인트를 이용

  var myChar4 = "\u{0058}" 

문자열 데이터 타입

Siwft에서 문자열은 내부적으로 문자들의 집합으로 표시
문자열 보간(string interpolation): 변수, 상수, 표현식, 함수 호출을 조합하여 구성

  var userName = "John"
  var inboxCount = 25
  let maxCount = 100

  var message = "\(userName) has \(inboxCount) messages. 
                  Message capacity remaining is \(maxCount - inboxCount) messages." 
  // 문자열 보간
  print(message)

여러 줄의 문자열은 삼중 따옴표(“”“)를 사용

  var multiline = """

      The console glowed with flashing warnings.
      Clearly time was running out.

      "I thought you said you knew how to fly this!" yelled Mary.

      "It was much easier on the simulator" replied her brother ,
      trying to keep the panic out of his voice.
      
  """

  print(multiline)//다중 문자열

특수문자/이스케이프 시퀀스

이스케이프 시퀀스(escape sequence): 개행, 탭 또는 문자열 내에 특정 유니코드 값을 지정
이스케이핑(escaping): 특수 문자들은 역슬래시 문자를 앞에 써서 구별

  • \n - 개행
  • \r - 캐리지 리턴
  • \t - 탭
  • \ - 역슬래시
  • " - 쌍따옴표
  • ' - 홀따옴표
  • \u{nn} - 한 바이트 유니코드 스칼라. nn은 유니코드 문자를 표현하는 두개의 16진수
  • \u{nnnn} - 두 바이트 유니코드 스칼라. nnnn은 유니코드 문자를 표현하는 네 개의 16진수
  • \u{nnnnnnnn} - 네 바이트 유니코드 스칼라. nnnnnnnn은 유니코드 문자를 표현하는 여덟 개의 16진수
  var newline = "\n" //개행
  var backslash = "\\" //역슬래쉬



상수와 변수

변수: var userCount = 10
상수: let maxUserCount = 20
어떤 변수가 초깃값 없이 선언되었다면, 옵셔널로 선언된 것으로 간주


타입 선언과 타입 추론

Swift는 데이터타입이 안전한(type safe) 프로그래밍 언어에 속한다.
-> 변수의 데이터 타입이 한번 정해지면 그 변수는 다른 타입의 데이터를 저장x, 컴파일 에러가 발생
데이터 타입이 느슨한(loosely typed) 프로그래밍 언어
-> 변수를 선언한 후에 다른 데이터 타입을 저장할 수 있는 언어

상수 또는 변수의 타입을 지정하는 방법

  1. 타입 선언(type annotation)
    변수나 상수 이름 뒤에 콜론을 쓰고 타입을 선언
      var userCount: Int =10
    

    타입 선언 없이 상수를 선언하게 될 경우 반드시 선언 시점에서 값을 할당

      let bookTitle = "SwiftUI Essentials"
    

    타입 선언을 사용하면 나중에 초기자(initializer)에서 할당할 수 있다.

      let bookTitle1: String
      if iosBookType {
      bookTitle1 = "SwiftUI Essentials"
      } else {
      bookTitle1 = "Android Studio Development Essentials"
      }
    
  2. 타입 추론(type inference)
    선언부에서 타입 선언이 없다면 컴파일러가 변수 또는 상수가 초기화되는 시점에
    할당된 값의 타입이 무엇인지를 판단하여 해당 타입으로 지정
     var signalStrength = 2.231 //Double(default)
     let companyName = "My Company" //String
    

튜플

여러 값을 하나의 항목으로 임시적으로 그루핑
서로 다른 값들이 튜플에 저장될 수 있으며, 모두 동일한 타입의 값이어야 한다는 제약x

 let myTuple = (10, 432.433, "This is a String")

튜플에 저장된 값을 얻는 방법

  • 인덱스 위치를 참조
     let myTuple = (10, 432.433, "This is a String")
     let myString = myTuple.2
     print(myString)
    
  • 하나의 구문으로 모든 값을 추출
     let (myInt, myDouble, myString) = myTuple
    
    • 선택적으로 추출
      var (myInt, _, myString) = myTuple // 밑줄 무시
      
  • 튜플을 생성할 시점에서 각각의 값을 변수에 할당
      let myTuple2 = (count: 10, length: 432.433, message: "This is a String")
      print(myTuple2.message) //"This is a String"
      print(myTuple2.2) //"This is a String"
    

옵셔널 타입

변수 또는 상수에 값이 할당되지 않은 상황(nil)을 처리하기 위해 안전하고 일관된 접근 방식을 제공

 var index: Int?

할당된 값이 있는지를 식별하기 위한 테스트

 if index != nil {
     //index 변수는 값이 할당되어 있다
 } else {
     //index 변수는 값이 할당되어 있지 않다
 }

옵셔널에 값이 할당되었다면 해당 값이 옵셔널 내에서 래핑되었다(wrapped) 고 말한다
옵셔널 안에 래핑된 값 사용방법

  • 강제 언래핑(forced unwrapping)
    var index: Int?
    
    index = 3
    
    var treeArray = ["Oak", "Pine", "Yew", "Birch"]
    
    if index != nil {
        print(treeArray[index!]) //느낌표(!)를 붙여 강제 언래핑
    } else {
        print("index does not contain a value")
    }
    
  • 옵셔널 바인딩(optional binding)
    1) 지정된 옵셔널이 값을 가지고 있는지를 확인
    2) 옵셔널 변수가 값을 가지고 있는 경우에 선언된 상수 또는 변수에 그 값을 할당
    var index: Int?
    
    index = 3
    
    var treeArray = ["Oak", "Pine", "Yew", "Birch"]
    
    if let myValue = index { //myValue 상수는 if 구문 안에서만 유효한 상수
        print(treeArray[myValue])
    } else {
        print("index does not contain a value")
    }
    
    • 한 줄의 코드 내에서 두 개의 옵셔널을 언래핑
       var pet1: String?
       var pet2: String?
      
       pet1 = "cat"
       pet2 = "dog"
      
       if let firstPet = pet1, let secondPet = pet2 {
           print(firstPet)
           print(secondPet)
       } else {
           print("insufficient pets")
       }
      
    • 조건문 사용
      if let firstPet = pet1, let secondPet = pet2, petCount > 1 {
          print(firstPet)
          print(secondPet)
      } else {
          print("insufficient pets")
      }
      

옵셔널 선언시 강제적 언래핑
강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근

 var index: Int! //물음표(?) 대신에 느낌표(!)를 사용
 
 index = 3

 var treeArray = ["Oak", "Pine", "Yew", "Birch"]

 if index != nil {
     print(treeArray[index])
 } else {
     print("index does not contain a value")
 }

옵셔널이 아닌 변수 또는 상수에는 nil을 할당할 수 없다.

 var myInt = nil // 유효하지 않은 코드
 var myString: String = nil // 유효하지 않은 코드
 let myConstant = nil // 유효하지 않은 코드

타입 캐스팅과 타입 검사

스위프트 코드를 작성할 때 메서드나 함수가 반환하는 값이 불명확하거나 예상되지 않은 타입의 값일 때
컴파일러가 어떤 값의 특정 타입을 식별하지 못하는 경우가 발생
-> 의도하는 값의 타입을 컴파일러가 알 수 있도록 함: 타입 캐스팅(type casting, 형 변환)

 let myValue = record.object(for: "coment") as! String
  • 업캐스팅(upcasting)
    특정 클래스의 객체가 상위 클래스들 중의 하나로 변형되는 것
    as 키워드를 사용하여 수행
    이러한 변환은 성공할 것이라고 컴파일러가 알려 줄 수 있기 때문에 보장된 변환(guaranteed conversion) 이라 칭함
      let myButton: UIButton = UIButton()
      let myControl = myButton as UIControl
    
  • 다운캐스팅(downcasting)
    어떤 클래스에서 그 클래스의 하위 클래스로 변환하게 되는 것
    as! 키워드를 사용하여 수행
    이러한 변환이 안전하게 수행된다거나 유효하지 않은 변환 시도를 컴파일러가 잡아낼 것이라는 보장을 할 수 없다: 강제 변환(forced conversion)
    유효하지 않은 변환을 시도한 경우 컴파일러가 발견하지 못한다면, 대부분의 경우 런타임 에러가 발생(주의!)
      let myScrollView: UIScrollView = UIScrollView()
      let myTextView = myScrollView as! UITextView 
      //UIScrollView를 UITextView로 변환x -> 실행 중 충돌발생
    
    • 안전한 방법 - as? 사용
      변환이 성공적으로 수행할 경우 = 지정한 타입의 옵셔널 값이 반환
      변환에 오류가 발생할 경우 = 옵셔널 값은 nil을 반환
        if let myTextView = myScrollView as? UITextView { // 옵셔널값이기에 옵셔널 바인딩
            print("Type cast to UITextView succeeded")
        } else {
            print("Type cast to UITextView failed")
        }
      

is 키워드를 사용한 타입 검사(type check)

  if myobject is MyClass {
      // myobject는 MyClass의 인스턴스다
  }