【问题标题】:Swift 5.1 generic usage in subclass子类中的 Swift 5.1 通用用法
【发布时间】:2021-11-14 17:22:36
【问题描述】:

我有以下数据模型类来表示 MyDataModel:

  public class MyDataModel <T> : Codable, Comparable where T:Codable {

   ...
  }

接下来我实现一个包含 MyDataModel 实例的视图。我显然不能在 UIView 的子类中保存通用参数,所以我尝试按如下方式解决它:

 protocol MyDataProtocol {
    associatedtype T:Codable
     var dataParam:T { get set }
 }

  public class MyDataView: UIView {

      public var myData:some MyDataProtocol?

  }

但我得到一个错误

  An 'opaque' type must specify only 'Any', 'AnyObject', protocols, and/or a base class

所以我可以使用 Any?作为 MyDataProtocol 的类型,但这仍然不会告诉我 MyDataModel 的参数类型。我想知道这里的解决方案是什么以及处理这个问题的正确方法。

【问题讨论】:

  • "我显然不能在 UIView 的子类中保存泛型参数" 真的吗?为什么不呢?
  • 我也不明白是什么阻止了你拥有public class MyDataView&lt;T&gt;: UIView { public var myData: T }
  • @KirilS。问题是我需要将这些数据视图存储在另一个类的数组中。然后我还需要将该类声明为泛型,然后链继续。根据我以前的经验,它使事情变得更加复杂(已经在其他地方尝试过,结果一团糟)。
  • @KirilS。而持有这些数据视图的类,为了使事情变得复杂,它可以同时持有不同子类型 T 的数据视图。这将如何工作(即使它使事情变得复杂)?
  • @Sweeper 上面我的cmets中解释过,不可行。

标签: ios swift generics swift5


【解决方案1】:

您应该为 myData 属性设置一个对象,并且错误不会显示。

// Protocol example

public protocol MyDataProtocol {
    var dataParam: Codable? { get set }
}

class MyData: MyDataProtocol {
    var dataParam: Codable?
    init() {}
}

public class MyDataView: UIView {
    public var myData: MyDataProtocol?

    public override init(frame: CGRect) {
        print("test")
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

MyDataView(frame: .zero)


// Opaque example

public protocol MyDataProtocol {
    associatedtype T
    var dataParam: T? { get set }
}

class MyData: MyDataProtocol {
    var dataParam: Codable?
    init() {}
}

public class MyDataView: UIView {
    public var myData: some MyDataProtocol = MyData()

    public override init(frame: CGRect) {
        print("test")
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

MyDataView(frame: .zero)

【讨论】:

  • 不构建!
  • @DeepakSharma,请再次查看我的评论,我上传了一个截图,你可以看到它是为我构建的。
  • 好的,我看到它是使用 Codable 构建的,但不是使用我定义的任何专有协议。它给出了错误 - Protocol 'Interpolatable' 只能用作通用约束,因为它具有 Self 或关联的类型要求
  • @DeepakSharma,我的帖子已更新。因为你试图组合它,它不会以这种方式工作。你应该选择一种方式。如果使用 opaque,则必须返回当前对象。 docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html
  • @Deepak Sharma:如果你得到那个错误,那么你要么重新考虑你在做什么(@Sweeper 评论是现货......)否则你需要创建类型擦除的具体类型具有关联类型的协议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
  • 2020-06-11
相关资源
最近更新 更多