在不同类型的对象上的Swift 4 KeyPath

时间:2018-09-21 15:10:24

标签: swift keypaths

我有两种类型,AB,它们实现相同的方法并具有相同的属性。我定义了一个扩展,以为AB中的每一个获取子属性中的值。我想知道是否有一种方法可以将这两个扩展减少为一种方法。想象有更多的类型,例如AB,因此代码复制问题变得更加严重。

更新:AB与许多其他类似的对象一起生成。最初的计划是完全避免为AB编写扩展名。我不知道这是否可行,但被告知可以为此使用KeyPaths。属性名称必须不同。这是代码生成的副产物

struct A {
    var something: Common
}

struct B {
    var somethingElse: Common
}

struct Common {
    var value1: String
    var value2: String
}

extension A {
    func valueFor(condition: Bool) -> String {
      return condition ? self.something.value1 : self.something.value2
    }
}

extension B {
    func valueFor(condition: Bool) -> String {
      return condition ? self.somethingElse.value1 : self.somethingElse.value2
    }
}

2 个答案:

答案 0 :(得分:2)

我认为协议可以解决您的问题。它们有助于使代码更通用。

protocol CommonContaining {

    var common: Common { get set }

    func valueFor(condition: Bool) -> String {
      return condition ? self.common.value1 : self.common.value2
    }
}


struct A {
    var something: Common
}

struct B {
    var somethingElse: Common
}


extension A: CommonContaining {
     var common: Common {
         return something
    }
}

extension B: CommonContaining {
     var common: Common {
         return somethingElse
    }
}

答案 1 :(得分:-1)

据我了解,如果该方法与Common struct有关,那么您应该在struct本身中实现此方法或为struct创建扩展:

struct A
{
    var something: Common
}

struct B
{
    var somethingElse: Common
}

struct Common
{
    var value1: String
    var value2: String

    func valueFor(condition: Bool) -> String {
    return condition ? self.value1 : self.value2 }
}

var object_1 = A(something: Common(value1: "1", value2: "1"))
var object_2 = B(somethingElse: Common(value1: "1", value2: "2"))

print(object_1.something.valueFor(condition: true))
print(object_2.somethingElse.valueFor(condition: false)) 

祝你好运。