迭代Swift中的对象类属性

时间:2014-08-23 14:48:37

标签: swift

Swift中是否有一种简单的方法来迭代类的属性。

即。我有一个Person类,它有3个属性:name,lastname,age。

有类似

的东西
for attribute in Person {
     println("\(attribute): \(attribute.value)")
}

输出将是例如:

name: Bob
lastname: Max
age: 20

5 个答案:

答案 0 :(得分:51)

他们已经删除了Swift 2.0中的反射。这就是我枚举属性和值的方式。

class People {
    var name = ""
    var last_name = ""
    var age = 0
}

var user = People()
user.name  = "user name"
user.last_name = "user lastname"
user.age = 20

let mirrored_object = Mirror(reflecting: user)

// Swift 2
for (index, attr) in mirrored_object.children.enumerate() {
    if let property_name = attr.label as String! {
        print("Attr \(index): \(property_name) = \(attr.value)")
    }
}

// Swift 3 and after
for (index, attr) in mirrored_object.children.enumerated() {
    if let property_name = attr.label as String! {
        print("Attr \(index): \(property_name) = \(attr.value)")
    }
}
  

输出:
  Attr 0:name =用户名
  Attr 1:last_name =用户姓氏
  Attr 2:年龄= 20

答案 1 :(得分:12)

是的,如果您只需要打印结构或类的属性,并且属性是简单类型(如String和Int),则可以使用reflectMirrorType

func print_properties(mirror: MirrorType) {
    for i in 0..<mirror.count {
        let (name, childMirror) = mirror[i]
        let value = childMirror.value
        println("\(i): \(name) = \(value)")
    }
}

struct Person {
    let first_name: String
    let last_name: String
    let age: Int
}

let john = Person(first_name:"John", last_name:"Doe", age:27)
let mirror = reflect(john)
print_properties(mirror)

如果你有嵌套的结构,枚举,你需要做更多的工作。

答案 2 :(得分:4)

正如@mohacs建议的那样, 您可以在所需的类中提供函数描述,如下所示;

10

然后简单地调用此实例方法

func description() -> String{

        let mirrored_object = Mirror(reflecting: self)
        let str:NSMutableString = NSMutableString()
        for (index, attr) in mirrored_object.children.enumerated() {
            if let property_name = attr.label as String! {
                str.append(" Attr \(index): \(property_name) = \(attr.value)")
            }
        }
        //print("desc=\(str)")
        return str as String
    }

答案 3 :(得分:3)

Apple没有删除reflect,他们只是将其更改为_reflect,他们也将MirrorType更改为_MirrorType。 Swift 2.0版本的@Teemu Kurppa代码:

func print_properties(mirror: _MirrorType) {
  for i in 0..<mirror.count {
    let (name, childMirror) = mirror[i]
    let value = childMirror.value
    print("\(i): \(name) = \(value) ")
  }
}

struct Person {
    let first_name: String
    let last_name: String
    let age: Int
}

let john = Person(first_name:"John", last_name:"Doe", age:27)
let mirror = _reflect(john)
print_properties(mirror)

答案 4 :(得分:1)

这里是对象描述的Swift 5版:

class TestClass: CustomStringConvertible {

    public var description: String {
        return Mirror(reflecting: self).children.compactMap({
            if let label = $0.label {
                return "\(label): \($0.value)"
            }
            
            return ""
        }).joined(separator: "\n")
    }
}