如何确定通用结构的两个实例是否属于同一类型?
例如,给定以下结构:
struct FooBar<T> {
let variable: T
init(arg: T) {
variable = arg
}
}
以下代码段:
let foo = FooBar(1)
let bar = FooBar(1.0)
let baz = FooBar("1")
如何确定foo
,bar
或baz
是相同还是不同类型?
func areExactType(x: FooBar) -> Bool {
return self.dynamicType === x.dynamicType
}
这给出了
类型'Foo'不符合协议'AnyObject'
func areExactType(x: FooBar) -> Bool {
return self.dynamicType === x.dynamicType
}
这给出了
无法使用类型为'(Foo.Type,Foo.Type)'的参数列表调用'=='
func areExactType(x: FooBar) -> Bool {
return self is x.dynamicType
}
这给出了三个错误:
一行上的连续陈述必须用';'
分隔
(这需要在句点和'dynamicType'之间加一个分号)
虚线类型的预期标识符
和
预期表达
答案 0 :(得分:11)
对于过早的回答感到抱歉,它实际上不起作用,因为编译器会在从另一个函数调用时选择不同类型的函数:
func foobar<T,U> (lhs: Foo<T>, rhs: Foo<U>) -> Bool {
return lhs.sameType(rhs)
}
给出一个简单的通用结构
struct Foo<T> {
let v : T
}
您可以定义一个函数sameType
,该函数转到同一类型的Foo
,然后返回true
:
func sameType<T> (a: Foo<T>, b: Foo<T>) -> Bool {
return true
}
并使用两个不同的Foo
s:
func sameType<T,U> (a: Foo<T>, b: Foo<U>) -> Bool {
return false;
}
编译器将根据参数类型选择一种方法:
let a = Foo(v: 1.0)
let b = Foo(v: "asdf")
sameType(a, b) // false
sameType(a, a) // true
这与struct上的实例方法的工作方式相同:
func sameType (other: Foo) -> Bool {
return true
}
func sameType<U> (other: Foo<U>) -> Bool {
return false
}
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>
答案 1 :(得分:6)
从Sebastian's answer获得一些灵感,我提出了这个解决方案:
func sameType<L,R>(left: L, right: R) -> Bool {
if let cast = left as? R {
return true
} else {
return false
}
}
即使嵌套在接受泛型的函数中,这也有效:
func compare<T,U>(foo: T, bar: U) -> Bool {
return sameType(foo, bar)
}
但它确实有一些塞巴斯蒂安的答案提到的垮台。也就是说,如果您从Objective-C集合中检索了您的值,则它们的类型都为AnyObject
。此外,如果我将sameType
函数嵌套在一个参数不是泛型的函数中,例如:
func compare(foo: Any, bar: Any) -> Bool {
return sameType(foo, bar)
}
此处的sameType
功能将始终返回true
。就foo
而言,bar
和sameType
的类型是Any
,而不是我可能将其转发到的最具体类型。
它也可能值得注意的是,如果我尝试将其嵌套为实例方法,Xcode会崩溃。再次阅读, Xcode崩溃。不会产生不良结果&#34;。应用程序崩溃。
例如:
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。我不知道为什么......但确实......
如果我们改为写:
if sameType(x,y) {
println("x is a y")
}
Xcode编译并运行得很好。
答案 2 :(得分:2)
如果我没有误解,你不想知道FooBar
类型的变量是否属于同一类型(因为它们是),你想要检查它们是否使用相同的泛型类型。
由于struct已包含泛型类型的属性,因此可以将其用于类型比较,而不是使用struct本身:
func areExactType<U>(x: FooBar<U>) -> Bool {
return x.variable is T
}
我在游乐场测试过,它适用于基本数据类型,数组,字典等。 缺点是,为了使其工作,结构必须具有泛型类型的属性。