Does swift type inference not work with function return types? - ios

Does swift type inference not work with function return types?
protocol Vehicle {
func numberOfWheels() -> Int
}
struct Car: Vehicle {
func numberOfWheels() -> Int {
return 4
}
}
struct Bike: Vehicle {
func numberOfWheels() -> Int {
return 2
}
}
struct Truck: Vehicle {
func numberOfWheels() -> Int {
return 8
}
}
struct VehicleFactory {
static func getVehicle<T: Vehicle>(_ vehicleType: T.Type = T.self) -> T? {
let id = identifier(for: T.self)
switch id {
case "Car":
return Car() as? T
case "Bike":
return Bike() as? T
default:
return nil
}
}
private static func identifier(for type: Any.Type) -> String {
String(describing: type)
}
}
let v: Bike = VehicleFactory.getVehicle() // ERROR HERE: Cannot convert value of type 'T?' to specified type 'Bike'
print(v.numberOfWheels())
I am trying this in playground. Why is there an error in above line?
Shouldnt the compiler infer the type to be Bike from the let v: Bike declaration?

The problem is that getVehicle returns an optional, you have to declare
let v: Bike? = VehicleFactory.getVehicle()
Further you have to unwrap v in the print line

Not a direct answer to your question. Vadian has already answered but a few notes on your implementation:
(_ vehicleType: T.Type = T.self) is pointless. You can just omit it.
Second I would simply add init() to your protocol requirements, get rid of the identifier method, change number of wheels to a computed property:
protocol Vehicle {
init()
var numberOfWheels: Int { get }
}
struct Car: Vehicle {
let numberOfWheels = 4
}
struct Bike: Vehicle {
let numberOfWheels = 2
}
struct Truck: Vehicle {
let numberOfWheels = 8
}
struct VehicleFactory {
static func getVehicle<T: Vehicle>() -> T { .init() }
}
let v: Bike = VehicleFactory.getVehicle()
print(v.numberOfWheels) // "2\n"

Related

How do declare methods that return a Sequence of custom Structs in Swift

What is the proper way to declare a function that return a Sequence in Swift 4. I tried the following but receive a error stating:
error: Models.playground:29:13: error: cannot convert return expression of type 'Cars' to return type 'S'
return Cars(cars)
^~~~~~~~~~
as! S
Here is the code I used:
import Foundation
struct Car {
let make:String
let model:String
}
class Cars: Sequence, IteratorProtocol {
typealias Element = Car
var current = 0
let cars:[Element]
init(_ cars:[Element]) {
self.cars = cars;
}
func makeIterator() -> Iterator {
current = 0
return self
}
func next() -> Element? {
if current < cars.count {
defer { current += 1 }
return cars[current]
} else {
return nil
}
}
}
let cars = Cars([Car(make:"Buick", model:"Century"), Car(make:"Buick", model:"LaSabre")])
func getCars<S:Sequence>(cars:[Car]) -> S where S.Iterator.Element == Car {
return Cars(cars)
}
The return value cannot be a specialization of the Sequence protocol.
You can either return Cars itself, as Daniel suggested, or –
if you want to hide the implementation of the sequence – a
“type-erased” sequence:
func getCars(cars:[Car]) -> AnySequence<Car> {
return AnySequence(Cars(cars))
}
or even
func getCars(cars:[Car]) -> AnySequence<Car> {
return AnySequence(cars)
}
AnySequence is a
generic struct conforming to the Sequence protocol which forwards
to the underlying sequence or iterator from which it was created.
See also A Little Respect for AnySequence
for more examples.
Remark: Similarly, it is possible to make Cars a Sequence
by returning a type-erased iterator which forwards to the array
iterator:
class Cars: Sequence {
typealias Element = Car
let cars: [Element]
init(_ cars: [Element]) {
self.cars = cars;
}
func makeIterator() -> AnyIterator<Element> {
return AnyIterator(cars.makeIterator())
}
}
The problem is that you are using a generic for a specific type. You can either return a Cars element (note that Cars conforms to Sequence, so you are returning a Sequence here):
func getCars(cars: [Car]) -> Cars {
return Cars(cars)
}
or use a generic (also a Sequence, since it is defined in the generic):
func getCars<S: Sequence>(cars: [Car]) -> S {
return cars as! S
}

Swift Equatable on a protocol

I don't think this can be done but I'll ask anyway. I have a protocol:
protocol X {}
And a class:
class Y:X {}
In the rest of my code I refer to everything using the protocol X. In that code I would like to be able to do something like:
let a:X = ...
let b:X = ...
if a == b {...}
The problem is that if I try to implement Equatable:
protocol X: Equatable {}
func ==(lhs:X, rhs:X) -> Bool {
if let l = lhs as? Y, let r = hrs as? Y {
return l.something == r.something
}
return false
}
The idea to try and allow the use of == whilst hiding the implementations behind the protocol.
Swift doesn't like this though because Equatable has Self references and it will no longer allow me to use it as a type. Only as a generic argument.
So has anyone found a way to apply an operator to a protocol without the protocol becoming unusable as a type?
If you directly implement Equatable on a protocol, it will not longer be usable as a type, which defeats the purpose of using a protocol. Even if you just implement == functions on protocols without Equatable conformance, results can be erroneous. See this post on my blog for a demonstration of these issues:
https://khawerkhaliq.com/blog/swift-protocols-equatable-part-one/
The approach that I have found to work best is to use type erasure. This allows making == comparisons for protocol types (wrapped in type erasers). It is important to note that while we continue to work at the protocol level, the actual == comparisons are delegated to the underlying concrete types to ensure correct results.
I have built a type eraser using your brief example and added some test code at the end. I have added a constant of type String to the protocol and created two conforming types (structs are the easiest for demonstration purposes) to be able to test the various scenarios.
For a detailed explanation of the type erasure methodology used, check out part two of the above blog post:
https://khawerkhaliq.com/blog/swift-protocols-equatable-part-two/
The code below should support the equality comparison that you wanted to implement. You just have to wrap the protocol type in a type eraser instance.
protocol X {
var name: String { get }
func isEqualTo(_ other: X) -> Bool
func asEquatable() -> AnyEquatableX
}
extension X where Self: Equatable {
func isEqualTo(_ other: X) -> Bool {
guard let otherX = other as? Self else { return false }
return self == otherX
}
func asEquatable() -> AnyEquatableX {
return AnyEquatableX(self)
}
}
struct Y: X, Equatable {
let name: String
static func ==(lhs: Y, rhs: Y) -> Bool {
return lhs.name == rhs.name
}
}
struct Z: X, Equatable {
let name: String
static func ==(lhs: Z, rhs: Z) -> Bool {
return lhs.name == rhs.name
}
}
struct AnyEquatableX: X, Equatable {
var name: String { return value.name }
init(_ value: X) { self.value = value }
private let value: X
static func ==(lhs: AnyEquatableX, rhs: AnyEquatableX) -> Bool {
return lhs.value.isEqualTo(rhs.value)
}
}
// instances typed as the protocol
let y: X = Y(name: "My name")
let z: X = Z(name: "My name")
let equalY: X = Y(name: "My name")
let unequalY: X = Y(name: "Your name")
// equality tests
print(y.asEquatable() == z.asEquatable()) // prints false
print(y.asEquatable() == equalY.asEquatable()) // prints true
print(y.asEquatable() == unequalY.asEquatable()) // prints false
Note that since the type eraser conforms to the protocol, you can use instances of the type eraser anywhere an instance of the protocol type is expected.
Hope this helps.
The reason why you should think twice about having a protocol conform to Equatable is that in many cases it just doesn't make sense. Consider this example:
protocol Pet: Equatable {
var age: Int { get }
}
extension Pet {
static func == (lhs: Pet, rhs: Pet) -> Bool {
return lhs.age == rhs.age
}
}
struct Dog: Pet {
let age: Int
let favoriteFood: String
}
struct Cat: Pet {
let age: Int
let favoriteLitter: String
}
let rover: Pet = Dog(age: "1", favoriteFood: "Pizza")
let simba: Pet = Cat(age: "1", favoriteLitter: "Purina")
if rover == simba {
print("Should this be true??")
}
You allude to type checking within the implementation of == but the problem is that you have no information about either of the types beyond them being Pets and you don't know all the things that might be a Pet (maybe you will add a Bird and Rabbit later). If you really need this, another approach can be modeling how languages like C# implement equality, by doing something like:
protocol IsEqual {
func isEqualTo(_ object: Any) -> Bool
}
protocol Pet: IsEqual {
var age: Int { get }
}
struct Dog: Pet {
let age: Int
let favoriteFood: String
func isEqualTo(_ object: Any) -> Bool {
guard let otherDog = object as? Dog else { return false }
return age == otherDog.age && favoriteFood == otherDog.favoriteFood
}
}
struct Cat: Pet {
let age: Int
let favoriteLitter: String
func isEqualTo(_ object: Any) -> Bool {
guard let otherCat = object as? Cat else { return false }
return age == otherCat.age && favoriteLitter == otherCat.favoriteLitter
}
}
let rover: Pet = Dog(age: "1", favoriteFood: "Pizza")
let simba: Pet = Cat(age: "1", favoriteLitter: "Purina")
if !rover.isEqualTo(simba) {
print("That's more like it.")
}
At which point if you really wanted, you could implement == without implementing Equatable:
static func == (lhs: IsEqual, rhs: IsEqual) -> Bool { return lhs.isEqualTo(rhs) }
One thing you would have to watch out for in this case is inheritance though. Because you could downcast an inheriting type and erase the information that might make isEqualTo not make logical sense.
The best way to go though is to only implement equality on the class/struct themselves and use another mechanism for type checking.
Determining equality across conformances to a Swift protocol is possible without type erasure if:
you are willing to forgo the operator syntax (i.e. call isEqual(to:) instead of ==)
you control the protocol (so you can add an isEqual(to:) func to it)
import XCTest
protocol Shape {
func isEqual (to: Shape) -> Bool
}
extension Shape where Self : Equatable {
func isEqual (to: Shape) -> Bool {
return (to as? Self).flatMap({ $0 == self }) ?? false
}
}
struct Circle : Shape, Equatable {
let radius: Double
}
struct Square : Shape, Equatable {
let edge: Double
}
class ProtocolConformanceEquality: XCTestCase {
func test() {
// Does the right thing for same type
XCTAssertTrue(Circle(radius: 1).isEqual(to: Circle(radius: 1)))
XCTAssertFalse(Circle(radius: 1).isEqual(to: Circle(radius: 2)))
// Does the right thing for different types
XCTAssertFalse(Square(edge: 1).isEqual(to: Circle(radius: 1)))
}
}
Any conformances don't conform to Equatable will need to implement isEqual(to:) themselves
maybe this will be helpful for you:
protocol X:Equatable {
var name: String {get set}
}
extension X {
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.name == rhs.name
}
}
struct Test : X {
var name: String
}
let first = Test(name: "Test1")
let second = Test(name: "Test2")
print(first == second) // false
All people who say that you can't implement Equatable for a protocol just don't try hard enough. Here is the solution (Swift 4.1) for your protocol X example:
protocol X: Equatable {
var something: Int { get }
}
// Define this operator in the global scope!
func ==<L: X, R: X>(l: L, r: R) -> Bool {
return l.something == r.something
}
And it works!
class Y: X {
var something: Int = 14
}
struct Z: X {
let something: Int = 9
}
let y = Y()
let z = Z()
print(y == z) // false
y.something = z.something
print(y == z) // true
The only problem is that you can't write let a: X = Y() because of "Protocol can only be used as a generic constraint" error.
Not sure why you need all instances of your protocol to conform to Equatable, but I prefer letting classes implement their equality methods.
In this case, I'd leave the protocol simple:
protocol MyProtocol {
func doSomething()
}
If you require that an object that conforms to MyProtocol is also Equatable you can use MyProtocol & Equatable as type constraint:
// Equivalent: func doSomething<T>(element1: T, element2: T) where T: MyProtocol & Equatable {
func doSomething<T: MyProtocol & Equatable>(element1: T, element2: T) {
if element1 == element2 {
element1.doSomething()
}
}
This way you can keep your specification clear and let subclasses implement their equality method only if required.
I would still advise against implementing == using polymorphism. It's a bit of a code smell. If you want to give the framework user something he can test equality with then you should really be vending a struct, not a protocol. That's not to say that it can't be the protocols that are vending the structs though:
struct Info: Equatable {
let a: Int
let b: String
static func == (lhs: Info, rhs: Info) -> Bool {
return lhs.a == rhs.a && lhs.b == rhs.b
}
}
protocol HasInfo {
var info: Info { get }
}
class FirstClass: HasInfo {
/* ... */
}
class SecondClass: HasInfo {
/* ... */
}
let x: HasInfo = FirstClass( /* ... */ )
let y: HasInfo = SecondClass( /* ... */ )
print(x == y) // nope
print(x.info == y.info) // yep
I think this more efficiently communicates your intent, which is basically "you have these things and you don't know if they are the same things, but you do know they have the same set of properties and you can test whether those properties are the same." That is pretty close to how I would implement that Money example.
You have to implement a protocol extension constrained to your class type. Inside that extension you should implement the Equatable operator.
public protocol Protocolable: class, Equatable
{
// Other stuff here...
}
public extension Protocolable where Self: TheClass
{
public static func ==(lhs: Self, rhs:Self) -> Bool
{
return lhs.name == rhs.name
}
}
public class TheClass: Protocolable
{
public var name: String
public init(named name: String)
{
self.name = name
}
}
let aClass: TheClass = TheClass(named: "Cars")
let otherClass: TheClass = TheClass(named: "Wall-E")
if aClass == otherClass
{
print("Equals")
}
else
{
print("Non Equals")
}
But let me recommend you add the operator implementation to your class. Keep It Simple ;-)
Swift 5.1 introduces a new feature into the language called opaque types
Check code below
that still gets back a X, which might be an Y, a Z, or something else that conforms to the X protocol,
but the compiler knows exactly what is being returned
protocol X: Equatable { }
class Y: X {
var something = 3
static func == (lhs: Y, rhs: Y) -> Bool {
return lhs.something == rhs.something
}
static func make() -> some X {
return Y()
}
}
class Z: X {
var something = "5"
static func == (lhs: Z, rhs: Z) -> Bool {
return lhs.something == rhs.something
}
static func make() -> some X {
return Z()
}
}
let a = Z.make()
let b = Z.make()
a == b
I came cross this same issue and I figured that the == operator can be implemented in the global scope (as it used to be), as opposed to a static func inside the protocol's scope:
// This should go in the global scope
public func == (lhs: MyProtocol?, rhs: MyProtocol?) -> Bool { return lhs?.id == rhs?.id }
public func != (lhs: MyProtocol?, rhs: MyProtocol?) -> Bool { return lhs?.id != rhs?.id }
Note that if you use linters such as SwiftLint's static_operator, you'll have to wrap that code around // swiftlint:disable static_operator to silent linter warnings.
Then this code will start compiling:
let obj1: MyProtocol = ConcreteType(id: "1")
let obj2: MyProtocol = ConcreteType(id: "2")
if obj1 == obj2 {
print("They're equal.")
} else {
print("They're not equal.")
}
took some of the code from above and came with the following sollution.
it uses the IsEqual protocol instead of the Equatable protocol and with a few line codes you will be able to compare any two protocol objects with each other, wether they are optional or not, are in an array and even add comparing dates while I was at it.
protocol IsEqual {
func isEqualTo(_ object: Any) -> Bool
}
func == (lhs: IsEqual?, rhs: IsEqual?) -> Bool {
guard let lhs = lhs else { return rhs == nil }
guard let rhs = rhs else { return false }
return lhs.isEqualTo(rhs) }
func == (lhs: [IsEqual]?, rhs: [IsEqual]?) -> Bool {
guard let lhs = lhs else { return rhs == nil }
guard let rhs = rhs else { return false }
guard lhs.count == rhs.count else { return false }
for i in 0..<lhs.count {
if !lhs[i].isEqualTo(rhs[i]) {
return false
}
}
return true
}
func == (lhs: Date?, rhs: Date?) -> Bool {
guard let lhs = lhs else { return rhs == nil }
guard let rhs = rhs else { return false }
return lhs.compare(rhs) == .orderedSame
}
protocol Pet: IsEqual {
var age: Int { get }
}
struct Dog: Pet {
let age: Int
let favoriteFood: String
func isEqualTo(_ object: Any) -> Bool {
guard let otherDog = object as? Dog else { return false }
return age == otherDog.age && favoriteFood == otherDog.favoriteFood
}
}

Heterogeneous mixture of protocol types, including a generic protocol

protocol ParentProtocol { }
protocol ChildProtocol: ParentProtocol { }
protocol Child_With_Value_Protocol: ParentProtocol {
associatedType Value
func retrieveValue() -> Value
}
Attempting to create a single array of type ParentProtocol that contains both ChildProtocol and Child_With_Value_Protocol. Is there any possible way to create a function that loops through the heterogeneous array and returns the values of just type Child_With_Value_Protocol?
This may require an architecture change. Open to all solutions.
Attempted Failed Solution #1
var parents: [ParentProtocol] = [...both ChildProtocol & Child_With_Value_Protocol...]
func retrieveValues() -> [Any] {
var values = [Any]()
for parent in parents {
if let childWithValue = parent as? Child_With_Value_Protocol { // Fails to compile
values.append(childWithValue.retrieveValue())
}
}
return values
}
This fails with an error of protocol 'Child_With_Value_Protocol' can only be used as a generic constraint because it has Self or associated type requirements which makes sense since the compiler would not know the type when converted to just Child_With_Value_Protocol, this leads to the next failed solution.
Attempted Failed Solution #2
If the array was a homogeneous array of just Child_With_Value_Protocol, type erasing could be used to retrieve the values.
var parents: [ParentProtocol] = [...both ChildProtocol & Child_With_Value_Protocol...]
struct AnyValue {
init<T: Child_With_Value_Protocol>(_ protocol: T) {
_retrieveValue = protocol.retrieveValue as () -> Any
}
func retrieveValue() -> Any { return _retrieveValue() }
let _retrieveValue: () -> Any
}
func retrieveValues() -> [Any] {
var values = [Any]()
for parent in parents {
values.append(AnyValue(parent).retrieveValue()) // Fails to compile
}
return values
}
This fails to compile due to the fact that the struct AnyValue has no initializer for the ParentProtocol.
Attempted Failed Solution #3
struct AnyValue {
init<T: Child_With_Value_Protocol>(_ protocol: T) {
_retrieveValue = protocol.retrieveValue as () -> Any
}
func retrieveValue() -> Any { return _retrieveValue() }
let _retrieveValue: () -> Any
}
var erased: [AnyValue] = [AnyValue(...), AnyValue(...), AnyValue(...)]
func retrieveValues() -> [Any] {
var values = [Any]()
for value in erased {
values.append(value.retrieveValue())
}
return values
}
Unlike the other solutions, this solution actually compiles. Problem with this solution resides in the fact that the array erased can only hold values of the type-erased versions of Child_With_Value_Protocol. The goal is for the array to hold types of both Child_With_Value_Protocol and ChildProtocol.
Attempted Failed Solution #4
Modifying the type-erase struct to include an initializer for ParentProtocol still creates a solution that compiles, but then the struct will only use the less specific init, instead of the more specific init.
struct AnyValue {
init?<T: ParentProtocol>(_ protocol: T) {
return nil
}
init?<T: Child_With_Value_Protocol>(_ protocol: T) {
_retrieveValue = protocol.retrieveValue as () -> Any
}
func retrieveValue() -> Any { return _retrieveValue() }
let _retrieveValue: (() -> Any)?
}
The prior comments are likely right. Nevertheless, you could box the variants in an enum and create an array of those. The reference would then switch on the enum value, each having associated data of the right type
EDIT: I didn't bother with the associatedValue, because it seems irrelevant to the question being asked. The following works in a playground:
protocol ParentProtocol: CustomStringConvertible {
static func retrieveValues(parents: [FamilyBox]) -> [ParentProtocol]
}
protocol ChildProtocol: ParentProtocol { }
protocol Other_Child_Protocol: ParentProtocol { }
enum FamilyBox {
case Parent(parent: ParentProtocol)
case Child(child: ChildProtocol)
case OtherChildProtocol(withValue: Other_Child_Protocol)
}
var parents: [FamilyBox] = []
struct P: ParentProtocol {
var description: String { return "Parent" }
static func retrieveValues(parents: [FamilyBox]) -> [ParentProtocol] {
var values = [ParentProtocol]()
for parent in parents {
switch parent {
case .Parent(let elementValue):
values.append(elementValue)
default:
break;
}
}
return values
}
}
struct C: ChildProtocol {
var description: String { return "Child" }
static func retrieveValues(parents: [FamilyBox]) -> [ParentProtocol] {
var values = [ParentProtocol]()
for parent in parents {
switch parent {
case .Child(let elementValue):
values.append(elementValue)
default:
break;
}
}
return values
}
}
struct CV: Other_Child_Protocol {
var description: String { return "Other Child" }
static func retrieveValues(parents: [FamilyBox]) -> [ParentProtocol] {
var values = [ParentProtocol]()
for parent in parents {
switch parent {
case .OtherChildProtocol(let elementValue):
values.append(elementValue)
default:
break;
}
}
return values
}
}
let p = FamilyBox.Parent(parent: P())
let c = FamilyBox.Child(child: C())
let cv = FamilyBox.OtherChildProtocol(withValue: CV())
let array:[FamilyBox] = [p, c, cv]
print(P.retrieveValues(array))
print(C.retrieveValues(array))
print(CV.retrieveValues(array))
The prints from the last three lines are:
[Parent]
[Child]
[Other Child]
While I'm sure it can be improved, I think that meets the original intent. No?

Generic class inheritance in Swift

I have the following class:
class BaseCache<T: Equatable>: NSObject {
var allEntities = [T]()
// MARK: - Append
func appendEntities(newEntities: [T]) {
....
}
}
Now I want to subclass it, but I get annoying error, that my type "does not conform to protocol 'Equatable'":
It seems generics in Swift are real pain-in-the-ass.
Your class definition of TrackingCache is wrong. It repeats the generic parameter:
class TrackingCache<AftershipTracking>: BaseCache<AftershipTracking> { }
It should be left out:
class TrackingCache: BaseCache<AftershipTracking> { }
This triggers the underlying swift error Classes derived from generic classes must also be generic. You can work around this issue by specifying a type parameter that is required to be or inherit from AftershipTracking:
class TrackingCache<T: AftershipTracking>: BaseCache<AftershipTracking> { }
Full example:
class BaseCache<T: Equatable>: NSObject {
var items: [T] = []
func appendItems( items: [T]) {
self.items += items
didAppendItems()
}
func didAppendItems() {} // for overriding
}
class AftershipTracking: NSObject {
var identifier: Int
init( identifier: Int) {
self.identifier = identifier
super.init()
}
}
extension AftershipTracking: Equatable { }
func ==( lhs: AftershipTracking, rhs: AftershipTracking) -> Bool {
return lhs.identifier == rhs.identifier
}
class TrackingCache<T: AftershipTracking>: BaseCache<AftershipTracking> {
override func didAppendItems() {
// do something
}
}
let a = TrackingCache<AftershipTracking>()
let b = TrackingCache<AftershipTracking>()
a.appendItems( [AftershipTracking( identifier: 1)])
b.appendItems( [AftershipTracking( identifier: 1)])
let result = a.items == b.items // true
this should work: < swift 4 >
class TrackingCache<T: AftershipTracking>: BaseCache<T>
Another example:
protocol P {
}
class C: P {
}
class CS: C {
}
class L<T:P> {
let c: T
init(_ c: T) {
self.c = c
}
}
class LS<T:CS>:L<T> {
}
let i = LS(CS())
i.c
c is CS now.

swift - Can I compare Any.Type?

I defined two types as follow: I want to define a function 'matches' that compares two KeyTypePairs and returns true or false depends on matching on key and type.
protocol KeyTypePair: Hashable {
typealias val
var key: String { get }
var type: Any.Type { get }
}
public struct KeyTypePairOf<T>: KeyTypePair {
typealias val = T
let _key: String
let _type: Any.Type
public var key: String {
get {
return _key
}
}
public var type: Any.Type {
get {
return _type
}
}
public var hashValue: Int {
get {
return _key.hashValue
}
}
public init(key: String) {
self._key = key
self._type = T.self
}
init<T: KeyTypePair>(property: T) {
self._key = pair.key
self._type = pair.type
}
func matches<T: KeyTypePair>(pair:T) -> Bool {
let x = self._type == pair.type // invalid, how do I check equal types?
return self._key == pair.key && x
}
}
How do I compare the 'types' of the struct? Been a headache. Should I use AnyObject instead?
I tested this in a Swift 4 playground
struct Foo {}
struct Bar {}
let fooType: Any.Type = Foo.self
let barType: Any.Type = Bar.self
fooType == Foo.self // true
fooType is Foo.Type // true
fooType == barType // false
The tool you want is object_getClassName (which returns a String). Right now, you can't directly compare types. This feels like just a missing compiler feature rather than anything deep about swift. You'd think you could compare x.dynamicType == y.dynamicType, but that doesn't currently work. See also What is the pattern for entities and Equatable?

Resources