일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- javascript closure
- 자바스크립트 scope
- 자바스크립트 클래스
- CSS
- 오블완
- 자바스크립트 실행 컨텍스트
- 자바스크립트 생성자 함수
- 웹 개발 트렌드
- 자바스크립트 클로저
- css display
- css3
- front-end
- javascript
- javascript opreator
- 자바스크립트 async await
- HTML
- 자바스크립트 promise
- 티스토리챌린지
- 자바스크립트
- css position
- html 코드
- javascript opreators
- css 포지션
- 프론트엔드
- 자바스크립트 프로미스
- 자바스크립트 스코프
- 자바스크립트 반복문
- 자바스크립트 상속
- 자바스크립트 연산자
- html 주석
- Today
- Total
Multi Developer SuHo
iOS 앱 프로그래밍 3주차 Reprot 본문
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/001.gif)
Swift 언어에서 optional를 쓰는 이유
Swift에서 옵셔널(Optional)은 변수가 값을 가질 수도 있고, 아무런 값도 가지지 않을 수도 있다는 것을 나타내는 타입입니다. 이것은 Swift의 안전한 특성 중 하나로, 개발자가 null 참조와 같은 일반적인 오류를 방지할 수 있게 도와줍니다.
옵셔널이 없다면, 모든 변수가 처음부터 값을 가져야 합니다. 하지만 실제 프로그래밍 상황에서는 그렇게 할 수 없는 경우들이 많습니다. 예를 들어, 네트워크 요청의 결과나 사용자 입력과 같은 값들은 프로그램 실행 시점에만 알 수 있으며, 때로는 이러한 값들이 존재하지 않을 수도 있습니다.
옵셔널을 사용하면 이런 상황을 안전하게 처리할 수 있습니다. 옵셔널 변수에 nil(값이 없음)이 할당되어 있다면 해당 변수를 사용하기 전에 nil 체크를 해야합니다. Swift에서는 if-let 구문 또는 guard-let 구문 등을 통해 옵셔널 바인딩(Optional Binding) 기능으로 이를 쉽게 처리할 수 있습니다.
var name: String? = "John" // Optional String
if let unwrappedName = name {
print("Name is \(unwrappedName)")
} else {
print("Name is not available")
}
위 코드에서 name 변수는 옵셔널 String 타입으로 선언되었습니다. 따라서 name은 문자열 값을 가질수도, 아무런 값도 가지지 않을(nil)수도 있습니다. if-let 구문을 사용하여 name의 값을 안전하게 언래핑(Unwrapping)하고 사용했습니다.
따라서 Swift의 옵셔널 기능은 개발자가 코드 내에서 발생할 가능성 있는 오류 상황에 대해 명시적으로 다루고 관리하도록 돕습니다.
Swift와 Kotlin에서 Optional 개념을 비교한 표
Optional 선언 | var name: String? = "John" | var name: String? = "John" |
Nil/Null 할당 | name = nil | name = null |
Optional Unwrapping (명시적 언래핑) | let unwrappedName = name! (주의: 값이 없을 때 런타임 오류 발생) | N/A - 코틀린은 명시적 언래핑 방식을 지원하지 않음. Null-safe 호출 사용. |
Safe Optional Unwrapping (if-let 구문) | <pre>if let unwrappedName = name {<br> print("Name is (unwrappedName)")<br>} else {<br> print("No name")<br>}</pre> | <pre>val unwrappedName = name ?: "Default"<br>println("Name is $unwrappedName")</pre> |
Safe Optional Unwrapping (guard-let 구문) | <pre>guard let unwrappedName = name else {<br> return<br>}<br>print("Name is (unwrappedName)")</pre> | N/A - 코틀린은 guard-let 구문을 지원하지 않음. if 문으로 대체 가능. |
Null-safe 호출(?. 연산자) | let length = name?.count | val length = name?.length |
위 표는 Swift와 Kotlin에서 옵셔널 개념을 간략하게 비교한 것입니다. 각 언어마다 더 복잡한 옵셔널 처리 기법들이 있으므로, 해당 언어의 공식 문서나 자세한 리소스를 참고하시면 좋습니다.
Swift에서 Optional를 예를 든 소스코드입니다
Swift에서 옵셔널(Optional)은 변수나 상수가 값을 가질 수도 있고, 아무런 값도 가지지 않을 수도 있다는 것을 나타내는 타입입니다. 이것은 Swift의 안전한 특성 중 하나로, 개발자가 null 참조와 같은 일반적인 오류를 방지할 수 있게 도와줍니다.
예를 들어, 사용자의 닉네임을 저장하는 앱을 만든다고 가정해봅시다. 사용자가 닉네임을 설정하지 않았다면, 이 값은 nil이 될 것입니다. 이러한 경우 Swift에서는 옵셔널 타입으로 닉네임 변수를 선언할 수 있습니다:
var nickname: String? // nickname이라는 Optional String 변수 선언
위의 코드에서 nickname 변수는 String? 타입으로 선언되었습니다. 즉, nickname은 문자열 값을 가질수도, 아무런 값도 가지지 않을(nil)수도 있습니다.
만약 사용자가 나중에 닉네임을 설정한다면 해당 값을 할당할 수 있습니다:
nickname = "SwiftMaster"
이제 nickname에 문자열 값 "SwiftMaster"가 할당되었습니다.
그러나 아직 닉네임이 설정되지 않았다면 어떻게 될까요? 그런 경우에 대비하여 옵셔널 값을 안전하게 언래핑(Unwrapping)하려면 if-let 구문 또는 guard-let 구문 등의 옵셔널 바인딩(Optional Binding) 기능을 사용할 수 있습니다:
if let actualNickname = nickname {
print("User's nickname is \(actualNickname)")
} else {
print("User has no nickname")
}
위 코드에서 if-let 구문으로 nickname의 값을 안전하게 언래핑하고 사용했습니다. 만약 nickname에 값이 없으면 (즉, nil이면), "User has no nickname"라고 출력됩니다.
따라서 Swift의 옵셔널 기능은 개발자가 코드 내에서 발생할 가능성 있는 오류 상황에 대해 명시적으로 다루고 관리하도록 돕습니다.
https://docs.swift.org/
docs.swift.org
Swift 언어에 대한 자료 사이트입니다
애플에서 Optional에 대한 개념을 설명해주는 사이트입니다
Optional | Apple Developer Documentation
Optional | Apple Developer Documentation
A type that represents either a wrapped value or the absence of a value.
developer.apple.com
Swift Operator precedence and associativity (With Examples) (programiz.com)
Swift Operator precedence and associativity (With Examples)
Operator precedence is a set of rules that determines which operator is executed first. Before you learn about operator precedence, make sure to know about Swift operators. Let's take an example, suppose there is more than one operator in an expression. va
www.programiz.com
Swift 언어에서 연산자의 우선순위와 결합성을 상세하게 확인할 수 있는 사이트입니다.
Swift 언어에서 연산자들의 우선순위와 결합성을 표로 나열했습니다.
Swift 언어에서 사용되는 연산자들의 우선순위와 결합 방향을 나타낸 표는 다음과 같습니다. 이 표에서는 우선 순위가 높은 연산자부터 낮은 연산자 순으로 나열되어 있습니다.
우선순위연산자결합방향
200 | * / % &* & << >> | 왼쪽에서 오른쪽으로 (Left Associative) |
190 | + - &+ &- `|^ (비트 OR) | 왼쪽에서 오른쪽으로 (Left Associative) |
180 | <, <=, >, '>=', '==', '!=', '===', '!==' ,'<>', '<=>', '~=', '..<', '...', '..<' and the cast operators as, as?, and is. | 없음 (Non-Associative) |
170 | Nil-coalescing operator (??) | 오른쪽에서 왼쪽으로 (Right Associative) |
160 - 140, 130 - 100, and less than or equal to 90 | Logical AND (&&) | 왼쪽에서 오른쪽으로 (Left Associative) |
Less than or equal to 90 | Logical OR (` |
이러한 우선 순위와 결합성은 Swift의 산수 및 비트 수준의 이진 연산자에 대한 것입니다. 단일 항목에 대한 일부 단항 전치 및 후치 연산자(!, -,++,--)는 항상 해당 항목보다 높은 우선 순위를 가집니다.
또한, 괄호를 사용하여 식의 계산 순서를 명확하게 지정할 수 있습니다. 괄호 안에 있는 식은 항상 괄호 밖의 식보다 먼저 계산됩니다.
Swift 언어에서 증가 연사자와 감소 연산자가 없어짐 (x++ , x-- , ++x, --x)
Swift 언어에서 ...와 ..<는 범위 연산자로 사용됩니다.
- ...: 닫힌 범위 연산자(Closed Range Operator) 이 연산자는 시작 값과 끝 값이 모두 포함되는 범위를 생성합니다. 예를 들어, 1...5는 1부터 5까지의 숫자(즉, 1, 2, 3, 4, 5)를 모두 포함하는 범위입니다.
- ..<: 반 열린 범위 연산자(Half-Open Range Operator) 이 연산자는 시작 값은 포함하지만 끝 값은 포함하지 않는 범위를 생성합니다. 예를 들어, 1..<5는 숫자 1부터 시작해서 숫자 5 직전까지(즉, 1, 2, 3, 4)의 범위입니다.
//for i in 1...5 {
//print(i, terminator: " ")
// print(i)
//}
let names = ["A", "B", "C", "D"]
for name in names[3...] { //[...2], [..<2] //과제: 실행 결과
print(name)
} // C
// D
여기서 실행 결과 인덱스 3에 값인 D가 출력됩니다.
클래스로부터 만들어진 Object(객체)를 instance(인스턴스)라고 한다
프로그래밍 언어에서 Type safe 의미
"Type safe"라는 용어는 프로그래밍 언어가 타입 시스템을 통해 잘못된 타입의 값이 사용되지 않도록 보장하는 속성을 나타냅니다. 즉, 데이터 타입에 대한 오류를 방지하기 위해 컴파일 시간에 타입 체크를 수행합니다.
예를 들어, 정수형 변수에 문자열 값을 할당하려고 하면, 타입-세이프 언어의 컴파일러나 인터프리터는 이런 코드를 거부하고 오류 메시지를 출력합니다.
Swift와 같은 type-safe 언어는 개발자가 의도치 않은 오류를 미리 방지할 수 있게 도와줍니다. 예를 들면, Swift에서 다음과 같은 코드는 컴파일 에러로 이어집니다:
var myInteger: Int = 10
myInteger = "Hello" // 컴파일 에러: 'String' 형식의 값은 'Int' 형식에 저장할 수 없습니다.
여기서 myInteger 변수는 Int 타입으로 선언되었기 때문에 문자열 "Hello"를 할당하는 것은 허용되지 않습니다. 이렇게 type-safe 언어들은 잘못된 데이터 유형의 사용을 미리 차단하여 버그와 오류 발생을 최소화하는 데 도움이 됩니다.
var x = 10
var y : Double = x
//print(x/y)
Swift 언어에서 Upcasting 과 Downcasting
"Upcasting"과 "Downcasting"은 객체 지향 프로그래밍에서 주로 사용되는 개념으로, 클래스의 계층 구조에서 상위 클래스와 하위 클래스 사이의 형 변환을 나타냅니다. 이들 용어는 특히 상속 관계가 있는 클래스에서 중요합니다.
- Upcasting: Upcasting은 하위 클래스의 인스턴스를 상위 클래스 타입으로 변환하는 과정입니다. 이는 항상 안전하며, 별도의 체크나 확인 없이 수행할 수 있습니다. Upcast된 인스턴스는 상위 클래스에 정의된 메서드와 속성만 접근할 수 있습니다.
- Downcasting: Downcasting은 상위 클래스의 인스턴스를 하위 클래스 타입으로 변환하는 과정입니다. 이 작업은 항상 안전하지 않으므로 실행 시간에 실패할 수 있습니다(즉, 모든 상위 클래스 객체가 반드시 해당 하위 클래스 객체가 될 수 있는 것은 아닙니다). 그래서 Swift에서는 as? 또는 as! 연산자를 사용하여 downcast를 안전하게(옵셔널) 또는 강제적으로(non-optional) 처리합니다.
Swift 언어에서 upcasting과 downcasting 예제:
class Animal {
func whoAmI() {
print("I am an animal.")
}
}
class Dog: Animal {
func bark() {
print("Woof Woof!")
}
}
let myDog: Dog = Dog()
// Upcast
let animal: Animal = myDog as Animal // 여기서 myDog 인스턴스가 Animal 타입으로 upcast됩니다.
animal.whoAmI()
//animal.bark() // 에러! bark 메소드는 Dog에만 있음
// Downcast
if let dog = animal as? Dog { // 여기서 animal 인스턴스가 Dog 타입으로 downcast됩니다.
dog.bark()
}
이 예제에서 myDog라는 Dog 타입의 인스턴스를 Animal 타입으로 upcast하였고, 그 다음에 다시 Dog 타입으로 downcast하여 원래의 형태로 되돌렸습니다.
타입 검사is)
Swift 언어에서는 is와 as 키워드를 사용하여 타입 검사와 타입 변환을 수행할 수 있습니다.
- is: 이 연산자는 인스턴스가 특정 서브클래스의 인스턴스인지, 또는 프로토콜을 준수하는지 확인합니다.
class Animal {}
class Dog: Animal {}
let myDog = Dog()
print(myDog is Dog) // true
print(myDog is Animal) // true
위의 예제에서 myDog 인스턴스가 Dog 클래스의 인스턴스인지, 그리고 상위 클래스인 Animal의 인스턴스인지 확인합니다.
- as, as?, and as!: 이들 연산자는 하나의 타입을 다른 타입으로 변환(casting)하는데 사용됩니다.
- 'as'는 upcasting에 사용되며, 이 변환이 항상 성공하기 때문에 안전하다.
- 'as?'는 downcasting에 사용되며, 이 변환이 실패할 가능성이 있으므로 결과가 옵셔널이다.
- 'as!'은 강제 downcasting에 사용되며, 만약 변환이 실패하면 런타임 오류를 발생시킨다.
class Animal {
func whoAmI() {
print("I am an animal.")
}
}
class Dog: Animal {
func bark() {
print("Woof Woof!")
}
}
let myAnimal = Animal()
let myDog: Dog = myAnimal as! Dog // 런타임 에러! 'myAnimal'은 'Dog' 타입이 아닙니다.
위의 예제에서 마지막 줄은 런타임 오류를 발생시킵니다. 왜냐하면 'myAnimal'은 단순한 'Animal' 인스턴스이고, 이것을 'Dog'로 downcast하는 것은 허용되지 않기 때문입니다. 따라서 안전한 downcasting (as?)를 권장합니다.
if let dog = myAnimal as? Dog {
dog.bark()
} else {
print("The casting has failed.")
}
위 코드에서 안전한 다운캐스트(as?)를 시도하고 실패한 경우 메시지를 출력합니다.
var x : Int?
print(x)
출력결과 nill (값이 없음)이 출력됩니다
var x : Int?
x = 10
print(x)
Optional 형은 일반값을 넣어주면 그냥 대입되는게 아니고 Opional() 안에 들어간다
Optional 형은 nil 도 출력할 수 있다.
var x : Int!
x = 10
print(x)
Type safe 을 해준 소스
var x : Double = 10.0
var y : Int = Int(x)
String형인 "123"을 Int 형으로 변환한 소스
var x : Double = 10.0
var y : Int = Int(x)
print(Int("123"))
var x : Double = 10.0
var y : Int = Int(x)
print(Int("123"))
print(Int("Hello my name is suho"))
출력결과 nill(값이 없다) 가 출력된다
var x : Int? //옵셔널 정수형 변수 x 선언
var y : Int = 0
x = 10 // 주석처리하면?
print(x) // Optional(10)
print(x!) // forced unwrapping해서 10이 나옴
print(y)
//x = x+2 //가능?
//y = x //가능?
출력결과 Optional(10) 10이 감춰저 출력된다.
-> Optional를 선언할때는 " ? "를 하지만 감춰진 값을 해제하고 싶을때, 또는 일반값으로 하고 싶을때 " ! "로 표기한다
(!) : forced unwrapping
Optional 형으로 적용한 소스
var x : Double? //옵셔널 정수형 변수 x 선언
var y : Double = 3.3
//x = 10 // 주석처리하면?
print(x) // Optional(10)
print(x!) // forced unwrapping해서 10이 나옴
print(y)
x = x! + 3.1 //가능?
y = x! //가능?
var x : Int?
x = 10
if x != nil {
print(x!)
}
else {
print("nil")
}
var x1 : Int?
if x1 != nil {
print(x1!)
}
else {
print("nil")
}
var x : Int?
x = 10
if let xx = x { //옵셔널 변수 x가 값(10)이 있으므로 언래핑해서 일반 상수 xx에 대입하고 if문 실행
print(x,xx)
}
else {
print("nil")
}
var x1 : Int?
if let xx = x1 { //옵셔널 변수 x1이 값이 없어서 if문의 조건이 거짓이 되어 if문 실행하지 않고 else로 감
print(xx)
}
else {
print("nil")
}
소스에서 독특한 점은 ! 가 없는데 출력됩니다.
var x : Int?
x = 10
if let x = x { //옵셔널 변수 x가 값(10)이 있으므로 언래핑해서 일반 상수 xx에 대입하고 if문 실행
print(x)
}
else {
print("nil")
}
var x1 : Int?
if let xx = x1 { //옵셔널 변수 x1이 값이 없어서 if문의 조건이 거짓이 되어 if문 실행하지 않고 else로 감
print(xx)
}
else {
print("nil")
}
// if let x= x 라고 써도 됩니다
Swift 5.7 부터는 if let x 라고 써도 됩니다
//short form of if-let to the Optional Binding
여러 옵셔널을 언래핑한 소스
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
if let firstPet = pet1, let secondPet = pet2 {
print(firstPet, secondPet)
} else {
print("nil")
}
Short form if let the Optional Binging 으로 변경한 소스코드
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
if let pet1, let pet2 {
print(pet1, pet2)
} else {
print("nil")
}
(Implicitly): 자동으로 풀리는 Optional 이다
-> Swift 에서 (,)콤마는 And 연산이다.
var x : Int! = 10
if let x , let y {
} //Optional Binding
implicitly (자동) Explicitly (수동)
9번째 줄과 12번 째 줄은 자동으로 값이 풀리게 된다
Swift 언어에서 Implicitly Unwrapped Optional 예시 코드
Swift에서 Implicitly Unwrapped Optional은 값이 있음을 확신할 수 있는 경우에 사용하는 특별한 종류의 옵셔널입니다. 이는 옵셔널이지만, 일반적으로 접근할 때마다 강제로 언래핑(unwrapping) 할 필요가 없습니다.
Implicitly Unwrapped Optional은 타입 뒤에 느낌표(!)를 붙여 선언합니다. 그리고 이 변수나 상수를 사용할 때는 일반 변수나 상수처럼 사용할 수 있습니다.
다음은 Implicitly Unwrapped Optional의 예시입니다:
var implicitlyUnwrappedOptionalString: String! = "Hello, world!"
// 강제 언래핑 없이 바로 접근 가능
print(implicitlyUnwrappedOptionalString) // "Hello, world!"
위의 예제에서 implicitlyUnwrappedOptionalString은 Implicitly Unwrapped Optional String으로 선언되었고, 해당 값을 출력하는데 별도의 강제 언래핑(!)을 하지 않아도 됩니다.
그러나 주의해야 할 점은 Implicitly Unwrapped Optional에 값이 없는 상태(nil)에서 해당 값을 참조하려고 하면 런타임 에러가 발생합니다. 따라서 가능한 한 안전한 언래핑 방법인 optional binding(if let 또는 guard let)를 사용하는 것이 좋습니다.
var implicitlyUnwrappedOptionalValue: String! = nil
if let value = implicitlyUnwrappedOptionalValue {
print("The value is \(value).")
} else {
print("The value is nil.")
}
위 예시처럼 if let 구문으로 안전하게 옵셔너값을 unwrap 할 수 있습니다.
let defaultAge = 1
var age : Int?
age = 3
print(age) //과제:값은?
var myAge = age ?? defaultAge
//age가 nil이 아니므로 언래핑된 값이 나옴
print(myAge) //과제: 값은
let defaultAge = 1
var age : Int?
//age = 5
print(age) //과제:값은?
var myAge = age ?? 1
//age가 nil이 아니므로 언래핑된 값이 나옴
print(myAge) //과제: 값은
myAge 는 Optional이 틀린값이 들어간다
nill 값이면 초기값 1이 들어간다
let defaultColor = "black"
var userDefinedColor: String? // defaults to nil
var myColor = userDefinedColor ?? defaultColor
//nil이므로 defaultColor인 black으로 할당됨
print(myColor) //black
userDefinedColor = "red"
myColor = userDefinedColor ?? defaultColor
//nil이 아니므로 언래핑된 red가 할당됨
print(myColor) //red, 주의 optional(red)가 아님
Swift 언어에서 Optional를 해제하는 방법
Swift에서 옵셔널을 처리하는 방법에는 여러 가지가 있습니다. 가장 일반적으로 사용되는 방법들을 다음과 같이 나열해볼 수 있습니다:
- Optional Binding (if let 또는 guard let): 이 방법은 옵셔널 값을 안전하게 언래핑하고, 그 값이 존재할 때만 코드 블록 내에서 사용할 수 있게 합니다.
var optionalValue: String? = "Hello, world!"
if let value = optionalValue {
print("The value is \(value).")
} else {
print("The value is nil.")
}
- Forced Unwrapping (!): 이 방법은 간편하지만, 옵셔널 값이 nil인 경우 런타임 오류를 발생시킵니다.
var optionalValue: String? = "Hello, world!"
print(optionalValue!) // "Hello, world!"
- Nil-Coalescing Operator (??): 이 연산자를 사용하면 옵셔널 값이 nil인 경우 기본값을 제공할 수 있습니다.
var optionalValue: String? = nil
let value = optionalValue ?? "Default Value"
print(value) // "Default Value"
- Optional Chaining (?. or ?.method() or ?[index]) : 이것은 옵셔널의 속성에 접근하거나 메소드를 호출할 때 사용됩니다. 만약 옵셔널 값이 nil인 경우, 나머지 체인은 무시되고 전체 표현식의 값은 nil입니다.
class MyClass {
var property: String?
}
let myInstance: MyClass? = MyClass()
myInstance?.property = "Hello, world!" // myInstance가 nil이 아니므로 속성 설정 가능
let anotherInstance: MyClass? = nil
anotherInstance?.property = "Hello again!" // anotherInstance가 nil이므로 속성 설정 무시됨.
위 순서는 일반적으로 많이 사용되는 순서를 나타내며 개발자의 선호도나 상황에 따라 달라질 수 있습니다.
'Swift 과제물' 카테고리의 다른 글
iOS 프로그래밍 6주차 Report (0) | 2023.10.17 |
---|---|
iOS 프로그래밍 5주차 Report (0) | 2023.10.10 |
iOS 프로그래밍 4주차 Report (0) | 2023.09.26 |
iOS 프로그래밍 2주차 Report (0) | 2023.09.12 |
iOS 프로그래밍 기초 1주차 Report (0) | 2023.09.05 |