在swift中,我如何return一个符合协议的相同类型的对象

In swift, how do I return an object of the same type that conforms to a protocol

我有以下协议

protocol JSONInitializable {
    static func initialize(fromJSON: NSDictionary) throws -> Self?
}

现在,我正在尝试使 return 函数 class 符合协议。 IE。如果我 class Foo 符合协议,我想从方法中 return 一个 Foo 对象。我该怎么做?

extension Foo: JSONInitializable {
    static func initialize(fromJSON: NSDictionary) throws -> Foo? {
    }
}

我收到错误:

Method 'initialize' in non-final class 'Foo' must return 'Self' to conform to protocol 'JSONInitializable'

Autocomplete 会帮助你,但基本上,如果 Foo 是一个 class,你只需要一个与协议中的方法签名完全匹配的方法:

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
    }
}

这里需要注意的是,在此方法中,您必须将 Fooall 个实例替换为 Self。如果要使用构造函数,则必须将其标记为必需。

考虑到这一点,将协议更改为需要初始化程序而不是称为 initialize 的静态方法可能更有意义,在这种情况下,请查看 。但是,这个答案代表了如何在协议中处理 Self 的问题,因为在某些情况下我们可能想要一个 returns Self 不是初始值设定项。


如果 Foo 不是 class,它是一个不能子class 的值类型,因此,我们 return类型:

struct Foo: JSONInitializable {
    static func initialize(fromJSON: [String : AnyObject]) throws -> Foo? {
        return nil
    }
}
enum Foo: JSONInitializable {
    case One, Two, Three

    static func initialize(fromJSON: [String : AnyObject]) throws -> Foo? {
        return nil
    }
}

在 class 的情况下,您需要从方法中 return Self? 的原因是因为继承。该协议声明,如果您遵守它,您将拥有一个名为 initialize 的方法,其 return 类型将是您的可选版本。

如果我们像你写的那样写 Fooinitialize 方法,那么如果我们用 Bar 子 class Foo,那么现在我们破坏了我们对协议的遵守。 BarFoo 继承了对协议的一致性,但它没有称为 initialize 和 returns Bar? 的方法。它有一个 returns Foo.

这里使用Self的意思是当我们的子class继承这个方法的时候,它会return什么类型的。 Self 是 Swift 等价于 Objective-C's instancetype.

如 nhgrif 答案中所述,将 Foo? 的 return 类型更改为 self?

或者

在 Swift 中,您可以在协议中声明 inits,所以尝试这样的事情:

protocol JSONInitializable {
    init?(fromJSON: NSDictionary) throws
}

extension Foo: JSONInitializable {
    required init?(fromJSON: NSDictionary) throws {
      //Possibly throws or returns nil
    }
}