글 작성자: HEROHJK

인터넷에서 좋은 글을 보고 가져왔습니다.

(번역은아니고, 공감하는대로..)

 

출처 : levelup.gitconnected.com/5-swift-extensions-to-write-smarter-code-7287b86fde68

 

Swift에서 배열을 쓰다보면, 보통은 오버플로우가 나는 경우가 많습니다.

let values = ["A", "B", "C"]

values[0] // A
values[1] // B
values[2] // C
values[3] // Fatal error: Index out of range

이와 비슷한 코드에 관한것을 많은 개발자분들이 경험해 보셨을겁니다.

 

그래서 오버플로, 언더플로를 방지하기위해 많이 노력합니다. (보통은 오버플로겠죠..)

if 2 < values.count {
    values[2] // C
}
if 3 < values.count {
    values[3] // 호출이 안되겠죠 이건.
}

 

이런식의 함수도 작성해볼수 있겠습니다.

func getValue<T>(in elements: [T], at index: Int) -> T? {
    guard index>= 0 && index < elements.count else {
        return nil
    }
    return elements[index]
}

let values = ["A", "B", "C"]
getValue(in: values, at: 2) // "C"
getValue(in: values, at: 3) // nil

 

 

 

values를 매번 넣기때문에, 원글을 보시면 매우 장황하고 추악(?)하다고 설명을 합니다.

 

그래서 Array에 관한 extension에 저 함수를 넣어볼수도 있겠죠.

extension Array {
    func getValue(at index: Int) -> Element? {
        guard index >= 0 && index < self.count else {
            return nil
        }
        return self[index]
    }
}

let values = ["A", "B", "C"]
values.getValue(at: 2) // "C"
values.getValue(at: 3) // nil

 

 

 

그리고 Swift는 subscript extension을 지원해서 최종적으로 이런 코드까지 다가갈수 있겠습니다.

 

extension Array {
    subscript(safe index: Int) -> Element? {
        guard index >- 0 && index < self.count else {
            return nil
        }
        return self[index]
    }
}

values[safe: 2] // "C"
values[safe: 3] // nil

values[safe: 2]는, values[2]와 비슷하지만, 요소에 안전한 접근을 가능하게 합니다.

 

추가로, 원글의 작성자분은 Daniil Vorobyev라는분의 도움을 받아 Collection 프로토콜을 구현하는 모든 클래스에 사용할수 있는 예제를 설명하였습니다.

 

extension Collection {
    public subscript(safe index: Self.Index) -> Iterator.Element? {
        (startIndex ..< endIndex).contains(index) ? self[index] : nil
    }
}

 

2022.05.24 내용 추가

 

요새 알고리즘을 많이 풀다보니, 채점을 할 때 저렇게 extension으로 Foundation 클래스들에 접근이 힘든 경우가 있습니다.

 

그럴때 가장 간단하게 접근하는방법은 이렇습니다.

 

// array라는 배열에서 i를 찾고자 할 때

if (0 ..< array.endIndex).contains(i) { /// 0이 아닌 array.startIndex로 처리해도 됩니다.
  array[i] = /// 코드 처리
}

 

반응형