Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the unwrapped type from an optional type in Swift?

Tags:

swift

swift2

I'm trying to get an unwrapped type from an optional type in runtime. The following code would print the type of a as Optional<String>.

class MySubClass: MyClass {

    var a: String? = nil
}

var a = MySubClass()

let mirror = Mirror(reflecting: a)
for child in mirror.children {
    print(child.value.dynamicType)
}

Now I want to unwrap the type and get String, what should I do to make this happen in runtime?

like image 738
Zhu Shengqi Avatar asked Dec 06 '15 08:12

Zhu Shengqi


People also ask

How to unwrap an optional variable in Swift?

If you know that an optional definitely has a value, you can force unwrap it by placing this exclamation mark after it. If you defined a variable as optional, then to get the value from this variable, you will have to unwrap it. Putting an exclamation mark at the end of the variable. var mycodetipsString:String? mycodetipsString = "Hello, Swift !"

What is the default value of null in Swift?

However there is another data type in Swift called Optional, whose default value is a null value (nil). You can use optional when you want a variable or constant contain no value in it. An optional type may contain a value or absent a value (a null value). Non technically, you can think optional as a shoe box.

What is the difference between Objective C and Swift optionals?

In Objective-C, C-based variables (primitives) always had to have a value, but object types could either be a valid object, or a pointer to nil. Swift optionals allow you to make any type in Swift into a nil-able type (though this nil is not exactly the same as an Objective-C nil).

How do you use optionals in Swift?

One way to use Swift Optionals in places that don’t take them, is to forcefully change them back into normal variables. Apparently you question a variable to make it into an optional, and you yell at at it to forcefully unwrap it: Yep, that exclamation point forcefully unwraps it. There is a problem though.


1 Answers

Assuming you have an optional

let someVar: String?

then print(type(of: someVar)) will print

Optional<String>

but if you add the following extension to Optional

protocol OptionalProtocol {
 func wrappedType() -> Any.Type
}

extension Optional: OptionalProtocol {
 func wrappedType() -> Any.Type {
   return Wrapped.self
 }
}

then print(someVar.wrappedType()) will print

String

No reflection whatsoever


Summary

As long as the optional is not referenced by Any or AnyObject the code will work fine.

For Any you will have to cast it to OptionalProtocol first. Running

let someVar: String?
let anyVar = someVar as Any

if let op = anyVar as? OptionalProtocol {
    print(op.wrappedType())
}

will print

String


As for AnyObject, strangely enough (at least for me), it doesn't cast to OptionalProtocol.


The original StackOverflow answer can be found here

like image 59
tonymontana Avatar answered Sep 22 '22 08:09

tonymontana