Geoff
Geoff

Reputation: 51

Conforming to Strideable Protocol in Swift 3.1

I am going through the absolute joy that is converting to Swift 3.1 I am running into issues with the Strideable protocol. The below code does not compile; the only error message is that the type 'Segment' does not conform to protocol Strideable (and also does not conform to _Strideable). Searching around I find a bunch of stuff about associated types and nested types, but nothing specific.

struct segment: Equatable, Comparable, Hashable, Strideable {
var segTurn: Int
var segSegment: Int
typealias Stride = Int

init() {
    segTurn = 0
    segSegment = 12
}

init(segment: Int, turn: Int) {
    segTurn = turn
    segSegment = segment
}

var hashValue: Int {
    get {
        return "\(self.segTurn),\(self.segSegment)".hashValue
    }
}

var description: String {
    if segTurn == 0 && segSegment == 12 {
        return "Start of Combat Segment 12"
    }
    return "Turn: \(self.segTurn) Segment: \(self.segSegment)"
}

static func successor() -> segment {
    return self + 1
}

static func advanced(by n: Int) -> segment {
    return self + n
}

static func distance(to other: segment) -> Int {
    return other - self
}

static postfix func ++(theSeg:inout segment) -> segment {
    theSeg = theSeg + 1
    return theSeg
}

static func +(lhs:segment, rhs:Int) -> segment {
    var intSeg = lhs.segSegment + rhs
    var intTurn = lhs.segTurn
    while intSeg > 12 {
        intTurn += 1
        intSeg = intSeg - 12
    }
    while intSeg < 1 {
        intTurn -= 1
        intSeg = intSeg + 12
    }

    return segment(segment: intSeg, turn: intTurn)
}

static func -(lhs:segment, rhs:Int) -> segment {
    var intSeg = lhs.segSegment - rhs
    var intTurn = lhs.segTurn
    while intSeg > 12 {
        intTurn += 1
        intSeg = intSeg - 12
    }
    while intSeg < 1 {
        intTurn -= 1
        intSeg = intSeg + 12
    }

    return segment(segment: intSeg, turn: intTurn)
}

static func ==(lhs:segment, rhs:segment) -> Bool {
    let areEqual = lhs.segTurn == rhs.segTurn &&
        lhs.segSegment == rhs.segSegment

    return areEqual
}

static func <(lhs:segment, rhs:segment) -> Bool {
    var isLessThan = false
    if lhs.segTurn < rhs.segTurn {
        isLessThan = true
    } else if lhs.segTurn == rhs.segTurn && lhs.segSegment < rhs.segSegment {
        isLessThan = true
    }
    return isLessThan

}

}

Upvotes: 0

Views: 619

Answers (1)

Wismin
Wismin

Reputation: 1145

The following are what you need to modify to make it work:

  1. Remove static keywords, from all your functions inside Segment. (leave them as instance methods)
  2. Move all the operator functions to outside the Segment structure definition.

Then your code will look like the following and it will compile without error / warning in Swift 3.1:

struct Segment: Equatable, Comparable, Hashable, Strideable {
    var segTurn: Int
    var segSegment: Int
    typealias Stride = Int

    init() {
        segTurn = 0
        segSegment = 12
    }

    init(segment: Int, turn: Int) {
        segTurn = turn
        segSegment = segment
    }

    var hashValue: Int {
        get {
            return "\(self.segTurn),\(self.segSegment)".hashValue
        }
    }

    var description: String {
        if segTurn == 0 && segSegment == 12 {
            return "Start of Combat Segment 12"
        }
        return "Turn: \(self.segTurn) Segment: \(self.segSegment)"
    }

    func successor() -> Segment {
        return self + 1
    }

    func advanced(by n: Int) -> Segment {
        return self + n
    }

    func distance(to other: Segment) -> Int {
        return other - self
    }
}

postfix func ++(theSeg:inout Segment) -> Segment {
    theSeg = theSeg + 1
    return theSeg
}

func +(lhs:Segment, rhs:Int) -> Segment {
    var intSeg = lhs.segSegment + rhs
    var intTurn = lhs.segTurn
    while intSeg > 12 {
        intTurn += 1
        intSeg = intSeg - 12
    }
    while intSeg < 1 {
        intTurn -= 1
        intSeg = intSeg + 12
    }

    return Segment(segment: intSeg, turn: intTurn)
}

func -(lhs:Segment, rhs:Int) -> Segment {
    var intSeg = lhs.segSegment - rhs
    var intTurn = lhs.segTurn
    while intSeg > 12 {
        intTurn += 1
        intSeg = intSeg - 12
    }
    while intSeg < 1 {
        intTurn -= 1
        intSeg = intSeg + 12
    }

    return Segment(segment: intSeg, turn: intTurn)
}

func ==(lhs:Segment, rhs:Segment) -> Bool {
    let areEqual = lhs.segTurn == rhs.segTurn &&
        lhs.segSegment == rhs.segSegment

    return areEqual
}

func <(lhs:Segment, rhs:Segment) -> Bool {
    var isLessThan = false
    if lhs.segTurn < rhs.segTurn {
        isLessThan = true
    } else if lhs.segTurn == rhs.segTurn && lhs.segSegment < rhs.segSegment {
        isLessThan = true
    }
    return isLessThan
}

Upvotes: 1

Related Questions