Swift 根据通用类型检查类型
Swift check type against a generic type
我有一个带 1 个参数的泛型函数,我想用泛型类型检查传递的参数的类型。像这样:
func generic<T>(parameter: AnyObject) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
但是我不知道怎么称呼这个
generic<String>("Hello")
给我一个编译器错误:“无法显式特化通用函数
通用("Hello")
这种情况不适合仿制药。您只是要求根据类型测试对象。如果这始终是 AnyObject,您可以尝试这样的操作:
func istest(parameter: AnyObject, whattype: AnyObject.Type) -> Bool {
if parameter.dynamicType === whattype.self {
return true
} else {
return false
}
}
如果你真的想要一个你可以特化的泛型,你不能明确地特化一个函数,所以你必须将你的函数包装在一个泛型类型中并特化它:
struct Generic<T> {
func generic(parameter: AnyObject) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
}
let ok = Generic<String>().generic("howdy")
let ok2 = Generic<Int>().generic(1)
但是正如我已经说过的那样,您给出的示例不适合这样做。请记住,泛型是在编译时解析的——我们已经知道解析后的类型是什么。因此,您的测试毫无意义,因为您已经知道答案。这就是为什么我向您展示了一个替代函数,其中值和类型都是未知的。
您无法告诉函数其通用占位符的类型是什么(与通用结构不同)。它必须从上下文中推断出它们,例如它的参数。
做你想做的事情的一种方法是添加另一个与类型 T
相关的参数。您可以使用所需类型的元类型,而不是传入虚拟值:
func generic<T>(parameter: AnyObject, type: T.Type) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
let o: AnyObject = "hello"
generic(o, String.self) // true
generic(o, NSString.self) // also true
generic(o, Int.self) // false
但是,我想问你,你认为你在这里取得了什么成就?您基本上只是将 is
作为函数实现:
o is String // true
o is NSString // true
o is Int // false
泛型的要点是对参数进行一般操作,但您没有为函数提供任何特定类型的参数以实际执行任何操作(因此无法推断出一个)。
更通用的方法:
struct Asserter<T>{
func generic(_ val:Any) -> Bool{
let type = type(of: val)
return T.self == type
}
}
_ = Asserter<String>().generic(2)//false
_ = Asserter<String>().generic("")//true
正在检查泛型类型是否 class。
protocol Some {}
class SomeClass: Some {}
class AClass: Some {}
func test(_ t: T) -> String {
if T.self == SomeClass.self {
return "Some Class"
} else {
return "Another Class"
}
}
print(test(SomeClass())) // Some Class
print(test(AClass())) // Another Class
我有一个带 1 个参数的泛型函数,我想用泛型类型检查传递的参数的类型。像这样:
func generic<T>(parameter: AnyObject) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
但是我不知道怎么称呼这个
generic<String>("Hello")
给我一个编译器错误:“无法显式特化通用函数 通用("Hello")
这种情况不适合仿制药。您只是要求根据类型测试对象。如果这始终是 AnyObject,您可以尝试这样的操作:
func istest(parameter: AnyObject, whattype: AnyObject.Type) -> Bool {
if parameter.dynamicType === whattype.self {
return true
} else {
return false
}
}
如果你真的想要一个你可以特化的泛型,你不能明确地特化一个函数,所以你必须将你的函数包装在一个泛型类型中并特化它:
struct Generic<T> {
func generic(parameter: AnyObject) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
}
let ok = Generic<String>().generic("howdy")
let ok2 = Generic<Int>().generic(1)
但是正如我已经说过的那样,您给出的示例不适合这样做。请记住,泛型是在编译时解析的——我们已经知道解析后的类型是什么。因此,您的测试毫无意义,因为您已经知道答案。这就是为什么我向您展示了一个替代函数,其中值和类型都是未知的。
您无法告诉函数其通用占位符的类型是什么(与通用结构不同)。它必须从上下文中推断出它们,例如它的参数。
做你想做的事情的一种方法是添加另一个与类型 T
相关的参数。您可以使用所需类型的元类型,而不是传入虚拟值:
func generic<T>(parameter: AnyObject, type: T.Type) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
let o: AnyObject = "hello"
generic(o, String.self) // true
generic(o, NSString.self) // also true
generic(o, Int.self) // false
但是,我想问你,你认为你在这里取得了什么成就?您基本上只是将 is
作为函数实现:
o is String // true
o is NSString // true
o is Int // false
泛型的要点是对参数进行一般操作,但您没有为函数提供任何特定类型的参数以实际执行任何操作(因此无法推断出一个)。
更通用的方法:
struct Asserter<T>{
func generic(_ val:Any) -> Bool{
let type = type(of: val)
return T.self == type
}
}
_ = Asserter<String>().generic(2)//false
_ = Asserter<String>().generic("")//true
正在检查泛型类型是否 class。
protocol Some {}
class SomeClass: Some {}
class AClass: Some {}
func test(_ t: T) -> String {
if T.self == SomeClass.self {
return "Some Class"
} else {
return "Another Class"
}
}
print(test(SomeClass())) // Some Class
print(test(AClass())) // Another Class