Swift 1. 기초 문법

박건희·2022년 3월 3일
0

Swift

목록 보기
1/10

들어가기에 앞서

Swift를 공부하기에 앞서 여러 유튜브 강의와 공식 도큐먼트 등을 찾아보았다.

그 중 boost course에서 나오는 야곰님의 Swift 강의가 가장 좋다고 느꼈고 그 이유는 아래와 같다:

  • 프로그래밍에 대한 기본적인 이해가 있다는 전제 하에 빠르고 쉽게 내용을 진행한다.
  • 목소리가 좋다(?)

Swift를 배우며 내용을 문서화 하기 위해 쓰는 개인적인 블로그 글이지만, 모든 내용의 base에는 부스트 코스에 나오는 야곰님의 강의를 바탕으로 쓰는 것이며 문제가 발생할 경우 모든 글을 지울 것이다

Reference
https://www.boostcourse.org/mo122/joinLectures/38564


이름 짓기 convention

  • Function,. Method, variable 등은 lower camel case
  • Type, Class 등은 Upper camel case

swift는 대소문자를 구별하는 문법임을 유의!

콘솔에 로그를 찍는 방법

print 는 단순 문자열 출력, dump는 인스턴스의 자세한 설명까지 콘솔 로그에 출력하는 함수다

String안에 다른 변수를 넣는 법

\() in Swift == ${} in Dart

(e.g. print(“ 안녕하세요 저는 \(name)입니다“) )

변수/상수 선언

싱수의 경우 let name: type = value
변수 var name: type = value

White space에 민감한 문법이기 때문에 반드시 변수나 상수의 이름 바로 뒤에 :을 붙이고 한 칸 띄운 뒤 type 선언

일단 변수나 상수명만 선언해두고 lazy하게 값을 할당하려는 경우 반드시 type을 명시 해야 한다. (dart도 하다못해 dynamic name; var name; 이렇게 하듯이)
당연히 상수는 lazy declaration을 할 때 단 한번만 값을 할당할 수 있다.

Primitive data type

Bool, Int, Float, Double, Character 등의 값들은 익숙하니까 건너뛰고..

UInt는 unsigned integer다. 당연히 음수 할당하려고 하면 컴파일 에러가 난다.
신기한 부분은 C언어보다도 implicit type conversion을 허용 안해준다. Float to int, int to Bool 도 안될 뿐더러. Float <-> double까지도 안된다.

Character type과 String type 모두 큰 따옴표 (“”)를 사용한다. 이런 건 대충해도 됐던 Dart에서의 안이한 습관을 이어가지 말자.
신기한 것은 Character type은 Unicode에서 가능한 모든 character가 되기 때문에 다양한 언어 뿐 아니라 이모지까지 된다! (왕신기)

당연히 String type 역시 이모지를 중간에 넣을 수 있다. Character <-> String 역시도 implicit type casting은 안된다.
그냥 컴파일러가 암시적으로 타입을 바꿔주는 모든 행위가 금지라고 생각하는 것이 편하다!

dynamic type: Any, AnyObject

어떤 타입도 담을 수 있는 타입으로 Any, AnyObject 라는 타입이 있다

var example: Any = 100
example = “스트링도 되지롱”
example = 123.45

이런 식으로 Any type으로 선언된 변수는 어떤 값도 담을 수 있다. 다만 위 예시에서 example의 값을
Primitive type으로 선언된 다른 변수나 상수에 넣으려고 하면 에러가 난다.

AnyObject도 Any와 비슷하지만, class instance만 넣을수 있다!

var example2: AnyOjbect = Persion(); 은 되지만 example2 = 123.45 은 안된다.

null을 의미하는 nil

nil은 비어있음을 의미하기 때문에 Any나 AnyObject에도 할당할 수 없다.
위 예시에서 example1 = nil 혹은 example2 = nil을 한다면 둘다 컴파일 에러가 난다.

컬렉션 타입 Array, Dictionary, Set

다시 한번 collection type들의 정의에 대해 간단히 짚고 넘어가자

  • Array : 순서가 있는 리스트 컬렉션. 즉 index를 통해서 search 하는데 유리하다.
  • Dictionary: {key, value} pair로 이뤄진 컬렉션. Hash map과 비슷하다. index를 통해서가 아니라 key값을 통해서 search를 하는 것에 유리하다
  • Set: 리스트안의 모든 멤버가 unique 하다는 제한 사항을 가지고 있는 컬렉션.
Array<Int>[Int]로 줄여서 표현할 수 있다. (e.g. var int: Array[Int] = [Int]() )
var integers: Array<Int> = Array<Int>()

// 위와 동일한 표현
// var integers: Array<Int> = [Int]()
// var integers: Array<Int> = []
// var integers: [Int] = Array<Int>()
// var integers: [Int] = [Int]()
// var integers: [Int] = []
// var integers = [Int]()

당연히 let을 사용해서 array 선언하면 바꿀 수가 없고, append, removeAt 등의 메소드도 사용 불가능

var dict: Dictionary<String, Any> = [String: Any]() 

오이오이 딱 봐도 Map 타입 같아 보이는 익숙한 이 친구는 뭐냐구~ json 파일받는 용인 것 같은 건 기분 탓이냐고~

// var anyDictionary: Dictionary <String, Any> = Dictionary<String, Any>()
// var anyDictionary: Dictionary <String, Any> = [:]
// var anyDictionary: [String: Any] = Dictionary<String, Any>()
// var anyDictionary: [String: Any] = [String: Any]()
// var anyDictionary: [String: Any] = [:]
// var anyDictionary = [String: Any]()

Dictionary 에서 특정 pair를 지우기 위해선 dict.removeValue(forKey: “키 이름”) 을 해주거나 dict[“키 이름”) = nil 을 선언해주면 된다.

set는 선언할 때 따로 줄임말이 없고 var setA: Set<Int> = Set<Int>() 이런 식으로만 선언해줘야 한다.
다만 집합의 특성을 가지고 있기 때문에 집합 전용 연산을 할 수 있다.

  • setA.union(setB) <- 합집합
  • setA.intersection(setB) <- 교집합
  • setA.subtracting(setB) <- 차집합

함수 선언

Swift도 다른 언어와 마찬가지로 function name, function body, parameter, parameter type, return type이 필요하고 그 형식은 아래와 같다.

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

만약 반환값이 없다면 return type에 Void를 넣어주거나 아예 -> returnType 부분을 생략해도 된다.

함수 호출

다른 언어들과 다르게, 선언에서 표기한 매개변수들에 값을 적어주는 방식으로 호출한다. 예를 들어 위 함수 선언의 예제에서 sum이란 함수의 매개 변수가 a와 b 였으니, 이를 그대로 사용해서

sum(a: 3, b: 5)

이런 식으로 호출해야 한다.

매개변수의 default value를 설정하기

func greeting(friend: String, me: String = "yagom") {
    print("Hello \(friend)! I'm \(me)")
}

위 예제처럼 default value를 설정하고 싶은 parameter에
parameterName: parameterType = defaultValue를 선언하면 된다.
기본 값이 설정된 파라매터에 값을 넣으면 그 값을 쓰고, 값을 안넣으면 기본 값을 쓴다.

전달인자 레이블 (parameter labels)

파라매터에 매개변수의 역할을 알기 쉽게 label을 붙일 때 사용한다.
사용성과 readability를 높이기 위해 사용되는 것이지, 기능적으로 다른 건 없는 것 같다.

func greeting(to friend: String, from me: String) {
    print("Hello \(friend)! I'm \(me)")
}

greeting(to: "john", from: "sydney") 

⭐️개신박한 기능 : 가변 매개변수 (variadic parameter)

함수마다 딱 하나의 가변 매개변수라는 것을 가질 수 있다.

전달 받을 값의 개수가 확실하지 않을 때 사용한다.
보통 이런 문제를 해결하기 위해서 List나 array를 사용하지만,
swift에선 굳이 그럴 필요가 없다.

func printNumbers(_ numbers: Int...) {
    for number in numbers {
        print(number)
    }
}

printNumbers(0, 1, 2, 3, 4, 5)

/*결과
0
1
2
3
4
5
*/

다만 variadic parameter에 아무 값도 안넣거나 nil을 넣으면 오히려 에러가 생기므로, 차라리 해당 변수를 아예 빼야 한다.

printNumbers(numbers: 0, 1, 2, 3, 4, 5) //Good
printNumbers(numbers: ) //Error
printNumbers(numbers: nil) //Error
printNumbers() //Good

Swift의 함수는 데이터 타입이다!

Swift의 함수는 객체 형태로 저장되기 때문에 일종의 data type처럼 사용 가능하다. 따라서

  • 변수나 상수에 저장이 가능하다
  • 파라매터로도 사용이 가능하다
var someFunction: (String, String) -> Void = greeting(to:from:)

someFunction("john", "sydney") 

동일한 파라매터와 리턴 타입을 가진 다른 function으로 someFunction을 다시 할당할 수 있지만, 타입이 다른 함수는 할당할 수 없다.

func runAnother(function: (String, String) -> Void) {
    function("jenny", "mike")
}

// Hello jenny! I'm mike
runAnother(function: greeting(friend:me:))

// Hello jenny! I'm mike
runAnother(function: someFunction)

위와 같이 함수 안의 파라매터로 함수를 넣어줄 수도 있다!

다중 값을 반환하는 함수

func minMax(array: [Int]) -> (min: Int, max: Int) {
    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)
}

let bounds = minMax([8, -6, 2, 109, 3, 71])
println("min is \(bounds.min) and max is \(bounds.max)")
// prints "min is -6 and max is 109"

하나 이상의 값을 반환하는 함수를 만들 땐 tuple로 반환 타입을 만들면 된다.

profile
CJ ENM iOS 주니어 개발자

2개의 댓글

comment-user-thumbnail
2022년 3월 3일

친구 노트북 뺏어서 작성된 건가요?

1개의 답글