我正在尝试为我的项目的 API 返回包装器类创建一个包装器。
这些是我的类(class)
class Wrapper<T> {
let message = "Hello World"
let wrapped = T.self
public func getData() -> T.Type {
return wrapped
}
}
class Object {
let number = 100
public func getNumber() -> Int {
return number
}
}
class SecondObject {
let name = "Second Object"
public func getName() -> String {
return name
}
}
我想实现的是,有什么方法可以像这样调用对象函数
let example = Wrapper<Object>()
example.getData().getNumber() // <<-- This is not working
let secondExample = Wrapper<SecondObject>()
secondExample.getData().getName() // <<-- This is not working
我的 Playground 的错误是这样的
error: instance member 'getNumber' cannot be used on type 'Object'
如果您注意到 Wrapper 类,则有消息属性将用于我所有的 API 返回对象模型
所以我的目标是,我可以简单地调用 Wrapper 类和我的对象模型类,然后调用对象模型类中的函数。
我仍在学习 swift 中的泛型。我在这里缺少什么?
最佳答案
您没有将 wrapped
设置为任何有用的值。您需要将其设置为 T
的实例。所以你可以将 T
传递给构造函数
class Wrapper<T>
{
let wrapped: T
init(wrapped: T)
{
self.wrapped = wrapped
}
}
或者你可以让类构造一个 T 的实例,但如果你想这样做,你需要告诉它如何构造实例。例如:
class Wrapper<T>
{
let wrapped: T
init()
{
self.wrapped = T() // << error!
}
}
不会工作,因为编译器对 T
一无所知,即使它有一个 init
。您可以使用协议(protocol)更改它
protocol Initable
{
init()
}
class Wrapper<T: Initable>
{
let wrapped: T
init()
{
self.wrapped = T()
}
}
并且您可以将该协议(protocol)应用到您喜欢的带有扩展名的任何类型。在大多数情况下,扩展名可以为空,因为 mot 类型已经有 init()
方法。例如:
class MyClass
{
init() { /* do stuff */ }
}
extension MyClass: Initable {}
class MyOtherClass
{
init(number: Int) { /* do stuff */ }
}
extension MyOtherClass: Initable
{
init() { self.init(number: 0) }
}
另一种选择是为包装器的初始化提供一个闭包。
class Wrapper<T>
{
let wrapped: T
init(factory: ()-> T)
{
self.wrapped = factory()
}
}
let w = Wrapper() { return Array<Int>() }
通常,如果您想创建多个实例,您只会这样做,即您会保留对闭包的引用,并在每次需要新实例时调用它。
关于swift - 通用类调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49005911/