Swift

Swift | The Basic (기본)

iOSDEv 2023. 12. 10. 15:17
상수와 변수 선언

 

1. 상수와 변수의 정의

  • 상수(let)
    • 상수의 값은 최초 지정 후 변경이 불가능
  • 변수(var)
    • 변수의 경우 다른 값으로 변경이 가능
//상수 선언 후 값을 변경할 수 없다
let maximuimNumberOfLoginAttemps = 10
//만약 이런식으로 변경할 시  오류가 남
//maximuimNumberOfLoginAttemps = 20

//변수는 선언 후 값을 변경할 수 있다
var currentLoginAttempt = 0

 

2. 상수와 변수를 선언할 때 콤마로 구분하여 한 줄로 선언이 가능

//반드시 초기에 초기화를 해야함
//초기화를 하지 않을시 오류남
//만약 타입 명시를 할 시, 초기화를 하지 않아도됨
//but 초기화 하지 않은 값을 호출할 시 오류가 나게됨

var number3 = 0 , number4 = 0, number5 = 0

let number6 = 0, number7 = 0, number9 = 0

 

  ⚠️  코드에서 저장한 값이 변경되지 않는다면 항상 let 키워드를 선언

 

타입명시
  1. 타입 명시 사용 이유 및 특징
    • 상수 또는 변수를 선언할 때 저장할 수 있는 값의 종류를 명확하게 하기 위해 타입 명시를 제공
    • 같은 타입에 여러개의 연관된 변수를 콤마로 변수 이름을 구분하고 마지막에 타입 명시를 통해 한줄 선언
    var number: Int
    
    var number10: Int = 10
    
    var message: String
    
    var message1 = "hello"
    
    //연관된 변수를 콤마로 이름을 구분하고 마지막에 타입 명시로 통해 한 줄 선언이 가능한 예
    var red, gree, purple, black: String
    
    red = "red"
    
    💡 실제로 타입 명시가 필요한 경우는 드뭅 변수를 선언할 때 초기값을 지정하면 타입추론 가능

 

상수와 변수의 이름

  1. 특정 타입으로 상수 또는 변수 선언하면 동일한 이름으로 다시 선언하거나 다른 타입의 값을 저장하도록 변경하여 선언할 수 없음.
    1. 상수→ 변수 ❌
    2. 변수→ 상수 ❌
  2. 동일한 타입의 다른 값으로 이미 선언된 변수의 값을 변경할 수 있음
  3. 변수와 달리 상수 값은 지정된 이후에는 변경할 수 없음
//변수의 경우 값의 변경이 가능함 
var message: String

message = "hello"

message = "bye"

//상수의 경우 값의 변경이 불가능함 
//만약 변경하려고 하면 코드가 컴파일 때 오류가 발생함

let red = "red"

//this is compile error
red = "realRed"
  1. 상수와 변수 이름은 유니코드 문자를 포함하여 대부분의 문자를 포함할 수 있다
    1. 안되는 경우 : 공백, 수학적 기호, 화살표, 내부에서 사용하는 유니코드 스칼라값, 선과 박스 그리는 문자
    let n = 3.14159
    
    let 你好 = "你好世界"
    
    let 🐶🐮 = "dogcow"

상수와 변수 출력

  1. print 함수로 상수 또는 변수의 현재 값을 출력할 수 있음
⚡ print(:seperator:terminator:)

 

print(message)
💡 만약 줄바꿈없이 값을 출력하려면 ❓
⇒ print(someValue, terminator: "")
긴 문자열에 상수 또는 변수 이름을 포함하여 문자열 삽입 방법
print(”\(red) is beautiful color”)

주석

 

//한줄 주석

/*

여러줄 주석

*/

세미콜론

  • swift에서 세미콜론(;)은 필수조건이 아님
  • 여러 구문을 한줄로 작성할 경우 세미콜론은 필수로 작성되어야함
let cat = "mow"

print(cat)

정수 Int

  1. 정수의 뜻
    1. 분수가 아닌 전체 숫자
    2. signed ⇒ 부호가 있는 정수(양수, 0, 음수)
    3. unsigned ⇒ 부호가 없는 정수 (양수 ,음수)
  2. 정수 범위
    1. min, max property를 통해 각 정수의 최소값과 최대값을 가질 수 있음
    let minValue = Int.min   // -9,223,372,036,854,775,808
    
    let maxValue = Int.max   // 9,223,372,036,854,775,807
    
    let minUValue = UInt8.min    //0
    
    let maxUValue = UInt8.max    //255
    
    let maxInt64bit = Int64.max    //9,223,372,036,854,775,807
    
    let maxInt32bit = Int32.max    // 2,147,483,647
    
  3. Int
    1. 32-bit 플랫폼 : Int32
    2. 64-bit 플랫폼 : Int64
💡 32-bit 플랫폼에서도 Int 는 -2,147,483,648 과 2,147,483,647 사이의 값을 저장할 수 있으며 일반적인 사용성에 문제가 없습니다.

 

  1. UInt
    1. 64-bit 플랫폼 : UInt64
    2. 32-bit 플랫폼 : UInt32

부동 소수점 숫자

  • 분수 성분을 가진 숫자
    • Double → 64-bit 부동 소수점 숫자 표기
    • Float → 32-bit 부동 소수점 숫자를 표기
💡 Double 15자리 소수점 정확도 Float 6자리 소수점 정확도

 

타입 세이프티와 타입 추론

var piNum = 0.14159

// 정수 + Double 
let anotherPi = 3 + 0.14159 //Double 형으로 알아서 인식함

숫자 리터럴

let decimalInteger = 17

let binaryInteger = 0b10001       // 17 in binary notation(2진수)

let octalInteger = 0o21           // 17 in octal notation(8진수)

let hexadecimalInteger = 0x11     // 17 in hexadecimal notation(16진수)

숫자타입변환

  • 명시적으로 크기가 지정된 데이터 또는 성능, 메모리 사용, 또는 다른 성능 최적화를 위한 경우에만 다른 정수 타입을 사용함
    • 명시적으로 크기의 타입을 사용하면 실수로 인한 값 초과를 포착하고 사용중인 데이터의 특성을 알 수 있음
  • 정수변환
    1. Int8 : -128 과 127 사이의 숫자를 지정할 수 있음
    2. UInt8 0 과 255 사이의 숫자를 저장할 수 있음
//크기가 지정된 정수 타입의 상수 또는 변수에 맞지않는 숫자 작성
//컴파일 시에 오류 발생

let cannotBeNegative: UInt8 = -1
// UInt8 cannot store negative numbers, and so this will report an error
let tooBig: Int8 = Int8.max + 1
// Int8 cannot store a number larger than its maximum value,
// and so this will also report an error

//데이터 타입이 다른 값을 더하려면?
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
  • 정수와 부동 소수점 변환
    1. 명시적으로 변환해야함
//three = Doulbe type으로 명시적 변환을 해야 소수점 상수와 덧셈이 가능함
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi equals 3.14159, and is inferred to be of type Double

//만약 Double형인 pointOneFourOneFiveNine를 Int형으로 변환하고 싶다면?
Int(pointOneFourOneFiveNine) //print = 0으로 나옴

타입별칭(Type Aliases)

💡 이미 존재하는 타입을 다른 이름으로 정의하고 키워드를 사용하여 정의할 수 있습니다

 


typealias AudioSample = UInt16

부울(Booleans)     

  • 참 거짓을 제공함
  • let orangesAreOrange = true let turnipsAreDelicious = false var isTure = true isTrue = false
  • if 구문과 같은 조건문으로 동작할 때 특히 유용
  • if turnipsAreDelicious { print("Mmm, tasty turnips!") } else { print("Eww, turnips are horrible.") } // Prints "Eww, turnips are horrible."
  • 비교 결과는 Bool type
//예제1
//비교하는 대상이 없기에 컴파일시 에러를 발생함 
let i = 1
if i {
}

//예제2
//비교하는 대상이 있을 시 에러를 발생하지 않음
if i == 1{}
if i != 1{}

튜플(Tuples)

 

여러값을 단일 복합 값으로 그룹화 합니다. 튜플안에 값은 어떠한 타입도 가능하며 서로 같은 타입일 필요는 없다.

  • 튜플의 내용을 별도의 상수 또는 변수로 분해하여 평소와 같이 접근이 가능
  • 튜플의 값 중 일부만 필요한 경우 튜플을 분해할 때 밑줄(_)로 튜플의 일부를 무시가능
  • 배열처럼 튜플의 개별 요소 값에 접근할 수 있음
  • 튜플을 정의할 때 각 요소마다 이름을 정의할 수 있음
  • 튜플 요소에 이름이 있다면 요소의 값에 요소 이름으로 접근이 가능
//튜플
var name : String = "name"
var adress : String = "adress"
var phoneNumber = 96710056
let http404Error = (404, "Not Found")
let loginSuccess = ("loginSuccess", name, adress, phoneNumber)

//변수로 분해하여 평소와 같이 접근이 가능함
let (statusCode, statusMessage) = http404Error

print("the status code is \\(statusCode)")
print("the status message is \\(statusMessage)")

//튜플의 값 중 일부만 필요한 경우 튜플을 분해할 때 밑줄로 튜플의 일부를 무시할 수 있음
let (justNeedStatusCodee, _) = http404Error
print("status code is \\(justNeedStatusCodee)") //404

//인덱스로 접근 가능
http404Error.0
http404Error.1

let http200Status = (statusCode: 200, description: "OK")
http200Status.statusCode
http200Status.description
💡 튜플은 관련된 값의 간단한 그룹에 유용 복잡한 데이터 구조를 생성하는데 맞지 않음 데이터 구조가 복잡한 경우 클래스나 구조체를 사용

 

옵셔널(Optionals)

 

값이 없는 경우에 옵셔널을 사용하는데 옵셔널은 2가지 기능성이 있다

  • 지정된 타입의 값이 있고 옵셔널을 풀어서 값에 접근
  • 값이 없을 수 도 있다(nil)
  • nil의 정의
    • Objective-C 객체가 존재하지 않는 포인터
    • Swift 포인터가 아님 그저 특정 타입의 값이 없다는 의미
let possibleNumber = "123"

//Int가 옵셔널로 정의됨
//현재 possibleNumber가 초기화 실패할 수도 있기 때문에 옵셔널 타입으로 들어가게됨
let convertedNumber = Int(possibleNumber)
// The type of convertedNumber is "optional Int"
nil
  • 값이 없는 상태를 나타낼 수 있습니다
var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404

serverResponseCode = nil
// serverResponseCode now contains no value

//기본값이 없이 정의만 하게될 때 자동적으로 nil로 설정
var survayAnswer: String?
  • if 구문은 옵셔널 nil을 비교하여 옵셔널 값이 포함되어있는지 확인 가능
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)

if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
}
// Prints "convertedNumber contains some integer value."

 

💡 옵셔널이 아닌 상수 / 변수 에서는 nil을 사용할 수 없음 코드에서 상수 또는 변수가 특정 조건에서 값이 없이 동작하려면
      적절한 타입의 옵셔널 값을 선언해야함 옵셔널이 아닌 값에 nil을 할당하면 컴파일 오류가 발생

 

  • 값이 없을 때(nil) 수행할 수 있는 작업
    • ! 연산자를 사용해서 프로그램을 멈춤
    • ?? 연산자를 사용해 대체값을 제공
    • nil을 반환하거나 옵셔널 체이닝에서 설명한 ?. 연산자를 사용하여 nil값을 전파
    • 값이 nil일 때 해당값에 대한 동작을 건너뜀

옵셔널 바인딩 (Optional Binding)

 

옵셔널 값을 포함하고 있는지 확인하고 값이 있는 경우 해당 값을 임시 상수 또는 변수로 사용할 수 있게 해줌

옵셔널 바인딩은 if, guard, while 구문에서 옵셔널에 값이 있는지 체크하고 단일 동작의 일부로 상수 또는 변수로 추출할 수 있음

  • if구문에서 옵셔널 바인딩
if let <#constantName#> = <#someOptional#> {
   <#statements#>
}

let possibleNumber = "123"

//optional type 
//값에 접근한 후에 기존 옵셔널 상수 또는 변수를 참조할 필요가 없다면 같은 이름으로 새로운 상수 또는 변수를 사용가능

if let actualNum = Int(possibleNumber) {
	print("possibleNumber : \\(possibleNumber)")
} else {
	print("possibleNumber could not be converted to an integer : \\(possibleNumber)")
}

//mynumber 값의 유무부터 확인 
//만약 값이 있다면 myNumber라는 상수에 설정
//if 구문 안에서 myNumber은 옵셔널이 아닌 상수를 참조
let myNumber = Int(possibleNumber)

//언래핑 하는데 더 짧게 사용 가능
//언래핑할 상수 또는 변수의 이름만 작성
//언래핑된 새로운 상수 또는 변수는 암시적으로 같은 이름의 옵셔널 값을 사용
if let myNumber = myNumber {
	print("my number is \\(myNumber)")
}

if let myNumber {
	print("My number is \\(myNumber)")
}

//if 구문에서 옵셔널 바인딩으로 생서된 상수와 변수는 if구문의 본문내에서만 사용 가능
//, 를 통해서도 사용이 가능함
if let firstNumber = Int("4"), let secondNumber = Int("42"), 
fistNumber < secondNumber && secondNumber < 100 {
	print("\\(firstNumber) < \\(secondNumber) < 100 ")
}

//4 < 42 < 100

if let firstNumber = Int("4") {
	if let secondNumber = Int("42") {
		if firstNumber < secondNumber && secondNumber < 100 {
			print("\\(firstNumber) < \\(secondNumber) < 100 ")
		}
	}
}

//4 < 42 < 100

대체값 제공(Providing a Fallback Value)

 

누락된 값을 처리하는 다른 방법은 nil-결합연산자 (??) 사용하여 기본값을 제공하는 방법

옵셔널에서 ??의 왼편이 nil이 아니면 값이 언래핑되고 사용 그렇지 않으면 ?? 오른편에 값이 사용

//대체값 사용
//??
//옵셔널에 ??의 왼편이 nil이 아니면 값이 언래핑되고 사용
//그렇지 않으면 ?? 오른편에 값이 사용
let name: String? = nil
let greeting = "hello" + (name ?? "friend") + "!"
print(greeting) //"hello, friend"

강제 언래핑(Force Unwrapping)

 

  • 프로그래머의 에러 또는 원치않는 상태와 같은 실패를 nil로 표현하려면 옵셔널의 이름 뒤에 !추가
  • nil값을 강제 언래핑하면 런타임 에러가 발생하기 때문에 잘 사용해야함
//강제 언래핑
//!
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)

let number = convertedNumber!

guard let number = convertedNumber else {
	fatalError("the number was invalid")
}

암시적으로 언래핑된 옵셔널(Implicity Unwrapped Optionals)

//암시적으로 언래핑된 옵셔널
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // Requires explicit unwrapping

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // Unwrapped automatically

let optionalString = assumedString
// The type of optionalString is "String?" and assumedString isn't force-unwrapped.

//"An implicitly unwrapped optional string."
if assumedString != nul {
		print(assumedStinrg!)
}

//"An implicitly unwrapped optional string."
if let definiteString = assumedStinrg {
	print(definiteString)
}

에러 처리

  • 값의 유무를 사용하여 함수의 성공 또는 실패를 전달할 수 있는 옵셔널과 달리 에러 처리를 사용하면 에러 원인을 판별하고 필요한 경우 에러를 프로그램의 다른 부분으로 전달할 수 있음
  • 함수에 에러조건이 되면 에러 발생하고 해당 함수의 호출자는 에러를 포착하고 적절하게 응답 가능

 

출처 : https://bbiguduk.gitbook.io/swift/language-guide-1/the-basics