iOS 프로그래밍 4주차
복습
데이터 타입(자료형, data type)
var myNumber : Int = 10
위와 같이 초깃값이 있을 경우에는 컴파일러가 타입 추론(type inference)를 하므로 데이터 타입을 명시할 필요 없음
'=' 양쪽에 일관된 공백이 있어야 함
Bool, Character, Int, Float, Double, String, Void
정수 데이터 타입: Int
정수(소수점이 없는 수)를 저장하는데 사용
애플은 특정 크기의 데이터 타입보다 Int 데이터 타입을 권장
부동 소수점 데이터 타입: Double(64비트) vs Float(32비트)
소수점이 있는 숫자
Double형이 기본
부울 데이터 타입: Bool
참 또는 거짓(1 또는 0) 조건을 처리할 데이터 타입
Boolean 데이터 타입을 처리하기 위하여 두 개의 불리언 상수 값(true/false) 사용
문자 데이터 타입: Character
문자, 숫자, 문장 부호, 심볼 같은 유니코드 문자 하나를 지정
var 변수명: Character = "초기값"
주의: 초기값은 작은 따옴표가 아니고 큰 따옴표
문자열 데이터 타입: String
단어나 문장을 구성하는 일련의 문자
저장, 검색, 비교, 문자열 연결, 수정 등의 기능 포함
문자열 보간(string interpolation)을 사용하여 문자열과 변수, 상수, 표현식, 함수 호출의 조합으로 만들 수도 있음
변수: var
기본적으로 변수는 프로그램에서 사용될 데이터를 저장하기 위한 메모리 공간
변수에 할당된 값은 변경 가능
상수: let
상수는 데이터 값을 저장하기 위해 메모리 내 공간을 제공한다는 점에서 변수와 비슷
어떤 값이 한번 할당되면 이후에 변경될 수 없음
코드 내에서 반복적으로 사용되는 값이 있을 경우에 유용
코드 내에서 반복적으로 사용되는 특정 값을 매번 사용하는 것보다, 그 값을 상수에 할당한 다음 코드 내에서 참조하면 코드 읽기가 더 쉬워짐
변수나 상수 명은 영문자, 숫자, Unicode(이모티콘, 중국어, 한글 등)도 가능
애플은 코드의 효율성과 실행 성능을 높이기 위해서 변수(var)보다는 상수(let)를 사용하라고 권장
타입 어노테이션과 타입 추론
상수와 변수의 타입을 식별하는 방법은 두가지
1. 변수 또는 상수가 코드 내에서 선언되는 시점에 타입 어노테이션(type annotation)을 사용하는 것
2. 선언부에 타입 어노테이션이 없으면 스위프트 컴파일러는 상수 또는 변수의 타입을 식별하기 위해 타입 추론(type inference) 사용
상수의 값 할당
상수를 선언할 때도 타입 어노테이션을 사용하면 나중에 코드에서 값을 할당할 수 있음
튜플(Tuple)
여러 값을 하나의 개체에 일시적으로 묶는 방법
let myTuple = (10, 12.1, "Hi")
튜플의 요소들은 여러 다른 방법들을 사용하여 접근할 수 있음
특정 튜플 값은 인덱스 위치를 참조하면 간단하게 접근(맨 첫 번째 값은 인덱스 0)
단 한 줄의 코드로 튜플의 모든 값을 추출하여 변수 또는 상수에 할당
var (myInt, _, myString) = myTuple // 12.1 무시
튜플의 값을 선택적으로 추출할 수 있으며, 무시하고 싶은 값에 밑줄을 사용하면 그 값은 무시
myTuple = (count: 10, length: 12.1, message: "Hi")
튜플을 생성할 때 각 값에 이름을 할당할 수도 있음
튜플에 저장된 값에 할당된 이름은 각 값을 참조하는데 사용
튜플의 가장 강력한 점은 함수에서 여러 값들을 한 번에 반환하는 것
Void는 빈 튜플
대입 연산자
오른쪽 피연산자는 주로 산술식 또는 논리식을 수행하는 표현식이며, 그 결과는 왼쪽 피연산자인 변수나 상수에 할당
산술연산자
-(단항): 변수 또는 표현식의 값을 음수로 만듦
* : 곱셈
/ : 나눗셈
+ : 덧셈
- : 뺄셈
% : 나머지 연산
증가 연산자와 감소 연산자
단항 연산자
x = x + 1 // x 변수의 값을 1 증가시킴
x = x - 1 // x 변수의 값을 1 감소시킴
비교 연산자
비교의 결과로 불리언(Boolean) 값을 반환
불리언 논리 연산자
NOT(!), AND(&&), OR(||), XOR(^)
범위 연산자
x...y // x에서 시작하여 y로 끝나는 범위에 포함된 숫자
닫힌 범위 연산자
x..<y // x부터 시작하여 y가 포함되지 않는 모든 숫자
반 열린 범위 연산자
let names = ["A", "B", "c", "D"]
for name in names[2...] {
}
One-Sided Ranges
삼항 연산자
비교 연산을 빠르게 하기 위해 삼항 연산자를 지원
[조건] ? [참 표현식] : [거짓 표현식]
nil-coalescing operator(nil 병합 연산자) ??
옵셔널 변수 ?? nil일 때 할당되는 값
옵셔널 변수의 값이 nil이면 ?? 다음 값으로 할당됨
옵셔널 변수의 값이 nil이 아니면 언래핑된 값이 나옴
클래스 vs 객체 vs 인스턴스
for - in 반복문
컬렉션 또는 숫자 범위 내에 있는 목록을 반복
for 상수명 in 컬렉션 또는 범위 {
// 실행될 코드
}
'상수명'은 반복문이 돌면서 컬렉션 또는 범위에서 가져온 항목을 담게 될 상수
for문 다음의 실행 코드가 한 줄이라도 괄호({})를 필수적으로 사용
_로 참조체 생략 가능
배열의 항목 접근
let names = ["A", "B", "c", "D"]
for name in names{
print(name)
}
dictionary의 항목 접근
let numberOfLegs = ["Spider":8, "Ant":6, "Dog":4]
for (animalName, letCount) in numberOfLegs {
print("\(animalName)s have \(legCount) legs")
}
while 반복문
지정된 조건을 만족할 때까지 작업을 반복
while 조건식 {
// 반복 코드
}
repeat ~ while 반복문
repeat ... while 반복문의 몸체는 적어도 한번은 실행
repeat {
//
} while 조건식
반복문에서 빠져나오기(break)
반복문이 완료되는 조건 전에 반복문을 빠져나오기
현재의 반복문에서 빠져나와서 반복문 바로 다음에 있는 코드를 실행
coutinue 문
반복문에서 continue문 이후의 모든 코드를 건너뛰고 반복문의 상단 시작 위치로 돌아감
if 문
if 불리언 표현식 {
//
}
if문 다음의 실행 코드가 한 줄이라도 괄호({})를 필수적으로 사용
기본적으로 '불리언 표현식'이 참으로 판단되면 중괄호로 감싼 코드 실행, 거짓이면 중괄호로 감싼 코드 건너 뜀
if문 조건에서 콤마:조건나열(condition-list)
guard 문(조건식이 거짓이면 실행)
표현식이 거짓(false)로 판단될 경우에 수행될 else 절을 반드시 포함해야함
guard <불리언 표현식> else {
// 표현식이 거짓일 경우에 실행될 코드
<코드 블럭을 빠져 나갈 구문>
}
// 표현식이 참일 경우에 실행되는 코드
기본적으로 특정 조건에 맞지 않을 경우에 현재의 함수나 반복문에서 빠져 나갈 수 있도록 하는 '조기 출구(early exit)' 전략을 제공
switch - case 문
switch 표현식
{
case match1:
구문
case match2:
구문
case match3, match4:
구문
default:
구문
}
주의: 각 case문 마지막에 break가 자동으로 들어 있음
Where: 조건을 추가
fallthrough
Int형 vs Optional Int형
10: Int
Int형 값을 저장
var x : Int = 10
Optional(10)
Int?
Int!
Int 형 값을 저장 or 값이 없음(nil)
var y : Int? = 10
var z : Int!
옵셔널 타입(매우 중요)
옵셔널 타입 강제 언래핑(forced unwrapping) 1
forced unwrapping
옵셔널 강제 언래핑(forced unwrapping) 2: optional binding
optional binding
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")
}
// 출력
// Optional(10) 10
// nil
if let x = x 라고 써도 됨
Swift 5.7부터는 if let x라고 써도 됨: short form of if-let to the Optional Binding
두 가지 Optional 형: Int? vs Int!
함수와 메서드(method)
함수
메서드
특정 클래스, 구조체, 열거형 내의 함수
함수를 클래스 내에 선언하면 메서드라 부름
함수를 선언하는 방법
func <함수명>(<매개변수 이름>:<매개변수 타입>, <매개변수 이름>:<매개변수 타입>,...) -> <반환값 타입> {
// 함수 코드
}
func sayHello() -> Void { // 리턴값 없으면( -> Void) 지정하지 않아도 됨
print("Hello")
}
sayHello() // 함수 호출
매개변수를 받지 않으며 결과를 반환하지도 않고 오직 메시지만 출력
반환하지 않으면(Void) 반환값 타입(Void)과 -> 는 생략 가능
func messge(name: String, age: Int) -> String {
return("\(name) \(age)")
}
하나의 문자열과 하나의 정수를 매개변수로 받아서 문자열을 반환
C언어에서 Swift 함수 변경
int add(int x, int y) {
return(x+y)
}
add(10, 20);
C언어
func add(x: Int, y: Int) -> Int {
return(x+y)
}
var z = add(x:10, y:20)
print(z) // 30
Swift
add함수의 자료형: (Int, Int) -> Int
func sayHello() { // 리턴값 없으면( -> Void) 지정하지 않아도 됨
print("Hello")
}
sayHello() // 함수 호출
print(type(of: sayHello())) // () -> ()
내부 매개변수(parameter name) 이름과 외부 매개변수(argument label) 이름
func add(first x: Int, second y: Int) -> Int {
//외부 내부:자료형, 외부 내부:자료형 -> 리턴형
return(x+y) // 함수 정의할 때는 내부 매개변수명을 사용
}
var z = add(first:10, second:20)
// 함수 호출할 때는 외부 매개변수명을 사용
print(z)
외부 매개변수명 생략하면 내부 매개변수명이 외부 매개변수명까지 겸함
Swift 함수 실습
func add(x: Int, y: Int) -> Int {
return(x+y)
}
print(add(x: 10, y: 20))
func add(first x: Int, second y: Int) -> Int {
return(x+y)
}
print(add(first: 10, second: 20))
func add(_ x: Int, _ y: Int) -> Int { // 추천하지 않음
return(x+y)
}
print(add(10, 20))
func add(_ x: Int, with y: Int) -> Int { // 제일 많이 씀
return(x+y)
}
print(add(10, with:20))
함수명: #function 리터럴(literal)
함수명(외부매개변수명:외부매개변수명: ...)
#function 리터럴을 사용해 얻을 수 있음
func add(x: Int, y: Int) -> Int {
print(#function) // add(x:y:)
return(x+y)
}
print(add(x: 10, y: 20))
func add(first x: Int, second y: Int) -> Int {
print(#function) // add(first:second:)
return(x+y)
}
print(add(first: 10, second: 20))
func add(_ x: Int, _ y: Int) -> Int {
print(#function) // add(_:_:)
return(x+y)
}
print(add(10, 20))
func add(_ x: Int, with y: Int) -> Int {
print(#function) // add(_:with:)
return(x+y)
}
print(add(10, with:20))
함수 실습 소스
1
func multiplyByTen(value: Int?) {
guard let number = value else { // 조건식이 거짓(nil)일 때 else 블록 사용
print("nil")
return
}
print(number * 10)
}
multiplyByTen(value: 3)
// 출력: 30, value에 3이 전달돼 print(number * 10)이 실행되어 10이 출력
multiplyByTen(value: nil)
// 출력: nil, value에 nil이 전달돼 guard문이 충족되지 않아 else 블록 사용
multiplyByTen(value: 10)
// 출력: 100, value에 10이 전달돼 print(number * 10)이 실행되어 10이 출력
2
func printName(firstName:String, lastName:String?) {
// if let
if let lName = lastName { // lastName이 nil이 아니면
print(lName, firstName)
}
else {
print("성이 없네요")
}
// guard let
guard let lName = lastName else { // lastName이 nil이면
print("성이 없네요!")
return // early exit
}
print(lName, firstName)
}
printName(firstName: "길동", lastName: "홍")
// (if let)홍 길동: lastName이 홍이 전달돼 if문 실행
// (guard let)홍 길동: lastName이 홍이 전달돼 print(lName, firstName) 출력
printName(firstName: "길동", lastName: nil)
// (if let)성이 없네요: lastName이 nil이 전달돼 else문 실행
// (guard let)성이 없네요!: lastName이 nil전달돼 print("성이 없네요!") 출력
3
func sayHello(count: Int, name: String = "길동") -> String {
return ("\(name), 너의 번호는 \(count)")
}
print(sayHello(count: 202312005))
// 길동, 너의 번호는 202312005
// name: 기본값이 "길동"으로 설정. 호출 시 값을 전달하지 않으면 기본값 "길동"이 사용됨
4
func converter(length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
let yards = length * 0.0277778
let centimeters = length * 2.54
let meters = length * 0.0254
return (yards, centimeters, meters)
}
var lengthTuple = converter(length: 10)
print(lengthTuple) // (yards: 0.277778, centimeters: 25.4, meters: 0.254)
print(lengthTuple.yards) // 0.277778, 10 * 0.0277778
print(lengthTuple.centimeters) // 25.4, 10 * 2.54
print(lengthTuple.meters) // 0.254, 10 * 0.0254
5
func sss(x: Int, y: Int) -> (sum: Int, sub: Int, div: Double) {
let sum = x + y
let sub = x - y
let div = Double(x) / Double(y) // 같은 자료형만 연산 가능
return (sum, sub, div)
}
var result = sss(x: 10, y: 3)
print(result.sum) // 13, 10 + 3
print(result.sub) // 7, 10 - 3
print(result.div) // 3.3333333333333335, 10 / 3
6
func displayStrings(strings: String...) {
for string in strings { // 전달받은 문자열을 하나씩 돌며 print(string)을 통해 출력
print(string)
}
}
displayStrings(strings: "일", "이", "삼", "사")
// 일
// 이
// 삼
// 사
displayStrings(strings: "one", "two")
// one
// two
7
var myValue = 10
func doubleValue(value: inout Int) -> Int {
value += value // 함수 내부에서 value에 자신의 값을 더해 두 배로 만들고 이 값을 반환
return(value)
}
print(myValue) // 10
print(doubleValue(value: &myValue))
// 20, doubleValue 함수를 호출하면서 &myValue를 전달. 함수 내부에서 value는 두 배가 되어 20이 됨. 이 값이 반환
print(myValue) // 10
출처: iOS 프로그래밍 기초 강의 자료