在swift中,如何返回符合协议的相同类型的对象
我有以下协议在swift中,如何返回符合协议的相同类型的对象,swift,return-value,swift-protocols,Swift,Return Value,Swift Protocols,我有以下协议 protocol JSONInitializable { static func initialize(fromJSON: NSDictionary) throws -> Self? } 现在我试图让这个函数返回任何符合协议的类。也就是说,如果我的类Foo符合协议,我想从方法返回Foo对象。我该怎么做 extension Foo: JSONInitializable { static func initialize(fromJSON: NSDictionar
protocol JSONInitializable {
static func initialize(fromJSON: NSDictionary) throws -> Self?
}
现在我试图让这个函数返回任何符合协议的类。也就是说,如果我的类Foo
符合协议,我想从方法返回Foo
对象。我该怎么做
extension Foo: JSONInitializable {
static func initialize(fromJSON: NSDictionary) throws -> Foo? {
}
}
我得到一个错误:
非最终类“Foo”中的方法“initialize”必须返回“Self”以符合协议“JSONInitializable”
自动完成将对您有所帮助,但基本上,如果
Foo
是一个类,您只需要一个与协议中方法的精确签名相匹配的方法:
class Foo {}
protocol JSONInitializable {
static func initialize(fromJSON: [String : AnyObject]) throws -> Self?
}
extension Foo: JSONInitializable {
static func initialize(fromJSON: [String : AnyObject]) throws -> Self? {
return nil
}
}
这里需要注意的是,在此方法中,您必须将Foo
的所有实例替换为Self
。如果要使用构造函数,则必须将其标记为必需
考虑到这一点,将协议更改为需要初始值设定项而不是名为initialize
的静态方法可能更有意义,在这种情况下,请查看。然而,这个答案回答了如何在协议中处理Self
的问题,因为在某些情况下,我们可能需要返回非初始值设定项的Self
的方法
如果
Foo
不是一个类,它是一个值类型,不能是子类,因此,我们返回类型的名称:
struct Foo: JSONInitializable {
static func initialize(fromJSON: [String : AnyObject]) throws -> Foo? {
return nil
}
}
对于类,需要从方法返回
Self?
的原因是继承。该协议声明,如果您遵守它,您将有一个名为initialize
的方法,其返回类型将是您所属内容的可选版本
如果我们像您编写的那样编写Foo
的initialize
方法,那么如果我们使用Bar
对Foo
进行子类化,那么现在我们已经破坏了对协议的一致性Bar
继承了来自Foo
的协议一致性,但它没有名为initialize
并返回Bar?
的方法。它有一个返回Foo
在这里使用
Self
意味着当我们的子类继承这个方法时,它将返回它们的任何类型Self
是Swift的等价物。如nhgrif回答中所述,将Foo?
的返回类型更改为Self?
或者
在Swift中,您可以在协议中声明init
s,因此请尝试以下操作:
protocol JSONInitializable {
init?(fromJSON: NSDictionary) throws
}
extension Foo: JSONInitializable {
required init?(fromJSON: NSDictionary) throws {
//Possibly throws or returns nil
}
}
因此,这将允许我从方法返回类型为
Foo
的对象?如果在Foo
的实例上调用它,它将返回Foo
。如果您将Foo
子类化为class Bar:Foo
,它将返回Bar
。我刚刚尝试了这个方法,现在当我尝试从该方法返回Foo
类型的对象时,它给出了一个错误。它说,无法将类型为“Foo”的表达式转换为返回类型为“Self”
我使用的是xcode 7.3,如果这有帮助的话,在这种方法中,您必须将Foo
的所有引用替换为Self
。如果你想使用一个构造函数,它必须是一个标记为必需的
。嗯,我有点不知道怎么做。我想做让f=Foo();返回f
。这就产生了错误。然后我尝试返回f.self()另一个错误。因此,我不确定现在返回什么,我认为您需要便利性
和必需
在该扩展中,您需要必需
。您不一定需要方便。还值得一提的是,Objective-C协议可以声明初始值设定项是协议的一部分。为了进一步阅读,。我只是尝试了这种方式,错误是我只能在非最终类的定义中这样做,即扩展不适用于进一步阅读required
关键字以及为什么需要它,@Smac89您在扩展之前已经声明了Foo
类了吗?如果没有,您可以在实现中包含协议,而不使用这样的扩展:Foo:JSONInitializable{required init?…}
protocol JSONInitializable {
init?(fromJSON: NSDictionary) throws
}
extension Foo: JSONInitializable {
required init?(fromJSON: NSDictionary) throws {
//Possibly throws or returns nil
}
}