Swift/Swift Syntax
Swift 문법 - 명명법, 콘솔로그, 문자열 보간법
eelijus
2022. 5. 4. 09:11
01. 명명법 / 콘솔로그 / 문자열 보간법
이름짓기 규칙
- 카멜케이스대문자 시작(UpperCamelCase) : type(class, struct, enum, extension)
- 소문자 시작(LowerCamelCase) : function, method, variable, constant
콘솔로그 남기기
- print : 단순 문자열 출력
- dump : 인스턴스의 자세한 설명(description 프로퍼티)까지 출력
문자열 보간법
- String Interpolation→
\(변수명)
import UIKit import Swift let age: Int = 10
"안녕하세요! 저는 \(age)살입니다"
"거짓말이에요! 사실 저는 \(age + 18)살이지롱"
print("안녕하세요! 저는 \(age + 18)살 거짓말쟁이입니다")
// Debug area : 안녕하세요! 저는 28살 거짓말쟁이입니다
- 프로그램 실행 중 문자열 내의 변수 또는 상수의 실질적인 값을 표현하기 위해 사용
02. 상수와 변수
- let : 상수 선언 키워드 → 차후에 변경이 불가능한 상수 선언
- var : 변수 선언 키워드 → 차후에 변경이 가능한 변수 선언
상수/변수 선언
//let 이름: 타입 = 값
//var 이름 = 값 (타입이 명확한 경우에. 권장 x)
let constant: String = "차후에 변경이 불가능한 상수 let"
var variable: String = "차후에 변경이 가능한 변수 var"
variable = "변수는 이렇게 차후에 다른 값을 할당할 수 있지만"
// constant = "상수는 차후에 값을 변경할 수 없습니다" -> 에러 발생
상수/변수 선언 후, 값 할당하기
//상수 선언만. 값 할당은 나중에
let sum: Int
let inputA: Int = 100
let inputB: Int = 200
//위에서 선언한 상수 sum에 여기서 값을 할당한다
sum = inputA + inputB
print(sum)
//변수도 마찬가지로 선언과 할당을 분리해서 할 수 있다
var nickName: String?
nickName = "sujilee"
print(nickName!)
import Swift
let constant: String = "차후에 변경이 불가능한 상수 let"
var variable: String = "차후에 변경이 가능한 변수 var"
variable = "변수는 이렇게 차후에 다른 값을 할당할 수 있지롱"
//constant = "이러면 에러 뜰걸?"
let sum: Int
let inputA: Int = 42
let inputB: Int = 200
//선언 이후 첫 할당만 가능
sum = inputA + inputB
print(sum)
03. 기본 데이터 타입
Swift의 기본 데이터 타입
- Bool
- 오직 true와 false만을 값으로 가지는 타입. 0과 1은 값으로 할당하면 컴파일 오류를 발생시킨다.
- Int
- 정수 타입. 기본적으로 64비트 정수형
- UInt
- 양의 정수 타입(Unsigned Int). 기본적으로 64비트 양의 정수형
- Float
- 실수 타입. 32비트 부동소수형. 정수값 받아들임
- Double
- 실수 타입. 64비트 부동소수형. 정수값 받아들임. float는 노노.
- Character
- 유니코드를 사용하는 문자 타입. 큰따옴표 사용
- String
- 유니코드를 사용하는 문자열 타입. 큰따옴포 사용
💡 swift는 자료형, 즉 데이터 타입에 엄격한 언어. 다른 데이터 타입 간의 자료교환이 매우 까다롭다
04. Any, AnyObject, nil
- Any어떤 타입도 수용 가능하나, 역시나 다른 데이터 타입에 Any 타입의 값을 할당할 수는 없다.
import UIKit import Swift var someAny: Any = 100 //어떤 타입의 변수도 수용 가능 someAny = 12.12 let someDouble: Double = someAny // 에러 nil - 없음을 의미하는 키워드
var someAny: Any = 100; someAny = "어떤 타입도 수용 가능합니다" someAny = 123.2 print(someAny) //let someDouble: Double = someAny -> 컴파일 오류 발생
- nil은 못들어옴.
- swift의 모든 타입을 지칭하는 키워드
- AnyObject
class someClass{} var someAnyObject: AnyObject = someClass() //AnyObject는 클래스의 인스턴스만 수용 가능 //someAnyObect = 123.12 -> 컴파일 에러
- 모든 클래스 타입을 지칭하는 프로토콜
- nilnull, Null, NULL 등과 유사한 표현임
class SomeClass{} var someAny: Any = 100 var someAnyObject: AnyObject = SomeClass() //someAny는 Any타입이고, someAnyObject는 AnyObject 타입이기 때문에 //nil을 할당할 수 없습니다 //someAny = nil -> 컴파일 오류 발생 //someAnyObject = nil -> 컴파일 오류 발생
- 없음을 의미하는 키워드
05. 컬렉션 타입(Array, Dictionary, Set)
- Array - 순서가 있는 리스트 컬렉션
- Dictionary - 키와 값의 쌍으로 이루어진 컬렉션
- Set - 순서가 없고, 멤버가 유일한 컬렉션
Array
import Swift
//빈 Int Array 생성
var integers: Array<Int> = Array<Int>() //뒤에 붙이는 ()는 빈 인스턴스 생성
integers.append(1) //append : 맨 뒤에다 멤버를 삽입하는 함수
integers.append(100)
integers.contains(100) //contains : 특정 멤버를 가지고 있는지 확인하는 함수
integers.remove(at: 0) //remove(at: 인덱스) : 해당 인덱스의 멤버를 제거하는 함수
integers.removeLast() //removeLast : 맨 마지막 멤버 제거
integers.removeAll() //removeall : 모든 멤버를 제거하는 함수
integers.count //count : 멤버 개수 세는 프로퍼티
// integers[0] -> Error! 없는 인덱스에 접근하려고 하면 에러임
//리터럴 표현(축약 표현)
//빈 Double Array 생성
var doubles: Array<Double> = [Double]() //Array<Double>과 [Double]은 동일한 표현
//더 축약을 원해?
var characters: Array<Character> = [] //이러면 빈 Character Array 생성
let immutableArray = [1, 2, 3]
//let을 사용해 Array를 선언하면 불면 Array가 되어 appen()나 remove()같은 메소드를 사용 못함
Dictionary
import Swift
//Key가 String이고 Value가 Any인 빈 Dictionary 생성 & 인스턴스 생성 : 키 - 스트링 / 벨류 - 암거나
var anyDictionary: Dictionary<String, Any> = [String: Any]()
anyDictionary["someKey"] = "value" //키, 벨류 매칭
anyDictionary["anotherKey"] = 100
anyDictionary
anyDictionary["someKey"] = "dictionary"
anyDictionary
//anyDictionary[0] : Dictionary는 순서나 인덱스가 없다. 키-밸류만 있을 뿐.
anyDictionary.removeValue(forKey: "anotherKey") //removeValue(forkey: 키명) : 해당 키의 벨류값 삭제
anyDictionary["someKey"] = nil //키 "somekey"에 해당되는 값을 없애주고 싶다 -> nil을 할당해도 됨
//스트링-스트링 형태의 빈 (축약 = [:]로 표현) Dictionary 생성
//let 선언이기때문에 값 변경 불가능
let emptyDictionary: [String: String] = [:]
let initializedDictionary: [String: String] = ["name": "sujilee", "gender": "female"]
//let someValue: String = initializedDictionary["name"] //Error! name의 벨류에 nil같은게 있으면 String인 someValue에 할당할 수 없다. 이런 불확실성때문에 에러가 뜸
Set
import Swift
//Set 컬렉션 타입은 축약문법이 없음
//빈(맨 뒤의 ()로 표현) Int Set 생성
var integerSet: Set<Int> = Set<Int>()
integerSet.insert(1) //insert() : Set에 요소를 추가하는 메소드
integerSet.insert(10)
integerSet.insert(100) //Set는 요소로 중복된 값이 있을 수 없음. 따라서 몇번을 동일하게 넣어도 한번만 추가됨
integerSet.insert(100)
integerSet.insert(100)
integerSet
integerSet.contains(100) //contains() : 해당 요소가 있는지 확인하는 메소드
integerSet.contains(99)
integerSet.remove(100)
integerSet.removeFirst()
integerSet
integerSet.count
//Set의 응용 -> 집합 연산에 매우 유용함
let setA: Set<Int> = [1, 2, 3, 4, 5]
let setB: Set<Int> = [3, 4, 5, 6, 7]
let union: Set<Int> = setA.union(setB) //setA와 setB의 합집합을 구하기 휘애 union() 메소드 사용
//Set는 자동정렬도 없고 인덱스도 없음
//let sortedUnion: Set<Int> = union.sorted() //Error! 왜? -> 배열 표현이기 때문임~
let sortedUnion: [Int] = union.sorted() // Int 배열에 정렬된 Set union을 담음<I
let intersection: Set<Int> = setA.intersection(setB) //intersection() : 교집합 구하는 메소드
let subtracting: Set<Int> = setA.subtracting(setB) //subtracting() : 차집합 구하는 메소드 (A - B)
06. 함수 기본
함수 선언 : func 키워드 사용
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 ...) -> 반환타입 {
함수 구현부
return 반환값
}
import Swift
//함수의 선언
func sum(a: Int, b: Int) -> Int {
return a + b
}
//함수의 호출
sum(a: 3, b: 5)
func printMyName(name: String) -> Void {
print(name)
}
//반환값 Void형은 그냥 표현 안해줘도 됨
func printYourName(name: String) {
print(name)
}
printMyName(name: "sujilee")
printYourName(name: "kchoi")
//매개변수가 없는 함수의 선언. 걍 괄호 안 비워주면 됨
func maximumIntegerValue() -> Int {
return Int.max
}
maximumIntegerValue()
//매개변수와 반환값이 없는 함수의 선언
func hello() -> Void { print("hello") }
func bye() { print("bye")}
hello()
bye()
07. 함수 고급
- 기본값을 갖는 매개변수 : 매개변수 목록 중 뒤쪽에 위치하는 것이 좋다
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 = 매개변수2기본값) -> 반환타입 { 함수 구현부 return 반환값 }
- 전달인자 레이블 : 함수 호출 시 매개변수의 역할을 좀 더 명확하게 하거나 함수 사용자의 입장에서 표현하고자 할때 사용
func 함수이름(전달인자 레이블 매개변수1이름: 매개변수1타입, 전달인자 레이블 매개변수2이름: 매개변수2타입) -> 반환타입{ 함수 구변후 return 반환값 }
- 가변 매개변수 : 전달받을 값의 개수를 알기 어려울때 사용. 함수당 하나만 허용
func 함수이름(매개변수1이름: 매개변수1타입, 전달인자 레이블 매개변수2이름: 매개변수2타입...) -> 반환타입 { 함수 구현부 return 반환값 }
- 저 "..." 이 중요한 거임!!
- 데이터 타입으로서의 함수
스위프트는 함수형 프로그래밍 패러다임을 갖고 있기 때문에 스위프트의 함수는 일급 객체임. 변수나 상수에도 저장될 수 있고 매개변수를 통해 전달될 수도 있다. 따라서 스위프트의 함수는 하나의 데이터 타입으로도 표현이 될 수 있음.
08. 조건문
- if-else조건문에는 항상 불 타입이 들어와야 함. 정수가 들어오면 안됨
- if 조건문의 소괄호는 생략 가능
- switch
switch 값 { case 패턴: 코드 default: 코드 }
- 사용예시
import Swift
let someInteger = 1000
if someInteger < 100 {
print("100 미만")
} else if someInteger > 100 {
print("100 초과")
} else {
print("100")
}
//디폴트 구문을 안써주면 에러 발생
//break 표현 안해도 브레이크 걸림
switch someInteger {
case 0:
print("zero")
case 1..<100:
print("1~99")
case 100:
print("100")
case 101...Int.max:
print("over 100")
default:
print("unknown")
}
//정수타입 외 대부분의 기본 타입 사용 가능
//콤마로 패턴 여러개 사용 가능
switch "sean" {
case "sujilee":
print("tada!")
case "kchoi":
print("cute boy")
fallthrough //break 안걸리고 쭉 내려옴
case "sean", "hejang":
print("cute girls")
default:
print("unknown")
}
9. 반복문
반복문은 컬렉션 타입과 특히 많이 쓰임
- for-in (마치 for-each)
for 아이템 in 아이템들 { 코드 }
- while
while 컨디션 { 코드 }
- whiled의 조건문에도 if 와 같이 꼭 불값이 들어와야함. c언어처럼 숫자값 넣어주면 컴파일 오류 발생
- repeat-while (마치 do-while. do가 쓰이지 않는건 do가 swift의 오류처리 부분에서 쓰이기 때문)
repeat { 코드 } while 조건
10. 옵셔널
- 옵셔널 : 스위프트 핵심개념!
- 왜 필요할까? -> nil의 가능성을 명시적으로 표현
- 전달받은 값이 옵셔널이 아니라면 nil체크를 할 필요없이 안심하고 사용할 수 있겠지?
- 애초에 옵셔널로 선언하지 않는 파라미터는 인자로 못보냄