Swift中如何通过字符串获取结构体属性值?
Swift中通过字符串key访问结构体属性的解决方案
这是个很典型的静态类型语言里动态访问属性的问题~Swift作为静态类型语言,编译器在编译期就需要明确知道你要访问的成员名称,所以直接写my_struct.i会报错——它找不到名为i的成员变量嘛。下面给你几个可行的解决办法,按需选择就行:
方法一:使用Mirror反射(通用方案)
Mirror是Swift里的反射API,可以帮你动态获取类型的成员信息。我们可以用它来遍历结构体的属性,匹配对应的key后取出值:
// 注意Swift里类型名建议用大驼峰命名哦 struct MyStruct { var informationA = "test" var informationB = "test...test" var informationC = "test...test" var informationD = "test...test..." } func getInformation() { let keys = ["informationA", "informationB", "informationC"] let structInstance = MyStruct() // 先创建结构体的实例 let mirror = Mirror(reflecting: structInstance) for key in keys { // 在Mirror的子属性中找到标签匹配当前key的项 if let matchedChild = mirror.children.first(where: { $0.label == key }), let value = matchedChild.value as? String { print(value) } } } // 调用测试 getInformation()
这个方法的好处是不用手动维护属性映射,新增属性后不需要修改遍历逻辑,但反射会有一定的性能开销,而且类型转换需要额外处理,适合属性较多或者需要通用处理的场景。
方法二:手动键值映射(高效安全)
如果你的结构体属性数量不多,手动写一个映射函数是更高效、更类型安全的选择——完全避免反射的开销,还能明确控制可访问的属性:
struct MyStruct { var informationA = "test" var informationB = "test...test" var informationC = "test...test" var informationD = "test...test..." // 自定义方法,根据key返回对应属性值 func value(forKey key: String) -> String? { switch key { case "informationA": return informationA case "informationB": return informationB case "informationC": return informationC case "informationD": return informationD default: return nil // 处理不存在的key } } } func getInformation() { let keys = ["informationA", "informationB", "informationC"] let structInstance = MyStruct() for key in keys { if let value = structInstance.value(forKey: key) { print(value) } } } getInformation()
新增属性的时候,只需要在value(forKey:)方法里加一个case分支就行,非常直观。
方法三:使用@dynamicMemberLookup(语法友好)
如果你想让结构体支持类似动态语言的点语法访问,可以用Swift的@dynamicMemberLookup特性,实现后就能用instance[key]甚至动态方式调用的语法:
@dynamicMemberLookup struct MyStruct { var informationA = "test" var informationB = "test...test" var informationC = "test...test" var informationD = "test...test..." // 实现动态成员查找的下标方法 subscript(dynamicMember member: String) -> String? { switch member { case "informationA": return informationA case "informationB": return informationB case "informationC": return informationC case "informationD": return informationD default: return nil } } } func getInformation() { let keys = ["informationA", "informationB", "informationC"] let structInstance = MyStruct() for key in keys { // 两种写法都可以:下标方式或者动态成员方式 if let value = structInstance[key] { print(value) } // 也可以写 structInstance.dynamicMember(key) } } getInformation()
这个方案兼顾了语法友好和类型安全,适合需要频繁动态访问属性的场景。
内容的提问来源于stack exchange,提问作者Jonas0000
相关产品推荐
相关产品推荐

