允许可选对象使用类扩展功能Swift

时间:2019-06-11 07:32:37

标签: swift

我不确定如何以更适当的方式来构造问题,并且存在非常相似的问题,但是它们并不能完全给我答案。

我想做的事情非常简单。我有一个模型:

struct Person: Codable {

...
    // And I have a func, or let's put it in an extension:

    func isEqual(to person: Person?) -> Bool {
      return self.id == person?.id
    }

}

它的用法是这样,不用理会:

let person1: Person!
let person2: Person?
person1.isEqual(to: person2)

但是我需要该函数将第一个对象接受为可选对象,例如:

let person1: Person?
let person2: Person?
person1?.isEqual(to: person2)

问题是,如何使此类函数将第一个对象接受为可选对象?

2 个答案:

答案 0 :(得分:3)

您问:

  

问题是,如何使此类函数将第一个对象接受为可选对象?

以“第一个对象”为例,我想你的意思是person1

您不能使该函数接受“第一个对象”(接收者,person1)作为可选对象。该函数在类型Person上定义,但是person1的类型为Optional<Person>

可以做的操作是Optional<Person>上定义方法,如下所示:

extension Optional where Wrapped == Person {
    func isEqual(to person: Person?) -> Bool {
        // If I’m `.some`, call through to my wrapped value’s isEqual(to:).
        // If I’m nil, I’m only equal to person if person is also nil.
        return self?.isEqual(to: person) ?? (person == nil)
    }
}

使用此方法(以及在isEqual(to:)上定义的现有Person),您可以同时在isEqual(to:)Person上调用Person?

答案 1 :(得分:1)

我要做的是用通用参数Optional的条件扩展Wrapped枚举

这就是它的样子

class User: Codable {
    var name: String
    var id: Int
    var age: Int

    ...

    func isEqual(to user: User) -> Bool {
        return self.id == user.id
    }
}

extension Optional where Wrapped == User {
    func isEqual(to user: User?) -> Bool {
        return self?.id == user?.id
    }
}

并且由于该方法使用的是不同类型的OptionalUser,因此您可以使用点表示法,而无需使用可选链接。例子

let user1: User? = nil
let user2: User? = nil
let bool = user1.isEqual(to: user2)