Swift中如何通过type(of:)获取可选类型的非可选类型?
获取Optional类型的原始包装类型(Swift)
嘿,这个场景我太熟悉了!Swift里的Optional本质是个枚举类型,直接打印它的类型会带Optional<>包裹,要拿到里面的原始类型,有几种实用的方法,我给你详细说说:
方法一:利用反射(Mirror)获取实际值的类型
如果你的Optional有值,Mirror可以帮你解析出它内部包装的元素,然后取这个元素的类型就行:
var check: Int? = 42 if let wrappedValue = Mirror(reflecting: check).children.first?.value { let rawType = type(of: wrappedValue) print(String(describing: rawType)) // 输出:Int }
要是你的Optional是nil,Mirror的children会是空数组,这时候可以结合泛型来处理(看方法二)。
方法二:泛型函数处理(支持nil的情况)
写个泛型函数,利用Optional的枚举特性(.some和.none),不管有没有值都能拿到原始类型:
func getUnderlyingType<T>(of optional: T?) -> Any.Type { switch optional { case .some(let value): return type(of: value) case .none: return T.self } } // 测试有值的情况 var check1: Int? = 42 print(String(describing: getUnderlyingType(of: check1))) // 输出:Int // 测试nil的情况 var check2: Int? = nil print(String(describing: getUnderlyingType(of: check2))) // 输出:Int
这个方法类型安全,不管Optional有没有值都能准确返回原始类型,是我最常用的方案。
方法三:字符串截取(不推荐,仅作补充)
如果只是需要字符串形式的类型名称,也可以直接对Optional<Int>这个字符串做截取处理,但这种方法不够类型安全,万一类型名称里包含<或>就会出错,只适合简单场景:
var check: Int? = 42 let fullTypeString = String(describing: type(of: check)) if let start = fullTypeString.firstIndex(of: "<"), let end = fullTypeString.lastIndex(of: ">") { let rawTypeString = fullTypeString[fullTypeString.index(after: start)..<end] print(rawTypeString) // 输出:Int }
总结一下,优先用方法二,类型安全还能处理nil的情况;方法一适合确定Optional有值的场景;方法三尽量少用,毕竟是字符串操作,不够可靠。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

