0

我正在尝试将具有相同属性的不同类传递给相同的函数。我如何将它们转换为与此功能一起使用?

下面是一个简单的例子来突出我想要实现的目标。

class A {
    var height:Int = 10
}

class B {
    var height:Int = 20
}

class C {
    static func grow(class:AnyObject) {
        class.height + 5
    }
}


C.grow(A)
C.grow(B)

两个最终调用应产生 15 和 25,但如果没有将 AnyObject 转换回 A 或 B,则会生成如下错误:“AnyObject 没有命名成员”。

我该如何完成这样的事情?

4

2 回答 2

1

看起来像是一个协议的好案例!定义一个具有高度属性的,让 A 和 B 都实现该协议,然后让增长方法接受该协议作为其参数。

于 2016-03-29T21:27:03.923 回答
1

Swift 反射 API 使您能够读取值但不能修改它们。因此,如果这对您来说已经足够了,您可以使用类似于以下的方法,它需要一个对象和您要访问的成员的标签:

func getValue<T>(object: AnyObject, memberLabel: String) -> T? {
    let mirror = Mirror(reflecting: object)
    for member in mirror.children {
        if let _ = member.label where member.label == memberLabel,
           let value = member.value as? T {
            return value
        }
    }
    return nil
}

但是如果你想修改这些值,你必须定义一个协议并使类符合它:

protocol HasHeight {
    var height: Int { get set }
}

extension HasHeight {
    mutating func grow() {
        self.height += 5
    }
}

class A : HasHeight {
    var height = 10
}

class B : HasHeight {
    var height = 20
}

var a = A()
print(a.height)
a.grow()
print(a.height)

var b = B()
print(b.height)
b.grow()
print(b.height)

在这里,我将其定义grow()为协议扩展,以便在符合HasHeight协议的每个类/结构上都可以使用它。

结果是:

10

15

20

25

您可以在别处定义它,但必须更改调用以包含&引用:

func grow<T: HasHeight>(inout sized: T) {
    sized.height += 5
}

grow(&b)
于 2016-03-29T22:05:33.547 回答