首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较泛型结构类型

比较泛型结构类型
EN

Stack Overflow用户
提问于 2014-11-12 02:24:10
回答 3查看 15.1K关注 0票数 32

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

例如,给定以下结构:

代码语言:javascript
复制
struct FooBar<T> {
    let variable: T
    init(arg: T) {
        variable = arg
    }
}

下面的片段是:

代码语言:javascript
复制
let foo = FooBar(1)
let bar = FooBar(1.0)
let baz = FooBar("1")

如何确定foobarbaz是同一类型还是不同类型?

代码语言:javascript
复制
func areExactType(x: FooBar) -> Bool {
    return self.dynamicType === x.dynamicType
}

这给了我们

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

代码语言:javascript
复制
func areExactType(x: FooBar) -> Bool {
    return self.dynamicType === x.dynamicType
}

这给了我们

不能使用类型的参数列表(Foo.Type,Foo.Type)调用“Foo.Type”

代码语言:javascript
复制
func areExactType(x: FooBar) -> Bool {
    return self is x.dynamicType
}

这就产生了三个错误:

行上的连续语句必须用';‘分隔。

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

虚线类型的期望标识符

预期表达

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-12 18:33:39

Sebastian's answer的启发下,我想出了一个解决方案:

代码语言:javascript
复制
func sameType<L,R>(left: L, right: R) -> Bool {
    if let cast = left as? R {
        return true
    } else {
        return false
    }
}

即使嵌套在接受泛型的函数中,这也是可行的:

代码语言:javascript
复制
func compare<T,U>(foo: T, bar: U) -> Bool {
    return sameType(foo, bar)
}

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

代码语言:javascript
复制
func compare(foo: Any, bar: Any) -> Bool {
    return sameType(foo, bar)
}

这里的sameType函数总是返回true。对于foobar,就sameType而言,它的类型是Any,而不是任何我可能将其简化到的最具体的类型。

同样值得注意的是,如果我尝试将其嵌套为实例方法,则Xcode会崩溃。再读一遍,Xcode会使崩溃。不是“产生不想要的结果”。应用程序崩溃。

例如:

代码语言:javascript
复制
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")
}

这个代码片段会导致Xcode崩溃。我不知道为什么..。但它确实..。

如果我们写的是:

代码语言:javascript
复制
if sameType(x,y) {
    println("x is a y")
}

Xcode编译并运行得很好。

票数 7
EN

Stack Overflow用户

发布于 2014-11-12 02:47:38

编辑:

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

代码语言:javascript
复制
func foobar<T,U> (lhs: Foo<T>, rhs: Foo<U>) -> Bool {
    return lhs.sameType(rhs)
}

如果您停留在纯粹的Swift领域,以下内容将有效:

给出一个简单的泛型结构

代码语言:javascript
复制
struct Foo<T> {
    let v : T
}

您可以定义一个函数sameType,该函数接受相同类型的Foo,然后只返回true

代码语言:javascript
复制
func sameType<T> (a: Foo<T>, b: Foo<T>) -> Bool {
    return true
}

并用两个不同的Foo来重载该函数:

代码语言:javascript
复制
func sameType<T,U> (a: Foo<T>, b: Foo<U>) -> Bool {
    return false;
}

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

代码语言:javascript
复制
let a = Foo(v: 1.0)
let b = Foo(v: "asdf")
sameType(a, b) // false
sameType(a, a) // true

对于结构上的实例方法,这种方法也是这样工作的:

代码语言:javascript
复制
    func sameType (other: Foo) -> Bool {
        return true
    }

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

如果您将Swift和Objective混合在一起,或者由于其他原因不得不依赖动态类型,这可能会产生意想不到的结果:

代码语言:javascript
复制
import Foundation
let x = NSArray(object: 1)
let y = NSArray(object: "string")
sameType(Foo(v: x[0]), Foo(v: y[0])) // true

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

票数 13
EN

Stack Overflow用户

发布于 2014-11-12 19:54:36

如果我没有误解,您不想知道FooBar类型的变量是否属于同一类型(因为它们是),您希望检查它们是否使用相同的泛型类型。

由于struct已经包含了泛型类型的属性,所以可以使用它进行类型比较,而不是使用结构本身:

代码语言:javascript
复制
func areExactType<U>(x: FooBar<U>) -> Bool {
    return x.variable is T
}

我在操场上进行了测试,它可以处理基本数据类型、数组、字典等。缺点是,要使其工作,结构必须具有泛型类型的属性。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26878200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档