Nested Types Inside a Protocol

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



Leave a reply



Submit