티스토리 뷰

iOS/Swift-Documents

swift5.5 공식문서 The Basics -1

malrang-malrang 2022. 1. 21. 23:57

표현이 이상하거나 잘못번역된 부분이 있을수 있습니다. 

혹 누군가 읽다 잘못된 부분이 있으면 댓글로 알려주세요! 

The Basics

Swift는 iOS, macOS, watchOS 및 tvOS 앱 개발을 위한 새로운 프로그래밍 언어입니다. Swift는 정수Int, 부동소수Double, Float, 참,거짓 Bool ,문자 Character, String 의 기초 자료형 을 제공하며 Array, Set 및 Dictionary의 컬렉션 타입을 제공합니다. swift는 값을 저장하기위해 변수(var)와 상수(let)를 사용하고 이름을지어 구분합니다. swift의 상수는 Objective-C의 상수보다 더많은 기능을 수행할수 있습니다. 상수는 변경할 필요가 없는 값으로 코드를 더 안전하고 명확하게 만들기위해 swift 전체에서 사용됩니다. Objective-C에서는 없던 튜플(Tuples)형식도 제공합니다. 튜플을 사용하면 여러개의 값을 하나의 값으로 반환할수 있습니다. Swift는 값이 있는지 없는지 나타낼수있는 Optional 을 제공합니다. 만약 값이 없을경우 제어할수있게 해주며, 값이 없을경우 nil 로 표현합니다. 이는 Class 뿐만 아니라 모든 유형에서 사용할수 있습니다.  Objective-C의 nil 포인터보다 옵셔널이 더 안전하고 표현력이 높을 뿐만 아니라 Swift 기능의 핵심입니다.

Swift는 안전을 지향하는 언어입니다. 사용자가 잘못된 자료형을 사용할경우 경고를 주어 알려줍니다. 유형 안전성은 개발 프로세스에서 가능한 한 빨리 오류를 포착하고 수정하는 데 도움이 됩니다.

 

Constants and Variables (상수와 변수)

상수(let), 변수(var) 에 특정 유형의값과 연결하여 사용합니다.(예: 숫자 10 또는 "Hello" 문자열)

상수의 값은 한 번 설정되면 변경할 수 없지만 변수는 나중에 다른 값으로 설정할 수 있습니다.

 

Declaring Constants and Variables (상수와 변수의 선언)

상수와 변수는 사용하기 전에 선언해야 합니다. let 키워드로 상수를 선언하고 var 키워드로 변수를 선언합니다.

다음은 사용자의 로그인 시도 횟수를 측정하기 위해 상수와 변수를 사용하는 방법의 예시 입니다.

예시) 선언과 동시에 값을 연결해준 모습

let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0

다음과 같이 읽을수 있습니다.

"maximumNumberOfLoginAttempts(최대 로그인 횟수)라는 새 상수를 선언하고 값을 10으로 지정합니다. 그런 다음 currentLoginAttempt(로그인 실패 횟수)라는 새 변수를 선언하고 초기 값을 0으로 지정합니다."  

maximumNumberOfLoginAttempts(최대 로그인 횟수) 최대 로그인 시도 횟수를 변경 할수 없도록 상수(let)로 선언 합니다.

currentLoginAttempt(로그인 실패 횟수) 는 로그인 시도가 실패할 때마다 값이증가해야 하기 때문에  변수로 선언됩니다.

 

쉼표로 구분하여 한 줄에 여러 상수 또는 여러 변수를 선언할 수 있습니다.

var x = 0.0, y = 0.0, z = 0.0

 

NOTE
코드에 저장된 값이 변경되지 않으면 항상 let 키워드를 사용하여 상수로 선언하십시오. 
변경할 수 있어야 하는 값을 저장하는 경우에만 변수를 사용하십시오.

Type Annotations  

상수 또는 변수를 선언할 때 유형 주석을 제공하여 상수 또는 변수가 저장할 수 있는 값의 종류를 명확히 할 수 있습니다.

상수 또는 변수 이름 뒤에 콜론, 공백, 사용할 유형 이름을 차례로 배치하여 유형 주석을 작성합니다.

이 예에서는 변수가 문자열 값을 저장할 수 있음을 나타내기 위해 welcomeMessage라는 변수에 대한 유형 주석을 제공합니다.

var welcomeMessage: String

선언의 콜론은 유형 을 의미하므로 위의 코드는 다음과 같이 읽을 수 있습니다.

String 유형의 welcomeMessage라는 변수를 선언합니다.

 

welcomeMessage 변수는 이제 오류 없이 모든 문자열 값으로 설정할 수 있습니다.

welcomeMessage = "Hello"

최종 변수 이름 뒤에 단일 유형 주석을 사용하여 동일한 타입유형의 변수를 여러게 한번에 정의할 수 있습니다.

var red, green, blue: Double
Note
실제로 유형 주석을 작성해야 하는 경우는 드뭅니다. 정의된 시점에서 상수나 변수에 대한 초기값을 제공하면,
유형 안전 및 유형 유추에 설명된 대로 Swift는 초기값을 보고 상수 또는 변수에 사용할 유형을 자동적으로
유추할 수 있습니다. 
위의 welcomeMessage 예시에서는 초기값을 제공하지 않았으므로 welcomeMessage 변수의 타입은 
초기값에서 유추되지 않고 타입 어노테이션으로 지정됩니다.

 

Naming Constants and Variables (상수와 변수에 이름 짓기)

상수 및 변수 이름에는 유니코드 문자를 포함하여 거의 모든 문자가 포함될 수 있습니다.

let π = 3.14159
let 你好 = "你好世界"
let 🐶🐮 = "dogcow"

상수 및 변수 이름에는 공백 문자, 수학 기호, 화살표, 전용 유니코드 스칼라 값을 사용할 수 없습니다.

상수와 변수의 이름의 첫번째는 숫자로 시작할수 없습니다. 이름의 처음이 아니면 다른곳에는 들어갈수 있습니다.

특정 유형의 상수 또는 변수를 선언한 후에는 동일한 이름으로 다시 선언하거나 다른 유형의 값을 저장하도록 변경할 수 없습니다. 또한 상수를 변수로, 변수를 상수로 변경할 수 없습니다.

Note
상수나 변수에 예약된 Swift 키워드와 동일한 이름을 지정해야 하는 경우 이름으로 사용할 때 키워드를 
역따옴표(`)로 묶습니다.
그러나 선택의 여지가 없는 경우가 아니면 키워드를 이름으로 사용하지 마십시오.

예시) 변수의 이름을 class 로 지정할경우 Swift에 존재하는 키워드이기 때문에 사용불가능하며
사용하기위해서는 `class` 라고 이름을 붙여 사용한다

기존 변수의 값을 호환 가능한 유형의 다른 값으로 변경할 수 있습니다.

이 예에서 friendlyWelcome의 값은 "Hello!"에서 변경됩니다. "Bonjour!"로:

var friendlyWelcome = "Hello!"
friendlyWelcome = "Bonjour!"
// friendlyWelcome is now "Bonjour!"

변수와 달리 상수의 값은 설정 후에 변경할 수 없습니다.

그렇게 하려고 하면 코드가 컴파일될 때 오류로 알려줍니다.

let languageName = "Swift"
languageName = "Swift++"
// This is a compile-time error: languageName cannot be changed.

 

Printing Constants and Variables (상수와 변수 출력)

print(_:separator:terminator:) 함수를 사용하여 상수 또는 변수의 현재 값을 출력 할 수 있습니다.

위의 예시에서 friendlyWelcome 의 현재 값은 "Bonjour!"

print(friendlyWelcome)
// Prints "Bonjour!"

print 함수는 하나 이상의 값을 적절한 출력으로 인쇄하는 전역 함수입니다.

예를 들어 Xcode에서 print 함수는 print함수 내부에있는 값을 Xcode의 "콘솔" 창에 값을 출력 합니다.

 separator(구분자) 및 terminator(종결자) 는 기본값이 있으므로 이 함수를 호출할 때 생략할 수 있습니다. 

 

Swift는 상수 또는 변수의 이름에 문자열 보간법을 사용할수있습니다. 

보간법 사용방법은 이름을 괄호로 묶고 여는 괄호 앞에 백슬래시를 작성합니다.

print("The current value of friendlyWelcome is \(friendlyWelcome)")
// Prints "The current value of friendlyWelcome is Bonjour!"

 

Comments (주석)

주석을 사용하여 코드에 실행할 수 없는 텍스트를 메모 또는 알림으로 포함할 수 있습니다. 

Swift의 주석은 C의 주석과 매우 유사합니다. 한 줄 주석은 두 개의 슬래시(//)로 시작합니다.

// This is a comment.

여러 줄 주석은 슬래시와 별표(/*)로 시작하고 별표와 슬래시(*/)로 끝납니다.

/* This is also a comment
but is written over multiple lines. */

Swift는 주석안에 주석이 중첩될수 있습니다.

/* This is the start of the first multiline comment.
 /* This is the second, nested multiline comment. */
This is the end of the first multiline comment. */

 

Semicolons (;)

다른 많은 언어와 달리 Swift는 코드의 각 명령문 뒤에 세미콜론(;)을 사용하지 않아도됩니다.

하지만 원하는 경우 그렇게 할 수 있습니다.  한 줄에 여러 개의 별도 명령문을 작성하려면 세미콜론이 필요합니다.

 

let cat = "🐱"; print(cat)
// Prints "🐱"

Integers (정수)

정수는 42 및 -23과 같이 분수 구성요소가 없는 정수입니다. 양수, 0 또는 음수 가 포함됩니다. 8, 16, 32, 64비트 형식의 부호 있는 정수와 부호 없는 정수를 제공합니다. 이 정수는 C와 유사한 명명 규칙을 따릅니다. 8비트 부호(-) 없는 정수는 UInt8 유형이고 32비트 부호 있는 정수는 Int32 유형입니다. Swift의 모든 유형과 마찬가지로 유형은 이름이 대문자로 시작합니다.

 

Integer Bounds (정수의 최대값)

min 및 max 프로퍼티를 사용하여 각 정수 유형의 최소값 및 최대값에 접근 할 수 있습니다.

let minValue = UInt8.min  // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max  // maxValue is equal to 255, and is of type UInt8

이러한 속성의 값은 적절한 크기의 숫자 유형(예: 위 예제의 UInt8)이므로 동일한 유형의 다른 값과 함께 표현식에서 사용할 수 있습니다.

 

Int (정수)

대부분의 경우 코드에서 사용할 특정 크기의 정수를 선택할 필요가 없습니다.

Swift는 현재 플랫폼의 기본 단어 크기와 동일한 크기를 갖는 추가 정수 유형 Int를 제공합니다.

  • 32비트 플랫폼에서 Int는 Int32와 크기가 같습니다.
  • 64비트 플랫폼에서 Int는 Int64와 크기가 같습니다.

32비트 플랫폼에서도 Int는 -2,147,483,648에서 2,147,483,647 사이의 모든 값을 저장할 수 있으므로 사용할수있는 값이 매우 크기때문에 굳이 다른 유형의Int 를사용하지 않아도 기본Int 만 사용해도된다.

 

UInt (부호가 없는 정수)

Swift는 Int와 마찬가지로 현재 플랫폼의 기본 단어 크기와 동일한 크기를 가진 unsigned integer type, UInt를 제공합니다.

 

Floating-Point Numbers  (부동 소수점)

부동 소수점 숫자는 3.14159, 0.1 및 -273.15와 같이 소수점 구성 요소가 있는 숫자입니다.

부동 소수점 유형은 정수 유형보다 훨씬 더 넓은 범위의 값을 나타낼 수 있으며 Int에 저장할 수 있는 것보다 훨씬 크거나 작은 숫자를 저장할 수 있습니다. Swift는 두 가지 부호 있는 부동 소수점 숫자 유형을 제공합니다.

  • Double은 64비트 부동 소수점 숫자를 나타냅니다.
  • Float은 32비트 부동 소수점 숫자를 나타냅니다.
NOTE
Double의 정밀도는 최소 15자리 소수점 이하 자릿수인 반면 Float의 정밀도는 소수점 이하 6자리까지 가능합니다.
두 유형 중 하나가 적절한 상황에서는 Double이 선호됩니다.

 

Type Safety and Type Inference (유형 안전성 및 유형 추론)

Swift는 안전한 을 지향하는 언어입니다. Swift는 코드에서 사용할 수 있는 값 Type을 명확하게 하도록 권장합니다. 코드의 일부에 String이 필요한 경우 실수로 Int를 전달할 수 없습니다.

코드를 컴파일할 때  Type-Checking을 수행하고 일치하지 않는 Type을 오류로 지정합니다. 이를 통해 개발 프로세스에서 빨리 오류를 포착하고 수정할 수 있게 해줍니다.

Type-Checking는 다른 유형의 값으로 작업할 때 오류를 방지하는 데 도움이 됩니다. 그러나 이것이 선언하는 모든 상수와 변수의 유형을 지정해야 한다는 의미는 아닙니다. 필요한 값의 Type을 지정하지 않으면 Swift는 type-inference(유형 추론)을 사용하여 적절한 유형을 찾습니다. type-inference는 초기 값이 있는 상수 또는 변수를 선언할 때 특히 유용합니다. 

swift는 C와 Objective-C와는 다르게 자료형 선언이 필수적이지 않습니다. 하지만 상수, 변수 선언을 위한 let, var는 꼭 써줘야 합니다.

 

어떤 유형인지 말하지 않고 상수에 값 42를 할당하면 Swift는 정수처럼 보이는 숫자로 초기화했기 때문에 상수가 Int가 되기를 원한다고 추론하여 타입유형은 Int 로 정의 됩니다.

let meaningOfLife = 42
// meaningOfLife is inferred to be of type Int

마찬가지로, 부동 소수점 값 에 대한 유형을 지정하지 않으면 Swift는 Double을 생성하기를 원한다고 추론합니다.

let pi = 3.14159
// pi is inferred to be of type Double

Swift는 부동 소수점 숫자 유형을 추론할 때 항상 Double(Float 대신)을 선택합니다.

 

표현식에서 정수와 부동 소수점 값을 더하면 Double 유형이 추론 됩니다.

let anotherPi = 3 + 0.14159
// anotherPi is also inferred to be of type Double

3에는 명시적인 유형이 없고 뒤에 나오는 0.14159에 부동 소수점 숫자가 존재하므로 Double로 추론합니다.

Numeric Literals (무슨소린지 아직은 모르겠다..추후에 다시보자)

대강..값을 표현할때 문자를 사용하여 표기하는 방법인듯하다.

 

정수 리터럴은 다음과 같이 작성할 수 있습니다.

  • 접두사가 없는 10진수
  • 접두사가 0b인 이진수
  • 접두사가 0o인 8진수 0x
  • 접두사가 있는 16진수

이러한 모든 정수 리터럴은 10진수 값이 17입니다.

let decimalInteger = 17
let binaryInteger = 0b10001       // 17 in binary notation
let octalInteger = 0o21           // 17 in octal notation
let hexadecimalInteger = 0x11     // 17 in hexadecimal notation

부동 소수점 리터럴은 10진수(접두사 없음) 또는 16진수(접두사 0x 포함)일 수 있습니다. 소수점 양쪽에 항상 숫자(또는 16진수)가 있어야 합니다. 소수 부동 소수점은 대문자 또는 소문자 e로 표시되는 선택적 지수를 가질 수도 있습니다. 16진수 부동 소수점은 지수가 있어야 하며 대문자 또는 소문자 p로 표시됩니다.

지수가 exp인 십진수의 경우 기본 수에 10exp를 곱합니다.

  • 1.25e2는 1.25 x 102 또는 125.0을 의미합니다.
  • 1.25e-2는 1.25 x 10-2 또는 0.0125를 의미합니다.

지수가 exp인 16진수의 경우 기본 수에 2exp를 곱합니다.

  • 0xFp2는 15 x 22 또는 60.0을 의미합니다.
  • 0xFp-2는 15 x 2-2 또는 3.75를 의미합니다.

이러한 모든 부동 소수점 리터럴의 10진수 값은 12.1875입니다.

let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0

숫자 리터럴에는 읽기 쉽도록 추가 서식이 포함될 수 있습니다. 정수와 부동 소수점은 모두 0으로 채워질 수 있으며 가독성을 돕기 위해 밑줄을 포함할 수 있습니다. 두 형식 모두 리터럴의 기본 값에 영향을 주지 않습니다.

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

 

Numeric Type Conversion (숫자 형변환)

음수가 아니어도 웬만하면 Int 타입을 사용해라. 그래야 어떤 경우에도 정수형 상수와 변수가 상호적으로 사용할수있다.

외부 소스에서 명시적으로 크기가 지정된 데이터를 사용하거나 성능, 메모리 사용 또는 기타 필요한 최적화를 위한 특별한 경우에만 다른 정수형 타입을 사용하는게 좋다. 이러한 경우 다른타입을 사용했다고 문서화해두도록하자!

 

Integer Conversion (정수 변환)

정수 상수 또는 변수에 저장할 수 있는 숫자의 범위는 숫자 유형마다 다릅니다.

Int8 상수 또는 변수는 -128에서 127 사이의 숫자를 저장할 수 있는 반면 UInt8 상수 또는 변수는 0에서 255 사이의 숫자를 저장할 수 있습니다. 크기가 지정된 정수 유형의 상수나 변수에 맞지 않는 숫자는 코드가 컴파일될 때 오류로 알려줍니다.

 

Uint8 에서는 -1 값을 저장할수 없으므로 오류발생!

Int8 의 최대값에 +1 을 더하게되면 Int8의 최대값보다 높아지게되므로 오류발생!

let cannotBeNegative: UInt8 = -1
// UInt8 can't store negative numbers, and so this will report an error
let tooBig: Int8 = Int8.max + 1
// Int8 can't 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)

다른 타입의 정수형을 직접 더할 수 없기 때문에 UInt16()을 사용하여 UInt8을 UInt16으로 변환한 뒤 더해줍니다.

이때  twoThousandAndOne의 타입은 타입추론 으로 UInt16이 됩니다.

Integer and Floating-Point Conversion (정수 및 부동 소수점 변환)

정수와 부동 소수점 숫자 타입 변환은 명시적으로 이루어져야 합니다.

let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi equals 3.14159, and is inferred to be of type Double

여기서 상수 3의 값은 Double 유형의 새 값을 만드는 데 사용되므로 더하기의 양쪽이 동일한 유형이 되도록 합니다. 

변환이 없으면 더하기가 되지않고 오류를 발생시킵니다.

 

부동 소수점에서 정수로의 변환도 명시해야 합니다. 정수 유형은 Double 또는 Float 값으로 초기화할 수 있습니다. 

let integerPi = Int(pi)
// integerPi equals 3, and is inferred to be of type Int

부동소수점 값을 정수로 변환하게되면 소수점아래 숫자를 모두 버리게됩니다.

Double타입 pi = 3.14159 를 Int 로 변환 하게되면 pi = 3이 된다!

 

Type Aliases (타입 별명)

유형 별칭은 기존 유형의 대체 이름을 정의합니다. typealias 키워드를 사용하여 유형 별칭을 정의합니다. 

기존 타입을 다른 이름으로 선언하는 것 

typealias AudioSample = UInt16

이렇게 하면 UInt16 타입을 AudioSample이라는 이름으로도 접근할 수 있게 된다.

유형 별칭은 외부 소스에서 특정 크기의 데이터로 작업할 때 유용합니다.

var maxAmplitudeFound = AudioSample.min
// maxAmplitudeFound is now 0

maxAmplitudeFound는 현재 Uint16에 해당하는 값을 저장할수있고 .min 을 사용하여 최소값을 할당하기때문에

maxAmplitudeFound 에는 Uint16의 최소값 0이 저장되게 된다.

Booleans (참,거짓)

Swift에는 Bool이라는 Type이 있습니다. Bool 값은 참(true) 또는 거짓(false) 만 값으로 가질수있습니다.

let orangesAreOrange = true
let turnipsAreDelicious = false

위의 코드처럼 상수나 변수를 생성하자마자 true, false로 설정하면 Bool로 선언할 필요가 없습니다. 

Bool 값은 if 문과 같은 조건문으로 작업할 때 특히 유용합니다.

if turnipsAreDelicious {
    print("Mmm, tasty turnips!")
} else {
    print("Eww, turnips are horrible.")
}
// Prints "Eww, turnips are horrible."

turnpsAreDelicious 는 현재 false 이므로 if 구문에서 else 를 실행하게됨!

let i = 1
if i {
    // this example will not compile, and will report an error
}

조건문에 Bool 값이 아닌 다른값이 들어오면 에러발생!

조건문에는 Bool타입의 값만 올수있다.

let i = 1
if i == 1 {
    // this example will compile successfully
}

이처럼 연산자를 이용하여 Bool값으로 대체하여 사용 가능하다.

 

Tuples (튜플)

튜플은 여러 값을 단일 복합 값으로 그룹화합니다. 튜플 내의 값은 모든 유형이 될 수 있으며 서로 다른 유형이어도 가능 합니다.

let http404Error = (404, "Not Found")
// http404Error is of type (Int, String), and equals (404, "Not Found")

예시 에서 (404, "Not Found")는 HTTP 상태 코드를 설명하는 튜플입니다.

404라는 정수타입과 "Not Found" 라는 문자열타입 이 함께 사용된 모습.

 

HTTP 상태 코드는 웹 페이지를 요청할 때마다 웹 서버에서 반환하는 특수 값입니다.

존재하지 않는 웹페이지를 요청하면 상태 코드 404 Not Found가 반환됩니다.

튜플의 내용을 별도의 상수나 변수로 분해한 다음 평소처럼 접근할 수 있습니다.

let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
// Prints "The status code is 404"
print("The status message is \(statusMessage)")
// Prints "The status message is Not Found"

튜플 값 중 일부만 필요한 경우 튜플을 분해할 때 밑줄(_) 사용하여 나머지 값은 생략 할수있다.

http404Error 의 값중 0번 인덱스 인 404 만을 justTheStatusCode에 할당하고 나머지값은 쉼표와 (_)표시로 생략해준모습.

let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// Prints "The status code is 404"

0번째 인덱스등 인덱스번호 를 표기하여 튜플의 개별 요소 값에 접근도 가능하다.

print("The status code is \(http404Error.0)")
// Prints "The status code is 404"
print("The status message is \(http404Error.1)")
// Prints "The status message is Not Found"

튜플 을 선언할때 튜플의 개별 요소 이름을 지정할 수 있습니다.

let http200Status = (statusCode: 200, description: "OK")

튜플에서 요소의 이름을 지정하면 요소 이름을 사용하여 해당 요소의 값에 접근할 수 있습니다.

print("The status code is \(http200Status.statusCode)")
// Prints "The status code is 200"
print("The status message is \(http200Status.description)")
// Prints "The status message is OK"

튜플은 특히 함수의 반환 값으로 유용합니다. 웹 페이지 검색을 시도하는 함수는 페이지 검색의 성공 또는 실패를 설명하기 위해 (Int, String) 튜플 유형을 반환할 수 있습니다. 각각 다른 유형의 두 개의 고유한 값이 있는 튜플을 반환함으로써 함수는 단일 유형의 단일 값만 반환할 수 있는 경우보다 결과에 대한 더 유용한 정보를 제공합니다.

Note
튜플은 관련된 값의 간단한 그룹에 유용합니다. 복잡한 데이터 구조 생성에는 적합하지 않습니다.
데이터 구조가 더 복잡할 가능성이 있는 경우 튜플이 아닌 클래스 또는 구조로 모델링하십시오.

 

Optionals  (값이 있을지 없을지 모름)

값이 없을 수 있는 상황에서 optional을 사용합니다.

선택 사항은 두 가지 가능성을 나타냅니다. 값이 있거나 값이 없는 경우

값이 있을경우 해당 값에 접근하기 위해 선택서는 래핑을 풀어사용하여야 합니다. (언래핑 과정 필요합니다.)

 

Swift의 Int 유형에는 String 값을 Int 값으로 변환하는 초기화 프로그램이 있습니다. 그러나 모든 문자열을 정수로 변환할 수 있는 것은 아닙니다. 문자열 "123"은 숫자 값 123으로 변환될 수 있지만 문자열 "hello, world"에는 숫자로 바꿀수있는 값이 없기때문에 불가능합니다.

 

이니셜라이저를 사용하여 String을 Int로 변환하려고 시도 하는 예시

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber is inferred to be of type "Int?", or "optional Int"

초기화가 실패할 수 있으므로 Int가 아닌 선택적 Int를 반환합니다. 선택적 Int는 Int가 아닌 Int?로 작성됩니다.

물음표는 포함된 값이 선택 사항임을 나타냅니다. 즉, 일부 Int 값이 포함되거나 값이 전혀 포함되지 않을 수 있습니다.

실패할경우 값이 없음을 나타내는 nil 이 들어가게 됩니다.

 

옵셔널 타입을 선언 하는방법

자료형 뒤에 ? 를 붙여 옵셔널 타입으로 선언할수있다.

Int? 타입에는 Int 타입의 값과 nil 만 들어갈수있다.

 

nil (값 없음)

특별한 값 nil을 할당하여 선택적 변수를 값이 없는 상태로 설정할수 있다.

var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value
Note
옵셔널 타입이 아닌 상수나 변수에는 nil을 사용할수 없습니다.
특정 조건에서 값이 없는 상태에서 작동해야 하는 경우 항상 적절한 타입의옵셔널 값으로 선언합니다.

기본값을 제공하지 않고 옵셔널 변수를 정의하면 변수의 값이 자동으로 nil로 설정됩니다.

var surveyAnswer: String?
// surveyAnswer is automatically set to nil
Note
Swift의 nil은 Objective-C의 nil과 다릅니다. 
Objective-C에서 nil은 존재하지 않는 객체에 대한 포인터입니다. Swift에서 nil은 포인터가 아닙니다.
특정 유형의 값이 없기 때문입니다.
모든 유형의 옵셔널은 객체 유형뿐만 아니라 nil로 설정할 수 있습니다.

 

If Statements and Forced Unwrapping  (조건문 과 강제 언래핑)

조건문을 사용하여 옵셔널타입에 값이 있는지 없는지 검사할수있으며 이때 if 를 사용할수있다.

if 문을 사용하여 옵셔널을 nil과 비교하여 옵셔널에 값이 있는지 확인할 수 있습니다. "같음" 연산자(==) 또는 "같지 않음" 연산자(!=)를 사용하여 이 비교를 수행합니다.

 

convertedNumber 에 할당된 값이 nil 이아니라면 조건문안에 들어있는 실행구문을 실행시켜라

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

옵셔널에 값이 포함되어 있다고 확신하면 옵셔널 이름 끝에 느낌표(!)를 추가하여 기본 값에 접근할 수 있습니다.

이것을 강제 언래핑 이라 표현하며 값이 없는경우 강제언래핑시에는 런타임 오류가 발생할수있다.

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

실행 구문을 보게되면 convertedNumber 에 ! 를 작성하여 convertedNumber의 옵셔널값이 아닌 기본값을 출력할수 있게 한다.

값이 없게되면 오류가 발생 할수있으니 조건문을 사용하여 안전하게 값이 있는지 없는지 확인하여 값이 있을 경우에만 사용하도록 하자.

 

Optional Binding 

옵셔널 바인딩은 if 및 while 문과 함께 사용하여 옵셔널에 값이 포함되어 있는지 확인하고, 값이 있다면 해당 값을 임시 상수나 변수에 옮겨 저장해 사용할 수 있도록 합니다.

 

if 를 사용한 바인딩 예시

if let constantName = someOptional {
    statements
}
if let actualNumber = Int(possibleNumber) {
    print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
    print("The string \"\(possibleNumber)\" couldn't be converted to an integer")
}
// Prints "The string "123" has an integer value of 123"

possibleNumber 를 Int 타입으로 변환에 성공하면 그 값을 actualNumber 에 할당 해라 

실패할경우(possibleNumber의 값이 nil 이거나 Int 타입으로 변환할수 없는 문자열인경우) else 구문을 실행 한다.

이때 상수가 아닌 변수에 할당하는것도 가능하다!

if 구문 밖에서는 바인딩된 값 을 가지고있는 actualNumber 는 사용할수 없다.

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

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

쉼표를 이용하여 if 구문에 여러개의 값을 바인딩 할수있으며 값이 nil 이거나 조건이 false 일경우 if 문 전체가 false 로 간주됩니다.

Note
if 문에서 바인딩으로 생성된 상수 및 변수는 if 문의 본문 내에서만 사용할 수 있습니다.
guard 문에서 바인딩으로 생성된 상수와 변수는 guard 문 밖에서 사용이 가능합니다.

 

Implicitly Unwrapped Optionals

위에서 설명한 것처럼 옵셔널은 상수 또는 변수가 "값 없음"을 가질 수 있음을 나타냅니다.

옵셔널은 값이 있는지 없는지 확인하기 위해 if 문으로 검사할 수 있으며, 값이 있는 경우 옵셔널의 값에 접근하기 위해 옵셔널 바인딩으로 조건부로 래핑을 해제할 수 있습니다.

 

때로는 프로그램의 구조에서 옵셔널이 항상 값을 가질 것이라는 것이 분명한 경우가 있습니다.

이러한 경우 항상 값을 가지고 있다고 안전하게 가정할 수 있기 때문에 접근할 때마다 옵셔널의 값을 확인하고 언래핑 과정을 하지 않는 것이유용합니다.

 

유형 뒤에 물음표(String?) 대신 느낌표(String!)를 작성하여 값이 확실하게 있다고 가정하여 사용할수 있습니다.

옵셔널을 사용할 때 이름 뒤에 느낌표를 붙이지 않고 선언할 때 옵셔널의 타입 뒤에 느낌표를 붙입니다.

값이 있다고 가정한 옵셔널을 정의하게되면 그후 접근하여 사용할때에도 값이 존재하는것으로 가정하기때문에 모든 사용시점에 값이 존재한다고 가정할수있을때 유용합니다.

  • 옵셔널 변수 선언시 ? 를 붙이면 암시적 옵셔널
  • 옵셔널 변수 선언시 ! 를 붙이면 명시적 옵셔널

Swift에서는 주로 클래스 초기화할 때 사용됩니다.

 

암시적 옵셔널과 명시적 옵셔널의 사용 예시

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation point

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation point

forcedString에서 possibleString에 !를 붙여주는 이유는 possibleString이 ?를 붙여준 암시적 옵셔널 변수이기 때문입니다. 하지만 처음 선언부터 !를 붙여 정의한 assumedString 같은 경우에는 다른 변수에서 사용할 때 !를 붙여주지 않아도 되는 것을 볼 수 있습니다.

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

만약 암시적으로 선언된 옵셔널이 nil인데 명시적 옵셔널이 접근하려고 하면 런타임 오류가 발생합니다.

명시적 옵셔널이 일반 옵셔널을 확인하는 것과 같은 방식으로 값이 nil인지 확인할 수 있습니다.

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

명시적 옵셔널이지만 일반적인 바인딩 방법과 같이 if 문을 사용하여 값을 다른 상수나 변수에 할당 해줄수 있다.

if let definiteString = assumedString {
    print(definiteString)
}
// Prints "An implicitly unwrapped optional string."
Note
나중에 변수의 값이 nil 이 될 가능성이 있는경우 명시적 옵셔널을 사용하지 마십시오.
가능성이 있다면 암시적 옵셔널 을 사용하십시오.

 

Error Handling

프로그램 사용중 오류가 생긴다면 오류 처리를 사용하여 해결할수 있습니다.

오류 처리를 통해 실패의 근본 원인을 찾고 필요한 경우 프로그램의 다른 부분에 오류를 전파할 수 있습니다.

함수에 오류가 발생하면 throws 를 사용해 오류를 던져줄수있고 do, catch 를 사용해 해당 오류를 붙잡아 어떤 것을 실행시켜줄지 미리 정해줄수 있게됩니다.

func canThrowAnError() throws {
    // this function may or may not throw an error
}

함수 선언에 throws 키워드를 포함하여 오류를 던질수 있음을 나타냅니다.

오류를 발생시킬 수 있는 함수를 호출할 때 try 키워드를 앞에 추가합니다.

do {
    try canThrowAnError()
    // no error was thrown
} catch {
    // an error was thrown
}

do 의 실행구문인 canThrowAnError() 함수를 호출할때에는 에러를 던질수있는 함수이기 때문에 앞에 try 를 작성 해주어야 한다.

func makeASandwich() throws {
    // ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}

위의 예시를 보면 오류를 던질수있는 함수 makeASandwich 를 호출하고

만약 out0fCleanDishes 라는 오류를 던지게되면

해당 오류를 명시한 catch 가 이를 붙잡아 해당 catch 문 안에있는 실행구문을 실행시킨다.. 라는 느낌이다.

makeASandwich():오류 던져졌어!!

catch1, catch2, catch3: 앗!?

catch2: 이건 내오류야! 내껄 실행시킬게!!

하는느낌..?

오류를 던지지 않았다면 do 구문에서 makeASandwich() 다음 구문인 atASandwich() 를 호출하게된다.

 

Assertions and Preconditions

Assertions and preconditions 은 런타임시에 발생하는 것들을 검사하는것이다.

추가 코드를 실행하기 전에 필수 조건이 충족되었는지 확인하는 데 사용합니다.

만약 조건들이 false로 나오게 되면 코드 실행이 중단되고 프로그램이 종료됩니다. Assertion은 개발과정에서 실수를 잡고 preconditions는 문제를 감지하는 데 도움을 줍니다. 

앞에서 본 Error Handling 과는 다르게 Assertions and Preconditions는 복구 가능하거나 예상되는 오류에는 사용되지 않습니다. 이는 발견 즉시 프로그램을 종료하기 때문입니다. 하지만 바로 종료하기 때문에 잘못된 상태로 인한 피해를 줄일 수 있습니다. 또한 종료가 되어버리기 때문에 오류를 쉽게 디버깅할 수 있습니다. 
Assertions 과 preconditions 의 차이점은 조건을 확인할때 입니다.

Assertions는 디버그 빌드에서만 확인되지만 preconditions은 디버그 및 프로덕션 빌드 모두에서 확인됩니다.

프로덕션 빌드에서는 Assertion이 확인되지 않기 때문에 프로덕션 성능에 영향을 주지 않으면서 Assertion을 사용할 수 있습니다.

Debugging with Assertions

assert(_:_:file:line:) 을 사용하여 Assertions 할수있습니다.

let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// This assertion fails because -3 isn't >= 0.

 

예시에서 age >= 0이 true 라면 지나치게되고 false 라면 프로그램을 종료하게된다.

오류 구문을 적어뒀다면 오류 구문을 출력하게된다.

 

코드가 이미 조건을 확인하는 경우 assertionFailure(_:file:line:) 함수를 사용하여 조건이 실패했음을 나타낼수있다.

if age > 10 {
    print("You can ride the roller-coaster or the ferris wheel.")
} else if age >= 0 {
    print("You can ride the ferris wheel.")
} else {
    assertionFailure("A person's age can't be less than zero.")
}

조건을 모두 실패하게되면 프로그램이 종료되고 assertionFailure(_:file:line:)에 작성된 오류구문을 출력하게된다.

 

Enforcing Preconditions (지금은 이해가 안된다..다음에 다시보도록 하자)

precondition은 조건이 거짓이 될 가능성이 있지만 코드가 실행되기 위해선 반드시 참이어야 할 때 사용합니다. precondition(::file:line:) 함수로 사용할 수 있고 만약 조건이 false라면 설정해둔 오류 구문을 출력합니다.

// In the implementation of a subscript...
precondition(index > 0, "Index must be greater than zero.")

preconditionFailure(_:file:line:) 함수를 사용해서 실패가 발생했다는 것을 표시할 수 있습니다. 만약 uncheckedmode(-Ounchecked) 라면 preconditions는 체크되지 않습니다. 이때 컴파일러는 조건들이 모두 참이라고 생각하고 진행합니다. 그러나 fatalError(_:file:line:) 함수는 이와 관계없이 항상 체크되고 프로그램을 중지시킵니다. 개발자는 fatalError(_:file:line:) 함수를 개발 초기에 사용하여 치명적인 오류에 대해 항상 중지되도록 설정할 수 있습니다.

 

Swift 공식문서

https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html

 

The Basics — The Swift Programming Language (Swift 5.5)

The Basics Swift is a new programming language for iOS, macOS, watchOS, and tvOS app development. Nonetheless, many parts of Swift will be familiar from your experience of developing in C and Objective-C. Swift provides its own versions of all fundamental

docs.swift.org

개발자 pingu 님의 블로그를 참고하여 작성하였습니다!

https://icksw.tistory.com/

 

PinguiOS

iOS 개발자가 되기 위해 iOS 공부, Swift 공부, CS 공부를 하고 있습니다.

icksw.tistory.com

The Basics

'iOS > Swift-Documents' 카테고리의 다른 글

Swift 5.5 Functions -6  (0) 2022.02.04
Swift 5.5 Control Flow -5  (0) 2022.01.27
Swift 5.5 Collection Types -4  (0) 2022.01.27
Swift 5.5 Strings and Characters -3  (0) 2022.01.25
swift5.5 공식문서 Basic Operators -2  (0) 2022.01.23
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함