Optionals i Swift: set med et C# øje
Swift er et nyt programmerinssprog for iOS baserede enheder. Jeg hører ofte en udtalelse, at Swift minder om C#. Og den er ikke grundløs, det kan mærkes, at Swift er inspireret af C# og føles som om man roder med et nyt .Net sprog. Swift har en indbygget mekanisme, som sørger for at de variabler, der ikke bruges længere, slettes automatisk, så man behøver ikke at holde styre på maskine resurser. Denne mekanisme er kendt som "garbage collector" i .Net. Swift er et selvstændigt sprog, produceret af Apple, som en naturlig efterfølger af Objective C. Man kan altså fortsat bruge Objective C, men Swift er relativt nemmere at lære og derfor kommer der mere og mere kode til at blive skrevet på Swift med tiden.
Lige som i .NET, kan en variabel være enten af en værdi type (value typed) eller af en reference type (reference typed). Værdi typer bliver initialiseret med en standardværdi, når de bliver erklæret i koden. Derved kan man ikke erklære en værdi type som ikke indeholder en værdi. Apple har kommet med sit eget svar på dette problem, som minder om "nullable types" i .Net, men alligevel ikke det samme. For eksempel:
var optionalValue: Int?
Den ovenstående sætning erklærer en numerisk variabel med en valgfri værdi. Når Swift compiler kører denne linje, får optinalValue en blank værdi (nil). Man bør verificere, at valgfri typer indeholder en værdi før variablen kan bruges. Det kan man gøre med følgende if-sætning:
if optionalValue {
println("\(optionalValue!)");
} else {
...
}
Læg mærke til udråbstegnet (!) efter vores variabel, dette lille tegn fortæller compileren, at variablen er typesikker og indeholder en værdi. Hvis compileren møder en variabel med et udråbstegn, som ikke er initialiseret, vil der blive genereret en fejl. Swift byder på en nyttig konstruktion, som hjælper med at bruge en valgfri variabel uden at skulle verificere indholdet hver gang:
if let unwrappedOptionalValue = optionalValue {
println("\(unwrappedOptionalValue)")
}
På den måde kan unwrappedOptionalValue blive brugt inden for if-sætningen uden risiko for at variablen kunne indeholder en blank værdi. Generelt er if-let-sætning brugt meget bredt i Swift. Den næste nyttige operator er et spørgsmålstegn (?). Hvis en sætning, der er efterfulgt af et spørgsmålstegn, er falsk eller indeholder en blank værdig (nil), så kører compileren videre til næste sætning uden at generere en fejl.
if let navController = self.menuController()?.mainViewController as? UINavigationController {
if navController.topViewController.isKindOfClass(SKAboutViewController) {
self.menuController()?.removeGestures()
}}
I den ovenstående konstruktion, verificerer vi først, at self.menuController() ikke er falsk eller ikke er lige med nil. Hvis dette er tilfældet, bliver if-sætningen sprunget over. Bagefter konverterer vi værdien til UINavigationController type ved brug af as?-sætningen. Derved, bliver indholdet af If-sætningen kun eksekveret hvis mainViewController variabel har UINavigationController typen eller er nedarvet af denne type. Man bør bruge as?-sætning hvis man ikke ved præcist om variablen kan konverteres til denne type. Der bliver ikke kastet nogen fejl hvis variablens type ikke er som forventet. Men hvis man er helt sikker, at konvertering altid vil være succes, så bør man bruge as!-sætning.
let navController = self.menuController()?.mainViewController as! UINavigationController
Hvis mainViewController ikke kan konverteres til UINavigationController, vil der blive kastet en fejl.