본문 바로가기

iOS/Swift

Swift - Strideable Protocol

https://developer.apple.com/documentation/swift/strideable

 

Strideable | Apple Developer Documentation

A type representing continuous, one-dimensional values that can be offset and measured.

developer.apple.com

 

 

 

Definition

 

Strideable연속적인 1차원 값을 나타내며, offset(차이)을 계산하고 측정(거리 계산)할 수 있는 타입을 정의한다.

즉, 어떤 값이 Strideable 프로토콜을 채택하면, 그 값 사이의 거리를 측정하거나, 일정 간격으로 값을 증분시킬 수 있다는 의미이다.

 

protocol Strideable<Stride> : Comparable

 

  • 대표적인 Strideable 타입에는 Int, Double, Date, CGFloat 등이 있다.
  • 두 값의 거리(distance)를 나타내는 Stride 타입을 Associcated Type으로 갖는다.
associatedtype Stride : Comparable, SignedNumeric

 

Overview

 

Strideable을 채태한 타입은 stride(from:to:by:)stride(from:through:by:)에서 사용할 수 있다.

  • 값 간의 간격을 설정하여 반복 작업
  • 특히 부동 소수점, 정수, 날짜와 같은 타입에 대해 간격을 두고 반복하거나 계산할 때 유용

stride(from:to:by:)

  • 시작 값에서 목표 값까지 지정한 간격으로 반복하되, 목표 값은 포함하지 않음

 

stride(from:through:by:)

  • 목표 값을 포함하여 반복

 

[부동 소수점을 사용한 반복]

// 0부터 2π까지, π/2 간격으로 반복하면서, 각 라디안(radian) 값을 도(degree)로 변환하여 출력
for radians in stride(from: 0.0, to: .pi * 2, by: .pi / 2) {
    let degrees = Int(radians * 180 / .pi)
    print("Degrees: \(degrees), radians: \(radians)")
}

 

[정수를 사용한 반복 - for in loop]

/// When a closed range uses integers as its lower and upper bounds, or any
/// other type that conforms to the Strideable protocol with an integer
/// stride, you can use that range in a for-in loop or with any sequence or
/// collection method. The elements of the range are the consecutive values
/// from its lower bound up to, and including, its upper bound. 
  • Stride 타입이 Int인 경우 ClosedRange를 사용하여 for-in 루프를 돌 수 있다.
  • Float이나 Double의 경우 Stride 타입이 각각 자기 자신이기 때문에 위의 stride 함수 들을 사용해야 함
var sum = 0
for x in 1...100 {
    sum += x
}
// sum == 5050


let digits = (0..<10).map(String.init)
// ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

 

Conforming to the Strideable Protocol

Strideable 프로토콜을 채택하기 위해서 다음 두 가지주요 메서드를 구현해야 한다.

 

  • advanced(by:): 현재 날짜에서 n일만큼 앞서거나 뒤로 이동한 날짜를 반환합니다.
  • distance(to:): 다른 날짜와의 일 수 차이를 반환합니다.

 

다음은 2000년 1월 1일 이후의 날짜를 나타내는 커스텀 구조체에 Strideable 프로토콜을 채택하는 예시이다.

 

1. Date 타입 정의

struct Date: Equatable, CustomStringConvertible {
    var daysAfterY2K: Int

    var description: String {
        return "Days after Y2K: \(daysAfterY2K)"
    }
}

 

 

2. Strideable 프로토콜 구현

  • typealias Stride = Int가 자동으로 추론됨 
extension Date: Strideable {
    func advanced(by n: Int) -> Date {
        var result = self
        result.daysAfterY2K += n
        return result
    }

    func distance(to other: Date) -> Int {
        return other.daysAfterY2K - self.daysAfterY2K
    }
}

 

3. stride(from:to:by:) 함수 사용

let startDate = Date(daysAfterY2K: 0)   // 2000년 1월 1일
let endDate = Date(daysAfterY2K: 15)    // 2000년 1월 16일

for date in stride(from: startDate, to: endDate, by: 7) {
    print(date)
}

// Days after Y2K: 0
// Days after Y2K: 7
// Days after Y2K: 14

 

[중요]

  • Strideable 프로토콜을 구현할 때, ==(동등 비교)와 <(작다 비교) 연산자에 대한 기본 구현이 제공됨
  • 이 연산자들은 Strideable이 사용하는 Stride 타입에 의존해 동작
  • 하지만, Strideable 타입 자체가 그 타입의 Stride 타입인 경우, 즉 자기 자신이 Stride 타입인 경우에는 무한 재귀가 발생할 수 있기 때문에, 구체적인 구현을 제공해야 함
    • 타입 자체가 Stride 타입이라면, 이 연산자는 자기 자신을 참조하는 방식으로 구현될 수 있어, 무한 재귀가 발생한다

 

 

 

 

'iOS > Swift' 카테고리의 다른 글

Swift - In-Out 파라미터  (0) 2024.09.20
Swift 공식문서 5. Control Flow  (0) 2024.09.19
Swift 공식문서 4. Collection Types  (0) 2024.09.08
Swift 공식 문서 3. Strings and Characters (2)  (1) 2024.08.31
Swift API Design Guidelines  (0) 2024.08.29