변수와 상수
: 타입에 대해서 명시를 해줘야 합니다.
// 상수
let 이름: 타입 = 값
// 변수
var 이름: 타입 = 값
// 타입 추론
var happyNewYear = 0101
타입 추론 : int 라는 타입으로 명시하지 않아도 숫자임을 언어에서 추론하게 됩니다.
그렇다면 타입은 무엇이 있는지 설명하겠습니다.
- Int, Uint
- Float, Double
- String, Character
Int : 기본적으로 64비트 정수를 사용되지만, Int32 와 Int64 등으로 더 명확하게 표현할 수 있습니다.
Uint : 64비트 양수의 정수로 C에서 사용한 unsigned int와 동일합니다.
Float : A single-precision, floating-point value type
Double : A double-precision, floating-point value type
String : 문자열
Character : 문자
Any : 모든 타입을 지칭하는 키워드
AnyObject : 모든 클래스 타입을 지칭하는 프로토콜
nil : 없음을 나타내는 키워드로 NULL과 비슷
Array와 Dictionary
: Array는 멤버가 순서(인덱스)를 가진 리스트 형태의 컬렉션 타입이며, Dictionary는 '키'와 '값'의 쌍으로 이루어진 컬렉션 타입입니다.
// Array
var languages: [String] = []
// var integers: Array<String> = Array<String>()
// 와 같이 여러의 형태로 선언을 할 수 있습니다.
// Dictionary
var sportsPlayers : [String: Int64] = [:]
// var anyDictionary : Dictionary<String, Int64> = [String : Int64]()
// 와 같이 여러의 형태로 선언을 할 수 있습니다.
// ()를 부르는 것은 생성자를 생성하는 것입니다
조건문과 반복문
: 조건문에서는 if 와 switch 를 사용하며, 반복문에서는 for, while 을 사용합니다.
if (0 < randomNumber && randomNumber <= 10) {
"1 ~ 10사이의 수입니다"
} else if (10 < randomNumber && randomNumber <= 20) {
"11 ~ 20사이의 수입니다"
} else {
"1 ~ 20이 아닌 수입니다"
}
/*
C언어에서 사용하던
if (!isZero(n)) {
...
}
위와 같은 것은 정확한 타입으로 비교를 해야 하므로 이와 같이 써야합니다.
if (isZero(n) == 0) {
...
}
array이나 string의 경우는 anyArray.isEmpty 로 확인을 하면 됩니다.
*/
switch(randonNumber) {
case 1..<11:
"1 ~ 10사이의 수입니다"
case 11..<20:
"11 ~ 20사이의 수입니다"
default:
"1 ~ 20이 아닌 수입니다"
}
Range
Closed Range : (a..<b)의 형태로 사용되며, a이상 b미만을 의미합니다.
Partial Range : (a...), (...a) (..<a)로 사용되며, (a이상), (a이하), (a미만)을 의미합니다.
for color in Raindow {
print("무지개는 \(color) 색깔이 있습니다.")
}
for (country, capital) in capitals {
print("\(country)의 수도는 \(capital)입니다.")
}
while (randomNumber.count > 0) {
randomNumber.removeLast()
}
// reapeat while : C언어에서 사용하는 do while과 비슷함
repeat {
randomNumber.removeLast()
} while randomNumber.count > 0
Optional
: 선택적 값을 사용할 때마다 유형을 사용 합니다. (정해진 타입의 값이 있을 수도 있고 없을 수도 있다)
let shortForm: Int? = Int("42")
let longForm: Optional<Int> = Int("42")
let optionalForm: Int?
optionalForm = nil or Int
let notOptionalForm: Int
notOptionalForm = nil // Error
nil : value 가 없다는 의미
var optionalString: String? = “Hello World!”
print(optionalString)
// Optional("Hello World!")
옵셔널로 선언된 변수는 실제 코드가 실행되기 전까지는 값이 있는지 없는지 알 수 없기에 String 변수에 값을 대입할 수 없습니다.
Optional의 값만 가져오도록 Optional Binding(옵셔널 바인딩)
if let todayGuests = guests {
print(todayGuests)
}
if let name = guestName, phoneNumber = guestPhoneNumber {
...
}
Optional 값이 존재하면 변수에 값을 저장하여 동작하는 코드
let myName: String? = "jaewpark"
if let name = myName, name == "jaewpark" {
print("\(name) Hi!!!!")
}
/* 코드가 길어진다면, 여러 줄로 사용을 권고
if let whatIsYourName = collegeStudents
let age = 27... {
// 나이 27이상 학생 이름 사용
} */
Optional Chaining
: 코드를 좀더 간략하게 사용, 코드를 통해 쉽게 이해할 수 있습니다.
let myName: String? = "jaewpark"
if let name = myName? == "jaewpark" {
print("\(name) Hi!!!!")
}
let array: [String]? = []
// if let array = array, array.isEmpty {
if let array = array?.isEmpty == true {
print("Array is Empty")
} else {
print("Array is Not Empty")
}
Optional 벗기기
! 키워드를 붙여서 값에 바로 접근할 수 있습니다.
print(OptionalString) // Optional("this is optional?")
print(OptionalString!) // this is optional?
Implicitly Unwrapped Optional
let fruitJuice: String! = "Strawberry"
값이 포함하거나 nil 일수도 있지만 사용하기 전에 확인할 필요가 없습니다.
Unwrapping은 옵셔널 값을 확인하는 것을 의미하는데 nil이 남아있다면 코드가 충돌하면 문제가 생길 수 있으나,
시작에는 nil 일지라도 필요한 값이 nil이 되지 않을 때 사용을 하면 됩니다.
(확신이 들지 않는다면, 사용하지 않아야 합니다.)
Function
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입...) -> 반환타입 {
return 반환값
}
func max(a: Int, b: Int) -> Int {
return a > b ? a : b
}
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
argument label
: 매개변수 이름 앞에 공백으로 구분된 argument label을 작성하여, 코드를 더 읽기 쉽게 만드는 데 도움이 됩니다.
func greeting(for person: String) -> String {
"Hello, " + person + "!"
}
print(greeting(for: "Dave"))
// Prints "Hello, Dave!"
func someFunction(_ firstInt: Int, secondInt: Int) {
print("\(firstInt) and \(secondInt)")
}
somFunction(1, secondInt: 2)
_ 를 사용하여 매개변수를 생략할 수 있습니다.
variadic parameters
: 가변 매개변수는 지정된 유형의 0개 이상의 값을 허용합니다. c언어에서 printf가 가변인자를 통해 값을 받는 것과 같습니다.
func arithmeticMean(_ numbers: Int...) -> Int {
var total: Int = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
In-Out parameters
: 함수 매개변수는 기본적으로 상수입니다. 그렇기에 함수의 본문 내에서 매개변수의 값을 변경할 수가 없습니다.
in-out 매개변수를 작성하여 원래 값을 대체하여 전달할 수 있습니다. 전달할 때 변수 이름 앞에 &를 배치합니다.
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"
Closures (참고)
: 코드에 전달되어 사용될 수 있는 기능의 자체 포함 블록입니다. C 그리고 Objective-C의 블록 및 다른 프로그래밍 언어의 람다와 유사합니다. 클로저는 정의된 컨텍스트에서 모든 상수 및 변수에 대한 참조를 캡처하고 저장할 수 있습니다.
이러한 설명으로 소개가 되지만 코드를 간결하게 만들어 주는 코드로 중괄호로 감싸진 실행 가능한 코드 블럭입니다.
// Closure Expression Syntax
// { (parameters) -> return type in statements }
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
메서드에 인수로 전달되기 때문에 매개변수의 유형과 반환하는 값의 유형을 유추할 수 있습니다.
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
return 단일 표현식의 결과를 암시적으로 반환할 수 있습니다.
reversedNames = names.sorted(by: { $0 > $1 } )
Shorthand Argument Names $0, $1 와 같이 인자 값을 참조하여 사용할 수 있습니다.
reversedNames = names.sorted(by: >)
큼 연산자( >)의 문자열별 구현을 type 의 두 매개변수가 있는 메소드로 정의하고 type String값을 반환합니다
let arr1 = [2, 4, 6, 8, 10]
let arr2 = arr1.map{ $0 * 2 }
Enumerations
: 열거형 은 관련 값 그룹에 대한 공통 유형을 정의하고 코드 내에서 유형이 안전한 방식으로 해당 값으로 작업할 수 있도록 합니다.
enum CompassPoint {
case north
case south
case east
case west
}
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
var directionToHead = CompassPoint.north
directionToHead = .east
이미 유형이 유추가 가능하기 때문에 다른 값으로 설정할 수 있습니다
Iterating over Enumeration Cases
: CaseIterable 을 뒤에 붙여서 allCases 속성을 사용할 수 있게 합니다.
enum Beverage: CaseIterable {
case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases.count
print("\(numberOfChoices) beverages available")
// Prints "3 beverages available"
for beverage in Beverage.allCases {
print(beverage)
}
// coffee
// tea
// juice
associated values
: 케이스의 값과 함께 다른 유형의 값을 저장할 수 있습니다.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.qrCode("ABCDEFGHIJKLMNOP")
raw values
: 값을 미리 지정할 수 있습니다
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
Implicitly assigned raw values
: 정수 또는 문자열 원시 값을 저장하는 열거형으로 작업할 때 각 case에 대해 값을 명시적으로 할당할 필요가 없습니다. 자동으로 값을 할당하기 때문입니다.
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
structures and classes
구조체는 값 유형입니다.
struct Resolution {
var width = 0
var height = 0
}
let hd = Resolution(width: 640, height: 480)
var cinema = hd
cinema.width = 2048
cinema와 hd는 별개의 두 인스턴스였기 때문에 cinema가 값을 설정해도 hd에는 영향이 미치지 않습니다.
클래스는 참조 유형입니다.
위와 비슷하게 코드를 사용한다면, 동일한 인스턴스를 참조하기 때문에 단일 인스턴스에 두 개의 다른 이름일 뿐입니다.
클래스는 동일한 인스턴스를 참조하는지 여부를 찾는 두 가지 ID 연산자가 제공됩니다.
if tenEighty === alsoTenEighty {
print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}
=== : 동일하다
!== : 동일하지 않다
참고 사이트
'Language > Swift' 카테고리의 다른 글
swift computed property 연산 프로퍼티 (0) | 2022.08.23 |
---|---|
swift nested function (0) | 2022.08.22 |
swift defer 블록 (0) | 2022.08.22 |
[Swift] continue, fallthrough-switch, where-for, enumerated, zip, indices (0) | 2022.08.07 |
[Swift] guard 문 (0) | 2022.08.07 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!