首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我能做一些像ExpressibleByKeyPathLiteral这样的东西吗?

我能做一些像ExpressibleByKeyPathLiteral这样的东西吗?
EN

Stack Overflow用户
提问于 2019-03-12 04:33:30
回答 1查看 125关注 0票数 1

我可以像ExpressibleByKeyPathLiteral一样强制编译器为我装箱我的KeyPaths吗?或者这些协议使用了某种编译器魔法来使它们工作吗?

问题: Swift有ExpressibleBy*Literal协议族,允许编译器autoBox某些类型,如下所示:

代码语言:javascript
复制
struct Box: ExpressibleByIntegerLiteral {
    typealias IntegerLiteralType = Int
    let value: IntegerLiteralType
    init(integerLiteral value: IntegerLiteralType) {
        self.value = value
    }
}

func pbox(_ box: Box...) {
    for b in box {
        print(b)
    }
}

pbox(1,2,3)

我想知道是否有对Swift Keypath文本做同样的事情。例如,我有:

代码语言:javascript
复制
struct PartialEquatableKeyPath<Root> {
    let keyPath: PartialKeyPath<Root>
    let yieldsEqualValue: (Root, Root) -> Bool
    init<Value: Equatable>(_ keyPath: KeyPath<Root, Value>) {
        self.keyPath = keyPath
        self.yieldsEqualValue = { $0[keyPath: keyPath] == $1[keyPath: keyPath] }
    }
}

extension Equatable {
    func isEqual(to other: Self, byComparing keyPaths:[PartialEquatableKeyPath<Self>]) -> Bool {
        return keyPaths.allSatisfy { $0.yieldsEqualValue(self, other) }
    }
}

我不得不这样叫它:

代码语言:javascript
复制
let a = UIView()
let b = UIView()
b.isHidden = true
let keyPaths: [PartialEquatableKeyPath<UIView>] = [.init(\.isHidden), .init(\.frame)]
print(a.isEqual(to: b, byComparing: keyPaths))

我真正想要的是这样的东西:

代码语言:javascript
复制
extension Equatable {
    func isEqual<SomeEquatable: Equatable>(_ other: Self, byComparing keyPaths:PartialEquatableKeyPath...) -> Bool {
        return keyPaths.allSatisfy { $0.yieldsEqualValue(self, other) }
    }
}

所以我可以这样称呼它:

代码语言:javascript
复制
let a = UIView()
let b = UIView()
b.isHidden = true

print(a.isEqual(b, byComparing: \.frame.origin.x, \.isHidden))

有没有办法做到这一点?(我知道我可以让它与泛型一起工作,但前提是所有的KeyPaths都是同一类型的,这是非常有限的实用工具)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-12 23:08:44

我相信你在这里需要的是Variadic Generics,它在Swift中还不存在,但将来可能会存在。

作为一种变通方法,您可以创建采用一个键路径、两个键路径、三个键路径等的方法版本,直到您认为合理需要使用的最大数量(然后可能再使用一个)。您可以通过使用Sourcery生成变体来节省一些时间。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55109964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档