比较通用结构类型

nhg*_*rif 30 generics struct types swift

如何确定通用结构的两个实例是否属于同一类型?

例如,给定以下结构:

struct FooBar<T> {
    let variable: T
    init(arg: T) {
        variable = arg
    }
}
Run Code Online (Sandbox Code Playgroud)

以下片段:

let foo = FooBar(1)
let bar = FooBar(1.0)
let baz = FooBar("1")
Run Code Online (Sandbox Code Playgroud)

我如何确定foo,是bar,或是baz相同或不同的类型?


func areExactType(x: FooBar) -> Bool {
    return self.dynamicType === x.dynamicType
}
Run Code Online (Sandbox Code Playgroud)

这给了

类型'Foo'不符合协议'AnyObject'


func areExactType(x: FooBar) -> Bool {
    return self.dynamicType === x.dynamicType
}
Run Code Online (Sandbox Code Playgroud)

这给了

无法使用类型'(Foo.Type,Foo.Type)'的参数列表调用'=='


func areExactType(x: FooBar) -> Bool {
    return self is x.dynamicType
}
Run Code Online (Sandbox Code Playgroud)

这给出了三个错误:

一行上的连续陈述必须用';'分隔

(这要在句点和'dynamicType'之间加一个分号)

虚线类型的预期标识符

期待的表达

Seb*_*ian 12

编辑:

对于过早的答案很抱歉,它实际上不起作用,因为当从另一个函数中调用时,编译器将为不同类型选择函数:

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

如果您留在纯Swift领域,以下将工作:

给出一个简单的通用结构

struct Foo<T> {
    let v : T
}
Run Code Online (Sandbox Code Playgroud)

您可以定义一个函数sameType,该函数采用Foo相同类型的s并返回true:

func sameType<T> (a: Foo<T>, b: Foo<T>) -> Bool {
    return true
}
Run Code Online (Sandbox Code Playgroud)

并使用两个不同的Foos 重载该函数:

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

编译器将根据参数类型选择一个方法:

let a = Foo(v: 1.0)
let b = Foo(v: "asdf")
sameType(a, b) // false
sameType(a, a) // true
Run Code Online (Sandbox Code Playgroud)

这与结构上的实例方法的工作方式相同:

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

    func sameType<U> (other: Foo<U>) -> Bool {
        return false
    }
Run Code Online (Sandbox Code Playgroud)

如果混合使用Swift和Objective-C,或者由于其他原因必须依赖动态类型,则会产生意外结果:

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

结果是真的,因为because Foo(v: x[0])有类型Foo<AnyObject>

  • 它在非常有限的情况下工作,否则无用.我可以投票给自己的答案吗? (6认同)

nhg*_*rif 6

塞巴斯蒂安的答案中汲取灵感,我提出了这个解决方案:

func sameType<L,R>(left: L, right: R) -> Bool {
    if let cast = left as? R {
        return true
    } else {
        return false
    }
}
Run Code Online (Sandbox Code Playgroud)

即使嵌套在接受泛型的函数中,这也可以工作:

func compare<T,U>(foo: T, bar: U) -> Bool {
    return sameType(foo, bar)
}
Run Code Online (Sandbox Code Playgroud)

但它确实有一些塞巴斯蒂安的回答提到的垮台.也就是说,如果你从Objective-C集合中检索了你的值,那么它们都有一个类型AnyObject.此外,如果我将sameType函数嵌套在一个参数不是泛型的函数中,例如:

func compare(foo: Any, bar: Any) -> Bool {
    return sameType(foo, bar)
}
Run Code Online (Sandbox Code Playgroud)

sameType此处的功能将始终返回true.该类型的foobar,至于sameType而言,是Any的,而不是什么最具体的类型我可能会垂头丧气它.


值得注意的是,如果我尝试将其嵌套为实例方法,Xcode会崩溃.再读一遍,Xcode崩溃了.不会"产生不良后果".应用程序崩溃.

例如:

func sameType<L,R>(left: L, right: R) -> Bool {
    if let cast = left as? R {
        return true
    } else {
        return false
    }
}

struct Foo<T> {
    func sameType<U>(bar: U) -> Bool {
        return sameType(self, bar)
    }
}

let x = Foo<Int>()
let y = Foo<Float>()

if x.sameType(y) {
    println("x is a y")
}
Run Code Online (Sandbox Code Playgroud)

此代码段崩溃了Xcode.我不知道为什么......但它确实......

如果我们改为写:

if sameType(x,y) {
    println("x is a y")
}
Run Code Online (Sandbox Code Playgroud)

Xcode编译并运行得很好.