스터디를 진행하며 처음부터 다시 Swift를 공부하고 있습니다.
오늘 기록할 차시는 변수입니다. ( 기본 / 기본연산자 / 문자열과 문자 / 콜렉션 타입 )
var number : Int = 10
var plusnumber : UInt = 10 //양의 정수 타입. 64비트 양의 정수형
var sosu1 : Float = 3.14 //32비트 부동소수형
var sosu2 : Double = 3.14 //64비트 부동소수형
var chars : Character = "Hello World!!" //문자 타입
var spring : String = "Hello World!!" //문자열 타입 (추후 자세히 다룰 예정)
var choose : Bool = false //true나 false만 가능
var all : Any = 100 //스위프트의 모든 타입을 지칭
all = "아무거나 넣을 수 있다" //마지막에 String 타입의 값을 넣었더라도 Any는 String이 아니기 때문에 할당 x
all = spring //ERROR
var box : Array<Int> = Array<Int>()
var integers = [Int]() //축약 (추후 자세히 다룰 예정)
var anyDic : Dictionary<String, Any> = [String : Any]() //[key : value]타입
var anyDictionary = [String : Any]() //축약
var integerSet : Set<Int> = Set<Int>() //중복되지 않는 멤버가 순서 없이 존재하는 컬렉션 (축약형 없음)
Swift는 타입-세이프 언어입니다. 때문에 Swift는 특정 타입을 지정하지 않으면 타입 추론을 사용합니다.
덕분에 개발 단계에서 가능한 빨리 오류를 포착하고 수정할 수 있습니다.
let save = 500000 // save is inferred to be of type Int
var spend : String = 800000 // Cannot convert value of type 'Int' to specified type 'String'
위의 예시처럼 spend는 Int형인데 String으로 타입 명시를 해버려서 틀렸다는 에러를 띄워줍니다.
Cannot convert value of type 'Int' to specified type 'String'
let
과 var
상수의 값은 최초 지정 후 변경이 불가능하지만 변수는 다른 값으로 변경이 가능합니다.
상수와 변수는 사용하기 전에 반드시 선언이 되어야 하며,
상수는 let
키워드와 함께 선언하고 변수는 var
키워드와 함께 선언합니다.
//8월
let save = 500000 //저축은 매달 50만원 고정이므로 let 선언
var spend = 400000 //지출액은 매달 변동되므로 var 선언
//9월
save += 200000 [ ⛔️ Left side of mutating operator isn't mutable: 'save' is a 'let' constant ]
spend += 200000 //9월은 명절으로 지출이 20만원 늘었다 (변경가능!!)
코드에서 저장한 값이 변경되지 않는다면 항상 let
키워드로 상수로 선언해야 합니다.
var
는 오직 값을 저장하고 변경이 필요할 때 선언합니다.**
👉🏻 is
, as
, as?
, as!
는 타입캐스팅으로 추후 다룰 예정!!
String
과 Character
⭐️String
은 문자열 타입이며, Character
는 문자 타입입니다!!!!!
하단에 유용한 String 관련 함수들을 작성해보았습니다.
var emptyStr = "" //혹은 "" 말고 String()도 가능!!
if emptyStr.isEmpty {
print("isEmpty here.")
}
//isEmpty here.
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
//3 times 2.5 is 7.5
문자열에서 Character
값의 카운트를 구하려면 문자열에서 count
프로퍼티를 사용합니다
var word = "cafe"
print("the number of characters in \(word) is \(word.count)")
//the number of characters in cafe is 4
String
의 메서드 index(before:)
와 index(after:)
를 사용하여 주어진 인덱스의 전과 후에 접근할 수 있습니다. 주어진 인덱스에서 먼 인덱스에 접근하려면 이러한 메서드를 여러번 호출하는 대신 index(_:offsetBy:)
메서드를 사용할 수 있습니다.
let greeting = "Guten Tag!"
greeting[greeting.startIndex]
// G
greeting[greeting.index(before: greeting.endIndex)]
// !
greeting[greeting.index(after: greeting.startIndex)]
// u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index]
// a
문자열 범위에 벗어나는 인덱스로 접근하거나, 문자열 범위에 벗어나는 인덱스의 Character
를 접근하려고 하면 런타임 에러가 발생합니다.
var welcome = "hello"
welcome.insert("!", at: welcome.endIndex) //hello의 마지막인덱스에 !를 삽입하라.
//hello!
welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex)) //hello!에 there을 삽입하되, 마지막인덱스인 ! 전에 삽입하라.
//hello there!
welcome.remove(at: welcome.index(before: welcome.endIndex)) //hello there!에서 마지막인덱스인 !를 삭제하라.
//hello there
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
//hello
유형 | hasPrefix | hasSuffix | contains |
---|---|---|---|
용도 | 앞에 이거 있어? (접두사) | 뒤에 이거 있어? (접미사) | 이거 포함됨? (요소) |
리턴 타입 | Bool | Bool | Bool |
공통점 | 대소문자를 구별함 | 대소문자를 구별함 | 대소문자를 구별함 |
hasPrefix
와 hasSuffix
를 이용하여 원하는 문자를 찾을 수 있습니다.
let drink = "Cafe Latte"
let dessert = "chocolates"
print(drink.hasPrefix("cafe Latte")) // false - 소문자 c로 시작했기 때문입니다.
print(drink.hasPrefix("Cafe Latte")) // true
print(dessert.hasSuffix("Chocolate")) // false - 대문자 C이기 때문입니다.
print(dessert.hasSuffix("chocolates")) // true
print(dessert.hasSuffix("chocolate")) // false
hasPrefix
처럼 hasSuffix
도 대소문자를 구별하기 때문에 위와 같은 결과를 반환합니다.
hasPrefix
는 앞으로 검색할 때, hasSuffix
는 뒤에서 검색할 때 사용합니다.
contains
도 마찬가지로 원하는 문자를 찾을 수 있습니다. 배열도, 문자열도 모두 가능합니다.
보통 일부 문자를 포함하는지 확인할 때 많이 사용합니다.
let drink = ["Cafe Latte", "Vanilla Latte"]
let hello = "Thanks. Here is my own cafe"
print(hello.contains("Thank")) // true
print(hello.contains("Thanks")) // true
print(hello.contains("x")) // false - x라는 문자가 하나도 없습니다.
print(hello.contains("t")) // false
print(hello.contains("T")) // true
참고 : https://velog.io/@un1945/Swift-hasPrefix-hasSuffix-contains
이름 | 형태 |
---|---|
Array | var someArray = [1,2,3] |
Dictionary | var someDic = [ “code” : 1, “number” : 2, “age” : 3 ] |
Set | var someSet : Set = ["Rock", "Classical", "Hip hop"] |
//1. 타입 추론으로 생성하기
var someArray = [1,2,3]
var someArray = [] // ⛔️ Empty collection literal requires an explicit type
//2. 타입 Annotation으로 생성하기
var someArray: [Int] = [1,2,3]
var someArray: [Int] = []
//3. 생성자로 생성하기
var someArray = Array<Int>()
var someArray = [Int]()
var someArray = [Int](repeating: 10, count: 0) //생성과 동시에 10개 Element 생성 및 0으로 초기화
var someArray = [1,2,3]
let count: Int = someArray.count // 배열 갯수 확인 : 3
let isEmpty: Bool = someArray.isEmpty // 배열 비었는지 확인 : false
var someArray = [1,2,3]
someArray.append(4) // [1, 2, 3, 4]
someArray.append(contentsOf: [5,6,7]) // [1, 2, 3, 4, 5, 6, 7]
someArray.insert(4, at: 3) // [1, 2, 3, 4]
someArray.insert(contentsOf: [5,6,7], at: 4) // [1, 2, 3, 4, 5, 6, 7]
⚠️ 배열의 경우 index로 접근하니 ,insert를 해주면 insert를 하는 위치부터 배열을 재배치 해야 하기 때문에 오버헤드가 발생한다. 꼭 필요하지 않다면 append를 사용하는게 좋다.
var someArray = [1, 2, 3]
//값 변경하기 - Subscript, 범위로 접근하여 값 변경
someArray[0] = 10 // [10, 2, 3]
someArray[0...2] = [0] // [0]
someArray[0..<1] = [] // []
//값 변경하기 - replaceSubrange (범위변경)
someArray.replaceSubrange(0...2, with: [10, 20, 30]) // [10, 20, 30]
someArray.replaceSubrange(0...2, with: [0]) // [0]
someArray.replaceSubrange(0..<1, with: []) // []
//요소 바꾸기
var someArray = [1, 2, 3, 4, 5]
someArray.swapAt(0, 4) // [5, 2, 3, 4, 1]
var someArray = [1, 2, 3, 4, 5, 6, 7, 8. 9]
//삭제하기
array1.remove(at: 8) // [1, 2, 3, 4, 5, 6, 7, 8]
array1.removeFirst() // [2, 3, 4, 5, 6, 7, 8, 9]
array1.removeFirst(2) // [4, 5, 6, 7, 8, 9]
array1.removeLast() // [5, 6, 7, 8]
array1.popLast() // [5, 6, 7]
array1.removeLast(2) // [5]
array1.removeAll() // []
//특정 범위 삭제하기
array2.removeSubrange(1...3) // [1, 5, 6, 7, 8, 9]
array2[0..<2] = [] // [6, 7, 8, 9]
배열에서는 contains
를 사용합니다. 앞서 설명했던 그 contains
입니다.
first | firstIndex |
---|---|
가장 첫 번째 요소의 "값"을 리턴 | 가장 첫 번째 요소의 "Index"을 리턴 |
last | lastIndex |
---|---|
가장 마지막 요소의 "값"을 리턴 | 가장 마지막 요소의 "Index"을 리턴 |
var someArray = [1, 2, 3, 2, 5]
someArray.contains(1) //true
someArray.contains { num in // true
num % 2 == 0
}
if let firstIndex = someArray.firstIndex(of: 2) {
print(firstIndex) // 1
}
if let lastIndex = someArray.lastIndex(of: 2) {
print(lastIndex) // 3
}
이름 | sort | sorted |
---|---|---|
공통(형태) | sort() = 오름차순 정렬 | sorted() = 오름차순 정렬 |
sort(by : > ) = 내림차순 정렬 | sorted(by : > ) = 내림차순 정렬 | |
차이 | 배열 원본을 건드리고 배열을 리턴 | 배열 원본은 건들지 않고 정렬된 새로운 배열을 리턴 |
var someArray = [1, 5, 3, 8, 6, 10, 14]
someArray.sort() // [1, 3, 5, 6, 8, 10, 14]
someArray.sort(by: >) // [14, 10, 8, 6, 5, 3, 1]
let sortedArray = someArray.sorted() // [1, 3, 5, 6, 8, 10, 14]
let sortedArray2 = someArray.sorted(by: >) // [14, 10, 8, 6, 5, 3, 1]
형태는 배열과 같이 []에 있으나 배열과 다르게 [key:value] 타입이며,
Key
는 딕셔너리 키로 사용되는 값의 타입이고 Value
는 딕셔너리에 저장될 값의 타입이다.
⚠️ Swift는 타입에 민감하기에 모든 Key의 자료형은 같아야 하고, 모든 Value의 자료형도 같아야 한다.
//딕셔너리 한 개에 여러 타입의 Value를 저장하고 싶을 경우
var dic : [String: Any] = ["name": "Dotzero", "age": 19]
//단, Key값은 무조건 Hashable이란 프로토콜을 준수하는 자료형만 올 수 있음.
// ⛔️ Type 'Any' does not conform to protocol 'Hashable'
var dic : [Any : Any] = [1 : "Dotzero", "age": 19]
Any를 남발하는 것은 정적 바인딩 언어인 Swift를 동적 바인딩 시키는 것이기 때문에 최대한 쓰지말자.
var dic : [String: Int] = ["code": 04, "age": 19]
//해당 키값이 없을 수도 있으니 기본 반환값은 Optional Type 이다.
let number = dic["code"] // Optional(04)
let fault = dic["phone"] // nil
//Optional Type이 싫다면 default 값을 직접 명시
let number = dic["code", default: 05] //4
let fault = dic["phone", default: 8212345678] //8212345678
var dic : [String: Int] = ["code": 04, "age": 19]
dic.updateValue(05, forKey: "code") // ["code": 5, "age": 19]
dic.updateValue(20, forKey: "age") // ["code": 5, "age": 20]
dic.removeValue(forKey: "code") // ["age": 20]
dic.removeValue(forKey: "age") // [:]
dic.removeAll() // [:]
익명의 구조체..같은 느낌?
솔직히 보통은 배열이나 딕셔너리를 많이 사용하다보니 튜플이 많이 낯설긴 하다.
let zero = (name : "hyi", age : 19, city : Seoul)
print(zero.name) //hyi
print(zero.age) //19
print(zero.city) //Seoul
https://bbiguduk.gitbook.io/swift/
https://babbab2.tistory.com