Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing generic struct types

How do I determine whether two instances of a generic struct are of the same type?

For example, given the following struct:

struct FooBar<T> {     let variable: T     init(arg: T) {         variable = arg     } } 

And the following snippet:

let foo = FooBar(1) let bar = FooBar(1.0) let baz = FooBar("1") 

How can I determine whether foo, bar, or baz are of the same or different types?


func areExactType(x: FooBar) -> Bool {     return self.dynamicType === x.dynamicType } 

This gives

Type 'Foo' does not conform to protocol 'AnyObject'


func areExactType(x: FooBar) -> Bool {     return self.dynamicType === x.dynamicType } 

This gives

Cannot invoke '==' with an argument list of type '(Foo.Type, Foo.Type)'


func areExactType(x: FooBar) -> Bool {     return self is x.dynamicType } 

This gives three errors:

Consecutive statements on a line must be separated by ';'

(this wants to put a semicolon between the period and 'dynamicType')

Expected identifier in dotted type

and

Expected expression

like image 239
nhgrif Avatar asked Nov 12 '14 02:11

nhgrif


1 Answers

Edit:

Sorry for the premature answer, it actually doesn't work, because the compiler will choose the function for different types when called from within another function:

func foobar<T,U> (lhs: Foo<T>, rhs: Foo<U>) -> Bool {     return lhs.sameType(rhs) } 

If you stay in pure Swift territory, the following will work:

Given a simple generic struct

struct Foo<T> {     let v : T } 

You can define a function sameType that takes to Foos of the same type and just return true:

func sameType<T> (a: Foo<T>, b: Foo<T>) -> Bool {     return true } 

and overload the function with two different Foos:

func sameType<T,U> (a: Foo<T>, b: Foo<U>) -> Bool {     return false; } 

The compiler will choose a method based on the argument type:

let a = Foo(v: 1.0) let b = Foo(v: "asdf") sameType(a, b) // false sameType(a, a) // true 

This works the same way with instance methods on the struct:

    func sameType (other: Foo) -> Bool {         return true     }      func sameType<U> (other: Foo<U>) -> Bool {         return false     } 

This can have unexpected results if you mix Swift and Objective-C or have to rely on the dynamic type for other reasons:

import Foundation let x = NSArray(object: 1) let y = NSArray(object: "string") sameType(Foo(v: x[0]), Foo(v: y[0])) // true 

The result is true because because Foo(v: x[0]) has type Foo<AnyObject>

like image 164
Sebastian Avatar answered Sep 29 '22 05:09

Sebastian