【问题标题】:Workarounds for generic variable in SwiftSwift 中泛型变量的解决方法
【发布时间】:2017-06-10 04:50:25
【问题描述】:

所以我有一个类型别名元组

public typealias MyTuple<T> = (key: T, value: String)

在我的 ViewController 中,我想声明一个具有通用数据类型的 MyTuple 数组,因为我仍然不知道键的类型。但是,从this 开始,在 Swift 中不可能有泛型类型的变量。还有其他解决方法如下,但我不喜欢其中任何一个。谁有更好的主意?

class ViewController: UIViewController {
    var array1 = [MyTuple<T>]() // compile error of course

    var array2 = [MyTuple<Any>]() // no point as I'd use `Any` for MyTuple

    func getArray<T>(array: Array<MyTuple<T>>) -> Array<MyTuple<T>> {
        return array // not a good approach
    }
}

【问题讨论】:

  • 所以问题是VC会在运行时确定实际的T类型,因此你不能声明数组[MyTuple&lt;ConcreteType&gt;],对吧?
  • @VadimPopov 问题是我有另一个视图控制器 (vcA),它将调用 ViewController 并将数据传递给 MyTuple 数组。到那时我会知道密钥的类型,但不是现在。

标签: swift variables generics tuples type-alias


【解决方案1】:

我认为解决这个问题的常用方法是将类型决策“推”到依赖链更高的位置,到视图控制器:

class ViewController<T>: UIViewController {
    var array: [MyTuple<T>]
}

这是有道理的,因为您可能会将控制器视为“foo 控制器”,其中“foo”是T 的具体值。 (“宠物控制器”、“产品控制器”等)当然,在您知道具体类型之前,您不能创建数组的实例。

【讨论】:

  • 我想过一个通用的视图控制器,但是如果我以后想扩展我的视图控制器,那不是不可能吗?
【解决方案2】:

您可以使用不依赖于键的数据类型的数组声明和基本方法的协议来做类似的事情:

protocol KeyValueArray
{
   associatedtype KeyType
   var array:[(key:KeyType,value:String)] { get set }
}

extension KeyValueArray
{
   var array:[(key: KeyType, value:String)] { get {return []} set { } }
}

class ViewController:UIViewController,KeyValueArray 
{
   // assuming this is like an "abstact" base class 
   // that won't actually be instantiated.
   typealias KeyType = Any   

   // you can implement base class functions using the array variable
   // as long as they're not dependent on a specific key type.
}

class SpecificVC:ViewController
{
   typealias KeyType = Int 
   var array:[(key:Int,value:String)] = []
}

我假设,在某些时候,视图控制器子类的具体实例将具有键的实际类型

【讨论】:

  • 迄今为止最好的主意。你知道如何在不继承 ViewController 的情况下更新 typealias KeyType 吗?
  • 这将需要某种形式的类型擦除,并且本质上会导致一个与 (key:Any, value:String) 一样宽松的数组变量。也许更详细地描述您想要实现的目标可以帮助我们提出更好的建议。
  • 谢谢,在这种情况下@zoul 的建议对我有用。唯一的缺点是我不能扩展 ViewController。
  • 发现它也不适用于委托,我不想使用闭包完成,所以我按照建议发布了一个新问题:stackoverflow.com/q/44490152/7113238
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 2020-04-21
  • 1970-01-01
  • 2016-02-22
  • 1970-01-01
相关资源
最近更新 更多