[英]Swift check type against a generic type
I've a generic function with 1 parameter and want to check the type of the passed parameter with the generic type. 我有一个带有1个参数的泛型函数,想要检查传递参数的类型和泛型类型。 Something like this:
像这样的东西:
func generic<T>(parameter: AnyObject) -> Bool {
if parameter is T {
return true
} else {
return false
}
}
But I don't know how to call this 但我不知道怎么称呼它
generic<String>("Hello")
Gives me a compiler error: "Cannot explicitly specialize a generic function generic("Hello") 给我一个编译错误:“不能明确地专门化泛型函数generic(”Hello“)
You cannot tell a function what the types of its generic placeholders are (unlike with a generic struct). 您无法告诉函数其通用占位符的类型是什么(与通用结构不同)。 It must infer them from the context eg its arguments.
它必须从上下文中推断它们,例如它的论点。
One way to do what you want is to add another argument related to type T
. 做你想做的事的一种方法是添加另一个与类型
T
相关的参数。 Rather than pass in a dummy value, you could use the metatype of the type you want: 您可以使用所需类型的元类型,而不是传入虚拟值:
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
However, I would ask you, what is it you think you're achieving here? 但是,我会问你,你认为你在这里取得了什么成就? You've essentially done nothing more than implement
is
as a function: 你已经基本上完成不外乎实现
is
作为一个函数:
o is String // true
o is NSString // true
o is Int // false
The point of generics is to operate on arguments generically, but you aren't giving the function any argument of a specific type to actually do any work on (hence the inability to infer one). 泛型的要点是通常对参数进行操作,但是你没有给函数任何特定类型的参数实际做任何工作(因此无法推断出一个)。
Checking if generic type is which 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
This situation is not a candidate for a generic. 这种情况不是通用的候选者。 You are just asking to test an object against a type.
您只是要求针对类型测试对象。 If this is always going to be an AnyObject, you might try something like this:
如果这总是AnyObject,你可以尝试这样的事情:
func istest(parameter: AnyObject, whattype: AnyObject.Type) -> Bool {
if parameter.dynamicType === whattype.self {
return true
} else {
return false
}
}
If you really want a generic that you can specialize, you cannot specialize a function explicitly, so you will have to wrap your function in a generic type and specialize that: 如果你真的想要一个可以专门化的泛型,你不能明确地专门化一个函数,所以你必须将你的函数包装成一个泛型类型并专门化:
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)
But the example you have given, as I've already said, is not a good candidate for doing that. 但是,正如我已经说过的那样,你给出的例子并不是一个好的候选人。 Remember, a generic is resolved at compile time - we already know what the resolved type is going to be.
请记住,泛型在编译时被解析 - 我们已经知道解析类型将是什么。 Thus, your test is pointless because you already know the answer.
因此,您的测试毫无意义,因为您已经知道了答案。 That is why I showed you an alternative function where the value and the type are both unknown.
这就是为什么我向你展示了一个替代函数,其中值和类型都是未知的。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.