Self and associated type requirements (yes again!)
Self and associated type requirements (yes again!)
- Subject: Self and associated type requirements (yes again!)
- From: Roland King <email@hidden>
- Date: Mon, 30 Nov 2015 20:12:58 +0800
I keep running myself into this issue when I try using some of my generic classes built on top of Protocols.
I have a TimeSeries protocol which has an Underlying (Float, Double, .. whatever) and also a Self requirement because you can return a sub series. There’s more to the protocol but this is enough for example
public protocol TimeSeries
{
typealias Underlying
mutating func addValue( value : Underlying, tick : Int )
func subSeriesFromTick( tick : Int )->Self
}
I have two concrete implementers of this protocol, a FullTimeSeries which is a memory pig and a CompressedTimeSeries which usually isn't
public struct FullTimeSeries<T> : TimeSeries
{
public typealias Underlying = T
// implementation
}
public struct CompressedTimeSeries<T> : TimeSeries
{
public typealias Underlying = T
// implementation
}
These work just fine. Now I want a UIView which shows a TimeSeries, in this case actually a TimeSeries of Floats, of course the code below doesn’t work
public class TimeSeriesView : UIView
{
public typelias Underlying = Float
public var timeSeries : TimeSeries
}
"Protocol 'TimeSeries' can only be used as a generic constraint because it has Self or associated type requirements”, my least favourite error message which always pops up just after I’ve done all the work and just before I get to use the fruits of my labour. I never see it coming.
The typealias in the above code doesn’t do anything of course, it was just me having an attempt.
I want to say that timeSeries is any TimeSeries with an underlying type of Float, but you can’t. I wanted to have a generic UIView I could just stuff a TimeSeries of Floats into and it would show it.
The best I can come up with is to parameterise on T, which is a TimeSeries
public class TimeSeriesView<T:TimeSeries>
{
public typealias Underlying = Float
public var timeSeries : T
}
now I have to create the correct TimeSeriesView<FullTimeSeries<Float>> or TimeSeriesView<CompressedTimeSeries<Float>>, which wasn’t really what I wanted to do.
There’s still no clever way around this right, this is still how Generics and Protocols work together, there’s nothing in Swift 2.0 which helps you work around this, no way to use Protocol extensions to do it? I thought (I’ve tried this before) of making a FloatTimeSeries protocol which only deals with Floats and has no Self or associated type issues which basically has all the same methods of TimeSeries but with ‘Float’ specifically instead of Underlying and then using a protocol extension like this
extension FullTimeSeries : FloatTimeSeries where T:Float
{
}
but Swift has you covered on that one too .. "Extension of type 'FullTimeSeries' with constraints cannot have an inheritance clause”
Nothing from last years WWDC I missed here? You still can’t do this, right?
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden