简体   繁体   English

使用 Swift `is` 检查泛型类型

[英]Use Swift `is` to check type of generic type

Lets say that I have a variable of type Any , and I would like to know wether this is an array or not, here is what I would like to do:假设我有一个Any类型的变量,我想知道这是否是一个数组,这就是我想做的:

if myVariable is Array { /* Do what I want */ }

But Swift requires to give the generic type of the array such as:但是 Swift 需要给出数组的泛型类型,例如:

if myVariable is Array<Int> { }

But I don't want to check the generic type, I just want to know wether this is an array or not, I tried:但我不想检查泛型类型,我只想知道这是否是一个数组,我试过:

if myVariable is Array<Any> { }  

Hoping that it would match every type of array, but that doesn't work either... (it doesn't match arrays of all types, so if my variable is an Int array, this code doesn't get called for instance)希望它能匹配每种类型的数组,但这也不起作用......(它不匹配所有类型的 arrays,所以如果我的变量是一个 Int 数组,则不会调用此代码)

What should I do?我应该怎么办?

Thank you.谢谢你。

Edit with example of an approach solution that doesn't seem to work:使用似乎不起作用的方法解决方案示例进行编辑:

struct Foo<T> {}

struct Bar {
    var property = Foo<String>()
}

var test = Bar()

let mirror = Mirror(reflecting: test)

// This code is trying to count the number of properties of type Foo
var inputCount = 0
for child in mirror.children {
    print(String(describing: type(of: child))) // Prints "(Optional<String>, Any)"
    if String(describing: type(of: child)) == "Foo" {
        inputCount += 1 // Never called
    }
}

print(inputCount) // "0"

Here's 2 things that might work for you. 这里有两件事可能对您有用。

Option 1: 选项1:

Note that child is a tuple containing a String? 注意child是一个包含String?的元组String? with the name of the property ( "property" in your example) and the item. 带有属性的名称(在您的示例中为"property" )和项目。 So you need to look at child.1 . 因此,您需要查看child.1

In this case, you should be checking: 在这种情况下,您应该检查:

if String(describing: type(of: child.1)).hasPrefix("Foo<")

Option 2: 选项2:

If you create a protocol FooProtocol that is implemented by Foo<T> , you could check if child.1 is FooProtocol : 如果创建由Foo<T>实现的协议FooProtocol ,则可以检查child.1 is FooProtocol

protocol FooProtocol { }

struct Foo<T>: FooProtocol {}

struct Bar {
    var property = Foo<String>()
}

var test = Bar()

let mirror = Mirror(reflecting: test)

// This code is trying to count the number of properties of type Foo
var inputCount = 0
for child in mirror.children {
    if child.1 is FooProtocol {
        inputCount += 1
    }
}

This is how to test a generic type parameter for conformance: 这是测试通用类型参数的一致性的方法:

let conforms = T.self is MyProtocol.Type

See this post: Swift: check if generic type conforms to protocol 参见这篇文章: Swift:检查泛型类型是否符合协议

In Java you would want to use Array<?> , in Swift it's not possible, but you can emulate it.在 Java 你想使用Array<?> ,在 Swift 这是不可能的,但你可以模拟它。

  1. Create a protocol protocol AnyArray {}创建协议protocol AnyArray {}

  2. Now let all arrays implement this protocol: extension Array: AnyArray {}现在让所有 arrays 实现这个协议: extension Array: AnyArray {}

  3. Now you can easily do what you intended to do:现在您可以轻松地做您想做的事情:

     if myVariable is AnyArray {... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM