当协议将属性声明为可选并且具体类型将其声明为非可选时,如何使具体类型符合协议?
这里是问题:
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
}
}
我不想在trackNumber
中将SpotifyTrack
设为可选,因为我知道SpotifyTracks的值将始终存在。有没有比重命名属性更优雅的解决方案?
除了重命名一致类型上的冲突属性外,没有其他解决方案。
Swift不允许同一类型的2个相同属性存在,即使它们的类型不同。另一方面,Int?
和Int
是完全不同的类型,因此trackNumber: Int
不能满足trackNumber: Int?
的协议要求。
唯一的解决方案(除了更改protocol
或struct
中的类型之外,其他方法是重命名SpotifyTrack
中的non-Optional属性,并使同名的可选计算属性返回非可选属性)。一个。
protocol Track {
var trackNumber: Int? { get }
}
struct SpotifyTrack {
private let _trackNumber: Int
}
extension SpotifyTrack: Track {
var trackNumber: Int? { _trackNumber }
}
一种方法可能是您拥有一个基本跟踪协议,然后有了第二个协议来扩展基本协议。例如
您可以拥有第二个属性作为第一个属性的支持: