【问题标题】:Swift - checking type of a generic classSwift - 检查泛型类的类型
【发布时间】:2020-09-18 20:12:25
【问题描述】:

我有一个 Swift 泛型类,如下所示:

class List<T> {
    var value: T
    var next: List<T>?
    ...
}

我想检查某个对象是否是此类的实例,无论 T 是什么类型。例如,如果我有:

let a = List<Int>(2, 3)
let b = List<Any>(5, List<String>("a", "b"))
let c = "something which is not a list"

我希望过程(或代码 sn-p)为 ab 返回 true,为 c 返回 false。

提前致谢。

【问题讨论】:

    标签: swift generics types


    【解决方案1】:

    其中一种解决方案是为您的通用List 使用协议:

    protocol AnyList {}
    
    class List<T>: AnyList {
        var value: T
        var next: List<T>?
        ...
    }
    
    func isList<T>(_ object: T) -> Bool {
        object is AnyList
    }
    
    let a = List<Int>(value: 2)
    let b = "something which is not a list"
    
    print(isList(a)) // true
    print(isList(b)) // false
    

    【讨论】:

      【解决方案2】:

      List&lt;T&gt; 是泛型类型,List&lt;Int&gt;List&lt;String&gt; 是具体类型,但 List 单独不是类型,它只是一个标识符。

      所以,说 2 个东西都是 List 是没有意义的。此外,例如,List&lt;Int&gt;List&lt;String&gt; 与某些 FooBar 一样彼此不同。

      如果您想对列表进行推理,则需要这两者之间的共同点,即协议或基类。但是,由于您的列表具有通用元素类型,因此在具有不同元素的任何两个列表之间几乎没有任何共同点,除了 countprint 之类的函数。

      所以你可以做这样的事情(正如另一个答案中正确建议的那样)

      protocol AnyList {
         func count() -> Int
         func print() -> Void
         // but, var value: T wouldn't work
      }
      
      class List<T>: AnyList {
        ...
      }
      

      但是您可以看到,与列表的作用相比,普通的AnyList 的用处有限。

      最后,您需要问自己接下来要对任何类型的“列表”做什么,并得出结论,List&lt;Int&gt;List&lt;String&gt; 都是列表,但对它们的具体值类型一无所知.

      【讨论】:

      • 我的最终目标是在最后展平列表,所以我想区分,例如,当我遍历我想要的列表时,我是否有一个 List&lt;List&lt;Int&gt;&gt;(List&lt;Int&gt;(2, 3), List&lt;Int&gt;(4, 5))看到每个元素确实是另一个列表,所以我也必须展平那个元素,而在我有 List&lt;Int&gt;(2, 3) 的情况下,我可以推断出基础类型是 Int 因此无法进一步展平。
      • 那么,您原来的顶级列表是列表列表吗?对我来说似乎很奇怪,但我想我不知道你想要实现什么,所以如果它对你有用,那就太好了:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 2018-11-23
      • 2016-10-10
      相关资源
      最近更新 更多