본문 바로가기

MOBILE/ios

[swift] 데이터 타입부터 함수까지 알아보기

swift 언어의 특징 세개를 합쳐서 SEF 으로 말할 수 있음 SAFE, EXPRESSIVE, FAST

여태까지 공부했을 때 safe는 인정하겠는데 expressive는 뭐 그렇다는데? 라고만 말할 수 있겠다.. 딱히 느껴지지 않음 자바스크립트를 별로 좋아하지 않았기 때문일까?

어쨌든 swift 기본 문법을 정리해서 ios 개발 가보자고


1. 변수와 상수

어느 프로그래밍 언어를 배우든지 가장 처음에 하는 것은 변수 선언과 데이터 타입이다.

변수(variable): 값이 변할 수 있음

상수(constant): 값이 변하지 않음. 고정된 값

 

상수는 let 키워드를 쓰고

변수는 var 키워드를 쓴다.

변수나 상수 이름을 써주고 반드시 콜론을 쓰고 띄워써야함 그 뒤에 데이터 타입을 써주면 된다.

// (let/var) 변수명: 데이터타입 = 초기화값

let constant: Int = 10
var variable: Int = 10

variable = 20 // 가능
constant = 20 // 불가능

따라서 변수와 달리 상수로 선언했다면 값을 변경하는 것이 불가능하다.

 

2. swift의 기본 데이터 타입

swift는 다른 언어와 달리 자료형의 구분이 엄격한 편이다. 아마 이런 부분이 SAFE를 올려주는 요인 중 하나인 듯 하다.

기본적인 데이터 타입으로는 Bool, Int, Float, Double, Character, String 이 있다

 

// Bool: c와 달리 0, 1로 t/f를 표현할 수 없고 true or false만 가능하다.
var BoolType: Bool = true

// Int: 정수형
var IntType: Int = 200

// UInt: unsigned int 즉 부호 없는 정수다. 양의 정수를 의미
var UintType: UInt = 200

// Float: float 타입
var FloatType: Float = 1.2345

// Double: double 타입
var DoubleType: Double = 678.9

// Character: char 타입이다. 한 글자이다. 여기서 유니코드면 다 가능하다. 즉 이모티콘 한개도 char이다.
var CharType: Character = "d"

// String: 하나 이상의 문자열이다.
var StringType: String = "String type"

// Any: 모든 데이터 타입을 가리킴
var AnyType: Any = "it can be anything"
AnyType = 200
AnyType = 3.12345

// AnyObject: 모든 클래스 타입을 지칭하는 프로토콜
class AnyClass {}
var AnyObjectClass: AnyObject = AnyClass()

 

여기서 주목해야할 점은 Any, AnyObject, nil이다. 다른 언어에는 없는 swift에만 있는 문법이다.

 

Any 는 모든 데이터 타입을 의미한다. 따라서 Any로 선언한 변수에는 다양한 데이터 타입을 넣을 수 있다. 근데 여기서 문제

다음과 같이 코드를 작성할 시 오류가 날까?

var AnyVar: Any = "test"
AnyVar = 123.45

var DoubleVar: Double = AnyVar

Any로 선언한 변수에 실수를 넣고 double 타입의 변수에 이를 넣어줬다.

 

별 문제가 없어보이지만 swift에서는 이를 오류로 처리한다.

왜냐면 현재 AnyVar의 변수에 Double 타입의 실수가 들어갔다고 해도 애초에 이 변수는 선언할 때 부터 Any 타입이었기 때문에 데이터 타입이 달라 컴파일 오류가 난다.

 

또 swift에서 눈여겨 볼 점은 nil이다.

null과 비슷한데 다르다. 사실 objective-c는 객체 지향 언어라서 null과 nill 둘 다 있었는데 swift는 함수 지향이라서 둘을 구분할 필요가 없어졌다. 따라서 nil만 남음

null이 포인터의 부재를 의미하는 데에 비해, nil은 그냥 값의 부재이다. just no value.

 

3. Array, Dictionary, Set

Array: 인덱스 즉 순서를 가진 리스트 형태

Dictionary: (key, value) 의 쌍으로 이루어진 형태

Set: 수학적 집합의 의미와 동일. 순서 없고 중복도 없다.

Array

다양한 방식으로 선언이 가능하다.

var ArrayType: Array<Int> = Array<Int>()
var ArrayType: Array<Int> = []
var ArrayType: [Int] = Array<Int>()
var ArrayType: [Int] = [Int]()
var ArrayType: [Int] = []

배열이니까 이 클래스의 메서드들을 사용할 수 있다.

대표적으로 .append .remove .removeLast .removeAll .count 등이 있음

ArrayType.append(1)
ArrayType.append(2)
ArrayType.append(3)

ArrayType.contains(1) // true가 나온다.
ArrayType.contains(5) // false가 나온다.

ArrayType[0] = 4 // [4, 2, 3]

ArrayType.remove(at: 0) // 0번 인덱스의 값을 지워줌
ArrayType.removeLast()  // 배열의 마지막 값을 지워줌
ArrayType.removeAll() // 전부 지워줌
ArrayType.count // 배열의 값의 개수 반환함

 

Dictionary

dictionary도 array와 마찬가지로 다양한 방법으로 선언 가능하다.

var DicType: Dictionary<String, Any> = Dictionary<String, Any>()

<데이터 타입, 데이터 타입> 으로 key의 데이터 타입과 그에 해당하는 value의 데이터 타입을 미리 지정해준다.

 

DicType["first"] = 100
DicType["second"] = 23.5
DicType["third"] = "value"

DicType.removeValue(forKey: "first") // ["second":23.5, "third":"value"]
DicType["second"] = nil // ["third":"value"]

dictionary 하나의 값을 지울 때는 nil을 넣거나 removeValue를 하면 된다.

근데 만약에 키 값을 변경하고 싶다면? 그냥 다른 변수에 그 값을 넣고 dictionary에서 지운 후, 키 값을 변경한 데이터를 새로 dictionary에 추가하는 방법을 쓰면 됨

근데 dictionary는 순서가 없어서 그런지 print로 출력할 때도 순서가 없이 지 맘대로 출력된다. 순서를 원한다면 sort를 쓰면 됨

 

Set

set은 array, dictionary와 달리 선언 방법이 한가지 뿐이다.

var SetType: Set<Int> = Set<Int>()

마찬가지로 다양한 메서드 사용 가능한.

SetType.insert(1)
SetType.insert(2)
SetType.insert(3)

SetType.contains(1) // true
SetType.contains(100) // false

SetType.remove(1) // 원소 1을 지워줌 [2, 3]
SetType.removeFirst() // 첫번째 원소를 지워줌 [3]
SetType.count // 원소의 개수를 셈

 

집합이니까 당연히 집합의 연산들이 있다.

합집합, 차집합, 교집합 모두 연산 가능하다.

이때 집합의 연산을 하면 자동으로 중복을 제거해준다.

let setA: Set<Int> = [1,2,3,4,5]
let setB: Set<Int> = [5,6,7,8,9]

// 합집합
let union: Set<Int> = setA.union(setB)

// 교집합
let intersection: Set<Int> = setA.intersection(setB)

// 차집합
let subtraction: Set<Int> = setA.subtracting(setB)

// 정렬
let sortedUnion: [Int] = union.sorted()

4. 함수

swift의 기본 함수 형태는 다음과 같다.

func 함수명(인자 레이블 인자 변수명: 데이터 타입 ...) -> 반환 타입 {
	동작
}

 

인자 레이블은 어떤 값이 파라미터에 들어가야 하는지 명시적으로 보여줄 때 사용한다. 이를 생략하면 인자 변수명과 같도록 설정된다.

만약 인자 레이블을 사용하고 싶지 않을 경우 _ 키워드를 쓴다.

 

함수를 호출할 때 인자 레이블까지 함수의 이름으로 묶어서 호출할 수 있다. 따라서 같은 함수 명도 인자 레이블에 따라 다른 함수의 기능으로 함께 쓸 수 있다.

 

 

덧셈 함수로 예를 들어서 설명해보자

func sum(a: Int, b: Int) -> Int {
	return a + b
}

func sum(inputA: Int = 0, inputB: Int = 0 -> Int {
	return inputA + inputB
}

이런식으로 반환 타입이 정수형이라면 함수 반환 타입도 Int, 반환 값이 없다면 Void 를 써준다.

파라미터 변수에 값을 넣어서 초기화를 할 수도 있다.

위 함수를 호출할 때는

 

sum(a: 4, b: 5)
sum(a:b:)(4, 5)

sum(inputA: 4, inputB: 5)
sum(inputA:inputB)(4, 5)
sum()

이렇게 다양한 형태로 호출 가능하다.

마지막 호출에서는 파라미터에 값을 넣지 않았지만 두번째 함수의 inputA와 inputB가 이미 0으로 초기화 되어 있기 때문에 0을 리턴하게 된다. 이는 c에서의 사용법과 같다.

 

다음 예시를 보자

func sum(first a: Int, second b: Int) -> Void {
	print(a + b)
}

func sum(_ a : Int, _ b: Int) -> Void {
	print(a + b)
}

인자 레이블을 생략한 위쪽의 함수와 달리 이쪽의 함수들은 인자 레이블이 있다.

따라서 호출 방법 또한 달라진다.

 

let inputA: Int = 4
let inputB: Int = 5

sum(first: 4, second: 5)
sum(first:second:)(4, 5)
sum(first:second:)(inputA, inputB)

sum(4, 5)
sum(_:_:)(4, 5)
sum(inputA, inputB)

 

_ 키워드를 사용하게 되면 인자 레이블을 생략하기 때문에 파라미터에 바로 값이나 변수를 쓸 수 있다.

 

 

데이터 타입으로서 함수를 사용하기

변수를 만들어서 함수를 대입할 수 있다.

var ExFunc: (Int, Int) -> Void = sum(first:second:)
ExFunc(4, 5)

ExFunc = sum(_:_:)
ExFunc(4, 5)

 

이때 타입이 같은 다른 함수를 다시 대입할 수도 있다.

따라서 다음과 같은 형태로도 사용 가능하다.

 

func ExFunc(function: (Int, Int) -> Void){
    function(5,5)
}
ExFunc(function: sum(_:_:))
ExFunc(function: sum(first:second:))

 

이렇게 함수를 데이터 타입 자체로 사용하는 것도 가능하다.