| protocol HumanType {} | |
| protocol HasName {} | |
| func printHumanName<T: protocol<HumanType, HasName>>(x: T) {} | |
| // It currently isn't possible to directly pass a protocol<> type value | |
| // as a concrete value conforming to the protocol. However, a protocol | |
| // extension method's Self type *is* a concrete type conforming to the | |
| // extending protocol. By introducing extension methods we can "open" | |
| // the protocol existential and use the opened Self type with generics. | |
| // | |
| // (Yes, this is a hacky workaround, and we should have first-class | |
| // support for it in the language. Doug Gregor addresses this as | |
| // a missing feature in the "Opening Existentials" section of his | |
| // Generics Manifesto: | |
| // https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md ) | |
| extension HumanType where Self: HasName { | |
| private func _printHumanName() { | |
| printHumanName(x: self) | |
| } | |
| } | |
| func tryToPrintUnknownData(unknownData: Any) { | |
| if let unknownData = unknownData as? protocol<HumanType, HasName> { | |
| // Compile Error: cannot invoke 'printHumanName' | |
| // with an argument list of type '(protocol<HasName, HumanType>)' | |
| /*printHumanName(unknownData)*/ | |
| // However, we can use an extension method on the protocol value: | |
| unknownData._printHumanName() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment