隐式设置关联类型

时间:2018-12-05 18:42:45

标签: swift generics swift-protocols associated-types

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

示例

此示例不起作用!这就是我希望它能工作的方式

protocol SomeTestProtocol {
    associatedtype T

    init(arg: T)
}

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

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

    // Use T outside the init-scope
}

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

所以主要问题是:我如何在不使用以下类的泛型的情况下,在下面的类的init-scope之外使用T,拥有对象时必须知道该类?

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

    // Use T outside the init-scope
}

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

重要说明,T中的associatedtype TT中的init<T>可以是不同的类型。它们都定义了具有不同作用域的通用类型,并且可能有所不同。如果您希望它们相同,则init应该为

init(arg: T)

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

typealias T = Int // or something

或将初始化实施为

required init(arg: Int)

如果您从协议中删除了associatedtype T,它将起作用。尽管这消除了SomeTestClass.T表单的存在。

答案 1 :(得分:0)

如果您在协议中声明关联类型,则该类型将在协议的不同实现上通用,但是每个符合条件的类都需要为该关联类型指定一个具体类型为typealias(可以通过使用具有相同具体类型的关联类型声明所有变量/函数来隐式完成),因此您的符合类型将不会是通用的。

如果要在符合条件的类中包含泛型方法,则需要使类本身成为泛型。

答案 2 :(得分:0)

如果您只想访问T之外的init,则只需将T存储在属性中即可。

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

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

因此,您首先需要使用TSomeTestClass。否则,就不可能讨论T的存储方式(如果您从未使用过,则存储是无关紧要的。)