Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swift protocol conformance when same property name is optional

When a protocol declares a property as optional and a concrete type declares it as non-optional, how can I make the concrete type conform to the protocol?

Here's the problem:

protocol Track {
    var trackNumber: Int? { get } // not all tracks have a track number
}

struct SpotifyTrack {
    let trackNumber: Int // all SpotifyTrack are guaranteed to have a track number
}

extension SpotifyTrack: Track {
    var trackNumber: Int? {
        return self.trackNumber // WARNING: All paths through this function will call itself
    }
}

I don't want to make trackNumber optional in SpotifyTrack because I know the value will always be there for SpotifyTracks. Are there are any solutions more elegant than just renaming the properties?

like image 428
Eric Avatar asked Mar 17 '26 19:03

Eric


2 Answers

There is no elegant solution to your problem other than renaming the conflicting property on the conforming type.

Swift doesn't allow 2 properties of the same name to exist on a type even if their types are different. On the other hand, Int? and Int are completely different types, so you cannot have trackNumber: Int fulfil the protocol requirement of trackNumber: Int?.

The only solution (other than changing the type in either the protocol or the struct) is to rename the non-Optional property in SpotifyTrack and make an optional computed property of the same name returning the non-optional one.

protocol Track {
    var trackNumber: Int? { get }
}
struct SpotifyTrack {
    private let _trackNumber: Int
}
extension SpotifyTrack: Track {
    var trackNumber: Int? { _trackNumber }
}
like image 53
Dávid Pásztor Avatar answered Mar 20 '26 15:03

Dávid Pásztor


One way could be that you have a base track protocol and then have a second protocol which extend the base protocol. For example

protocol BaseTrackProtocol {
    var title:String
    var artist:String
}

protocol SpotifyTrackProtocol : BaseTrackProtocol {
    var trackNumber:Int
}

struct SoptifyTrack: SpotifyTrackProtocol {
    var title:String
    var artist:String
    var trackNumber:Int
}

other type of tracks could then follow different extensions of the base track protocol

hope it helps :)

like image 37
Luca Iaco Avatar answered Mar 20 '26 14:03

Luca Iaco



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!