Skip to content

Instantly share code, notes, and snippets.

@GeekAndDad
Created January 10, 2020 21:02
Show Gist options
  • Save GeekAndDad/9a213b712d4847b2bf2130f8e96aee06 to your computer and use it in GitHub Desktop.
Save GeekAndDad/9a213b712d4847b2bf2130f8e96aee06 to your computer and use it in GitHub Desktop.
macOS playground playing with opaque types & protocols.
// paste into new macOS playground
// Xcode 11.3 on 10.15.2
import Cocoa
protocol InfoTypeProtocol {}
protocol Base {
associatedtype InfoType: InfoTypeProtocol
var info: InfoType { get set }
}
struct A<T: InfoTypeProtocol>: Base {
typealias InfoType = T
var info: InfoType
var diff: String
}
struct B<T: InfoTypeProtocol>: Base {
typealias InfoType = T
var info: InfoType
var other: Int
}
extension String: InfoTypeProtocol {}
extension Int: InfoTypeProtocol {}
func test<T:Base>(_ val: T) {
switch val.info {
case is String:
print("string")
case is Int:
print("int")
default:
print("unknown")
}
}
let a = A<String>(info: "hello", diff: "a-string")
let ai = A<Int>(info: 42, diff: "42 info")
test(a) // "string"
test(ai) // "int"
// this work also:
// function returns the protocol defined associated type field using opaque types.
// enough type information for switch statement below
// (without the `some` keyword this doesn't work)
func test2<T: Base>(_ val: T) -> some InfoTypeProtocol {
return val.info
}
let z = test2(ai)
switch z {
case is String:
print("string!", z)
case is Int:
print("Int!", z)
default:
print("unknown")
}
// prints: "Int! 42"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment