[swift] 서브스크립트

이은수, Lee EunSoo·2024년 9월 21일
0

Swift Basic

목록 보기
13/24
post-thumbnail
post-custom-banner

개요

먼저 이글을 보기전 클래스와 구조체, 프로퍼티 게시글을 안봤다면 이해하기 어려울 수 있다 (보고오자)


서브스크립트라는 키워드가 조금 생소할 수 있다 하지만 우리는 이미 서브스크립트를 알고 있다.

바로 배열이나 딕셔너리에서 [ ]괄호를 사용해서 내부요소에 접근했는데 이것이 서브스크립트이다.

이전까지는 배열이나 딕셔너리에서 제공하는 서브스크립트만 사용이 가능했다면 이제부턴 이 서브스크립트를 직접 구현해서 사용할 수 있다!

형태

서브 스크립트를 사용하면 인스턴스 이름 뒤에 대괄호에 하나 이상의 값을 작성하여 타입의 인스턴스를 조회할 수 있다.
(인스턴스 메서드 구문과 계산된 프로퍼티 구문과 유사함)

형태는 이전에 작성한 프로퍼티와 굉장히 유사한 형태를 갖는다.

get과 set을 가지며, 구조체나 클래스 내부에 작성한다.

struct TimesTable {
    let multiplier: Int
    subscript(index: Int) -> Int {
        return multiplier * index
    }
}
let threeTimesTable = TimesTable(multiplier: 3)
print(threeTimesTable[6])
// 결과.....18

↳ 형태는 다음과 같으며, 위 서브스크립트는 읽기전용 서브스크립트이다.

세부형태

subscript(index: Int) -> Int {
    get {
        // Return an appropriate subscript value here.
    }
    set(newValue) {
        // Perform a suitable setting action here.
    }
}

↳ get과 set을 갖는 서브스크립트

subscript(index: Int) -> Int {
    //Code here...
}

↳ 프로퍼티와 유사하게 get전용(읽기 전용)으로 만들수도 있다.

서브스크립트 활용

서브스크립트는 프로퍼티와도 비슷하지만 함수와도 굉장히 비슷하다.

  1. 함수처럼 파라메터를 받고 반환을 한다
  2. 가변 파라메터를 지원한다.
  3. 파라메터 기본값을 지정 가능하다.
  4. 여러개의 파라메터를 받아올 수 있다.
  5. 상속이(오버라이드) 가능하다.
  6. 오버로드가 가능하다

1. 가변파라메터

struct StringConnector {
    subscript(strings: String...) -> String {
        return strings.joined(separator: " ")
    }
}

let connect = StringConnector()
print(connect["Swift", "는", "재미있는", "언어입니다."]) 

// 출력: Swift 는 재미있는 언어입니다.

↳ 다음과 같이 함수와 같은 형태로 가변 파라메터를 지원한다.

2. 파라메터 기본값 지정

그냥 []안에 아무것도 작성하지 않아도 동작하는 서브스크립트를 만들 수 있다는 말이다.

struct StringConnector {
    subscript(strings: String...) -> String
    {
        return strings.joined(separator: " ")
    }
    subscript() -> String
    {
        return "아무것도 없었다..."
    }
}

let connect = StringConnector()
print(connect[]) 

// 출력: 아무것도 없었다...

3. 여러개의 파라메터

struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]
    
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(repeating: 0.0, count: rows * columns)
    }
    
    func indexIsValid(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
    
    subscript(row: Int, column: Int) -> Double {
        get {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}


//행렬 생성
var matrix = Matrix(rows: 2, columns: 2)

//행렬 좌표에 값 입력
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2

↳ 여기서 assert()는 if나 guard같이 유효성을 검사해주는 함수이다, 그냥 false값이 들어오면 에러메시지를 출력한다.

(생성된 행렬에 맞는 좌표값이 입력되는지 확인하기 위해서 작성되었다.)

4. 오버로드

struct StringConnector {
    subscript(strings: String...) -> String
    {
        return strings.joined(separator: " ")
    }
    subscript() -> String
    {
        return "아무것도 없었다..."
    }
}

let connect = StringConnector()
print(connect[]) 

// 출력: 아무것도 없었다...

↳ 오버로드란 앞서 파라메터 기본값에서 설명한대로 파라메터를 다르게 해서 여러개의 서브스크립트를 생성하는 것을 말한다.

5. 오버라이드

서브스크립트는 상속을 지원하기에 당연하게도 오버라이드또한 지원한다.

class ParentClass {
    subscript(index: Int) -> Int {
        return index * 2
    }
}

class ChildClass: ParentClass {
    override subscript(index: Int) -> Int {
        return super[index] + 1
    }
}

let parent = ParentClass()
print(parent[5]) // 출력: 10

let child = ChildClass()
print(child[5]) // 출력: 11

↳ 오버라이드를 하는 경우 override키워드를 서브스크립트 앞에 붙여줘서 명시해줘야 한다.

타입 서브스크립트

서브스크립트는 static키워드를 이용한 사용을 지원한다.

struct TemperatureConverter {
    static subscript(fahrenheit fahrenheit: Double) -> Double {
        return (fahrenheit - 32) * 5 / 9
    }
    
    static subscript(celsius celsius: Double) -> Double {
        return (celsius * 9 / 5) + 32
    }
}

// 화씨를 섭씨로 변환
let celsius = TemperatureConverter[fahrenheit: 98.6]
print("섭씨 온도: \(celsius)") // 출력: 섭씨 온도: 37.0

// 섭씨를 화씨로 변환
let fahrenheit = TemperatureConverter[celsius: 37.0]
print("화씨 온도: \(fahrenheit)") // 출력: 화씨 온도: 98.6

↳ 이렇게 인스턴스의 생성없이도 서브스크립트를 사용할 수 있다.

정리

  1. 서브스크립트는 구조체, 클래스, 열거형 내부에 작성된다.
  2. 형태는 프로퍼티와 함수와 굉장히 유사하다
  3. 오버로드나 오버라이드를 지원한다.
  4. 타입 서브스크립트또한 존재한다.
profile
iOS 개발자 취준생, 천 리 길도 한 걸음부터
post-custom-banner

0개의 댓글