【问题标题】:implicitely set an associated type隐式设置关联类型
【发布时间】:2018-12-05 18:42:44
【问题描述】:

我试图弄清楚如何在一个类中隐式设置一个 Generic(参数的类型)而不将整个类的类型更改为 SomeTestClass 之类的东西,其中对象的所有者必须知道泛型的类型。

示例

这个例子不起作用!这就是我希望它的工作方式

protocol SomeTestProtocol {
    associatedtype T

    init(arg: T)
}

不想使用 SomeTestClass 因为拥有这个班级的班级 不知道所使用的泛型类型

class SomeTestClass: SomeTestProtocol {
    required init(arg: T) {
    }

    // Use T outside the init-scope
}

注意:协议只是一种变通方法的尝试!最终解决方案没有必要

所以主要问题是:如何在不使用类泛型的情况下在下面的类的初始化范围之外使用 T,而拥有一个对象时必须知道这一点

class SomeTestClass2/*< T>*/ {
    init(arg: T) {
    }

    // Use T outside the init-scope
}

感谢您的帮助!

【问题讨论】:

  • “如何在不使用类泛型的情况下在下面的类的初始化范围之外使用 T,而拥有一个对象时必须知道这一点” 不清楚这些词的含义。泛型的占位符类型必须始终编译时解析。 当然类型是已知的。这就是泛型。它不是白板。它只是一个占位符表达式,用于简写表示两种类型是同一类型。
  • 在这里继续 matt 的观点:泛型和 PAT(带有关联类型的协议)都包含类型参数。它们之间的区别在于,在泛型中,实例的创建者决定类型值,而在 PAT 中,实现的创建者决定类型值。有人必须决定类型值。您要决定的人是您如何决定是使用泛型还是协议。 (在 Swift 中 90% 的情况下,答案都是通用的。)

标签: swift generics swift-protocols associated-types


【解决方案1】:

重要提示,来自associatedtype TT 和来自init&lt;T&gt;T 可以是不同的类型。它们都定义了具有不同范围的泛型类型,并且可能不同。如果您希望它们相同,则 init 应为

init(arg: T)

如果SomeTestClass总是使用相同的类型,你可以添加

typealias T = Int // or something

或将初始化实现为

required init(arg: Int)

如果你从协议中去掉associatedtype T,它就可以工作。虽然这会删除 SomeTestClass.T 表单的存在。

【讨论】:

  • 我不想在类本身中硬编码类型。它应该通过参数在类的init-Method中设置。这甚至可能吗?
【解决方案2】:

如果您在协议中声明关联类型,该类型将在协议的不同实现中成为通用类型,但每个符合标准的类都需要将具体类型分配给该关联类型作为 typealias(可以这样做通过使用具有相同具体类型的关联类型来隐式声明所有变量/函数),因此您的符合类型将不是通用的。

如果您想在符合标准的类中使用泛型方法,则需要将类本身设为泛型。

【讨论】:

    【解决方案3】:

    如果您只想在init 之外访问T,那么您只需将T 存储在一个属性中:

    class S {
        let theType: Any.Type
        init<T>(arg: T) {
            theType = T.self
        }
    }
    

    我怀疑您实际上想要的东西与您所说的想要的不同。我怀疑你想存储arg。但如果是这样,如果您不知道arg 的类型是什么,您打算做什么?你可以调用什么方法?它可以是什么函数的返回值?如果不诉诸 as?,则使用 T 将无济于事(依赖 as? 通常意味着您误解了您的类型)。

    因此,您需要从您希望如何使用TSomeTestClass 开始。没有它,就不可能讨论应该如何存储T(如果你从不使用它,存储就无关紧要了)。

    【讨论】:

      猜你喜欢
      • 2019-04-30
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      • 1970-01-01
      相关资源
      最近更新 更多