Nested types inside a protocol
A protocol cannot require a nested type, but it can require an associated type that conforms to another protocol. An implementation could use either a nested type or a type alias to meet this requirement.
protocol Inner {
var property: String { get set }
}
protocol Outer {
associatedtype Nested: Inner
}
class MyClass: Outer {
struct Nested: Inner {
var property: String = ""
}
}
struct NotNested: Inner {
var property: String = ""
}
class MyOtherClass: Outer {
typealias Nested = NotNested
}
Nesting structs in Protocol Extension: Type '...' cannot be nested in generic function '...()'
You cannot nest new types inside of generic structures in extensions this way. Allowing that would likely become very complex, since it is not quite clear whether this type would be Fruit.saveObject.Packet
or <ConformingType>.saveObject.Packet
. For example, consider the following (legal) code for how these kinds of types can escape, and the system has to deal with them, including knowing how to dispatch methods to them, how much storage they require, etc.
protocol P {}
func x() -> P {
struct T: P {}
return T()
}
type(of: x())
If you change this to make x()
generic, then it is no longer legal:
func x<Y>() -> P {
struct T: P {} // error: type 'T' cannot be nested in generic function 'x()'
return T()
}
That said, if you believe that the language should be changed to allow this, then Swift Evolution is the process to suggest it. You should first think though how you would like this to work if Fruit
had associatedtypes, if saveObject()
were itself generic, and if Packet
included reference to type variable defined in either of those places. (I'm not saying these are insurmountable problems at all. This may be an excellent feature and it may be possible to design it very well. You just need to think through how it interacts with other features of the language.)
The solution is to move Packet to the top level, outside the extension and outside the protocol.
Access variable of an enum nested in struct in a protocol extension in Swift
enum UnitStyle{
case Metric, Imperial
}
protocol RunParameter{
typealias Unit: RawRepresentable, CustomStringConvertible
var value: Double{get set}
var unit: Unit{get}
var unitStyle: UnitStyle{get set}
}
extension RunParameter where Unit.RawValue == Double{
mutating func getValueForUnitStyle(unitStyle: UnitStyle) -> (Double,String){
self.unitStyle = unitStyle
return (value * self.unit.rawValue, self.unit.description)
//here I want to return both calculated value and unit string
//but unable to access unit description on self.unit
}
}
struct Distance: RunParameter {
enum Unit: Double, CustomStringConvertible {
case km = 0.001
case m = 1.0
case mi = 0.000621371
var description: String{
switch self{
case .km: return "km"
case .m: return "m"
case .mi: return "mi"
}
}
}
var value: Double
var unitStyle = UnitStyle.Metric
var unit: Unit {
get{
switch unitStyle{
case .Metric: return Unit.km
case .Imperial: return Unit.mi
}
}
}
init(value: Double){
self.value = value
}
}
struct Run {
var unitStyle = UnitStyle.Imperial
var distance = Distance(value: 10.0)
}
var x = Run()
let z = x.distance.getValueForUnitStyle(.Imperial)
x.distance.unit.description //output "mi"
print(z.0,z.1) // 0.00621371 mi
Related Topics
Variable Captured by Closure Before Being Initialized
Uitableviewrowaction with Icon and Text
How to Add Caching to Asyncimage
How to Convert Copaquepointer in Swift to Some Type (Cgcontext? in Particular)
Need Self to Set All Constants of a Swift Class in Init
Swift: Force Show Navigation Bar in Modal
How to Get Motion Events with the Apple Tv Remote
Call Methods from Swift Initializer
Get Path to Swift Script from Within Script
"An Error Occurred While Accessing the Keychain" When Signing in Using Firebase
Accessing Self from Instance Properties Which Are Closures
Swift Uisearchcontroller Wired Up in Core Data Project, App Runs, But Search Not Updating
Scene Kit Performance with Cube Test
How to Filter Events Created for the Current Date in the Realm Swift
Mkmapview Not Clustering Annotation on Zooming Out Map in Swift
Cannot Assign to Property: 'Self' Is Immutable, I Know How to Fix But Needs Understanding