서브스크립트

- 클래스, 구조체, 열거형에는 컬렉션, 리스트, 시퀀스 등에서 접근할 수 있는 서브스크립트를 정의할 수 있다

- 별도의 설정자, 접근자 등의 메서드를 구현하지 않아도 인덱스를 통해 값을 설정하거나 가져올 수 있다

ex) Dictionary에서 dictionary[key] -> 이것이 서브스크립트 다

 

문법

subscript(index: Int) -> Int{
	get{
    	//getter
    }
    set(newValue){
    	//setter
    }
}

 

구현

struct Student{
	//...
}

class School{
	var students: [Student] = []
    
    func addStudent()...
    ...
    
    //School Class 내부에 있는 값들 혹은 그 값들의 조합으로도 반환 가능
    subscript(index: Int) -> Student?{
    	if index < self.number{
        	return self.students[index]
        }
        return nil
    }
}

 

복수개의 서브스크립트

- 하나의 타입이 여러개의 서브스크립트를 가징 수 있다

- 매개변수 타입과 개수, 반환 타입이 다르면 가능하다

- 서브스크립트에도 다형성이 가능

 

타입 서브스크립트

- subscript 앞에 static/class 키워드를 붙여준다

 

 

모나드

- 스위프트는 함수형 프로그래밍 패러다임에서 파생된 기능이나 개념이 종종 등장한다.

- 단순히 고차함수를 사용, 함수를 일급 객체로 사용, 재귀함수를 사용한 로직을 구현하는 등의 특정 기능에 국한되는 것은 아니지만, 모나드를 익혀두면 더 깊이 있는 함수형 프로그래밍을 이해할 수 있다

 

모나드의 조건

  • 타입을 인자로 받는 타입 (특정 타입의 값을 포장)
  • 특정 타입의 값을 포장한 것을 반환하는 함수(메서드)가 존재
  • 포장된 값을 변환하여 같은 형태로 포장하는 함수(메서드)가 존재
  • 옵셔널 = 기본적인 모나드

FlatMap vs Map

let optionals: [Int?] = [1,2,nil,5]

let mapped: [Int?] = optionals.map{ $0 } // [Optional(1),Optional(2),nil,Optional(5)]
let compactMapped: [Int] = optionals.compactMap{ $0 } // compactMap = flatMap
//[1,2,5]

//compactMap 은 컨테이너 내의 컨테이너까지 벗기는? 것을 볼 수 있다.

맵, 필터, 리듀스

 

Map

  • 자신을 호출할 때, 매개변수로 전달된 함수를 실행하여 그 결과를 반환
  • Sequence, Collection 프로토콜을 따르거나 옵셔널은 모두 사용 가능
  • 사용 시, 컨테이너가 담고 있던 각각의 값을 매개변수를 통해 적용 후, 다시 컨테이너로 포장하여 반환
  • 이전에 알아본 for - in 구문과 크게 다르지 않다
  • B.U.T. 코드 재사용 측면, 컴파일러 최적화 측면에서 성능 차이 있다
  • 다중 쓰레드 환경에서도 예측지 못한 결과의 부작용을 방지 가능 -> (Thread-Safe ? )
let numbers = [1,2,3,4,5]
var doubledNum = []
var stringNum = []

//for - in
for number in numbers{
	doubledNum.append(number * 2)
    stringNum.append("\(number)")
}

//map
//클로저 간소화한 문법
doubledNum = numbers.map{ $0 * 2 }
stringNum = numbers.map{ "\($0)" }

 

Filter

  • 내부의 값을 걸러서 추출하는 고차함수
  • 맵과 마찬가지로 새로운 컨테이너에 값을 담아 반환
  • Map = 변형, Filter = 거르기
  • 반환 타입 = Bool
let numbers = [1,2,3,4,5]

//짝수 걸러내기
ler evenNumbers = numbers.filter{ $0 % 2 == 0 } // [2,4]

 

Reduce

  • 컨테이너 내부의 콘텐츠를 하나로 합하는 기능을 실행하는 고차함수
  • 두가지 형태로 구현됨
    • 1. 클로저가 각 요소를 전달받아 연산한 후 값을 다음 클로저 실행을 위해 반환하며 컨테이너를 순환
    • 2. 컨테이너를 순환하며 클로저가 실행되지만 클로저가 따로 결괏값을 반환하지 않은 형태
      • 대신 inout 매개변수를 사용하여 초깃값에 직접 연산을 실행함
let numbers = [1,2,3]

// 1번 형태 
//초깃값이 0이고 모든 값을 더한다
var sum: Int = numbers.reduce(0,{ (result: Int, next: Int) -> Int in
	print("\(result) + \(next)")
    // 0 + 1
    // 1 + 2
    // 3 + 3
    return result + next
})

// 2번 형태
//초깃값이 0이고 모든 값을 더한다
sum = numbers.reduce(into: 0,{ (result: inout Int, next: Int) in
	print("\(result) + \(next)")
    // 0 + 1
    // 1 + 2
    // 3 + 3
	result += next
})

구조체와 클래스 (struct, class)

 

  • 구조체(struct)
    • 값 타입(value type) - 값이 복사됨
    • 상속 불가능
    • deinit 없음
    • 참조카운팅 없음
    • Swift의 대부분의 데이터 타입은 구조체로 작성되어 있다
  • 클래스(class)
    • 참조 타입(reference type) - 인스턴스를 참조하여 공유함
    • 상속 가능
    • deinit 있음
    • 참조 카운팅 있음

가장 큰 차이점은 값/참조 타입이다. -> 이에 대한 자세한 내용은 후에 나온다.

B.U.T. 구글링해서 좀 알아보고 읽으면 이해가 더! 잘될 것이라 생각한다.

 

클래스 vs 구조체

struct PersonStruct{
	var name: String
}

class PersonClass{
	var name: String
    
    deinit{
    	print("소멸됐어염")
    }
    
}

let structPerson = PersonStruct(name: "tree")
let classPerson = PersonClass(name: "tree")
var classPersonVar = PersonClass(name: "tree")

structPerson.name = "randy" // 변경 불가, 값 타입을 상수로 선언 시, 내부 프로퍼티 또한 변경할 수 없다
classPerson.name = "randy" // 변경 가능, 참조 타입을 상수로 선언 시, 참조하는 포인터(?)를 가진 classPerson만 변경이 불가

classPersonVar.name = "randy" // 가능
classPersonVar = nil // 소멸됐어염

 

간단하게만 차이를 알아보자

  구조체 클래스
메모리 영역 Stack Heap
속도 빠름 느림
상속 불가능 가능

 

선택하기

  • 애플은 가이드 라인에서 다음 조건 중 하나 이상에 해당한다면 구조체를 사용하라고 권장한다
    • 연관된 간단한 값의 집합을 캡슐화하는 것만이 목적일 때
    • 캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
    • 구조체에 저장된 프로퍼티가 값 타입이며, 참조하는 것보다 복사하는 것이 합당할 때
    • 상속받거나 상속할 필요가 없을 때

스위프트의 데이터 타입들이 대부분 구조체라서 속도가 빠른 건 알겠어!

B.U.T. 쓸데없이 메모리를 많이 잡아 먹는 것 아냐? 매개변수로든 치환이든 다 복사해서 메모리에 올라가잖아?

-> 스위프트는 꼭 필요한 경우에만 "진짜 복사"를 한다고 한다.

-> 진짜 복사 : 메모리에 실제로 데이터를 복사하여 올리는 것

-> 스위프트가 적절히 효율적으로 처리한다고 하는데 그에 대한 기준은 모르겠다... 나중에 시간나면 찾아보는 걸로...

-> 혹여나 이걸 보는 사람은 없겠지만, 혹시라도 보다가 궁금해서 찾게되면 저도 알려주세요..bb

 

 

 

+ Recent posts