Structures 101 In Swift

2015-12-22

Structures is not another type in swift. If you have background in C or objective C you will be impressed with the functionality of structs in swift. Structures have initialisers, methods, comfort to protocols have extensions…convinced?

Well, if start thinking that are like classes you are right but…only similar. Major difference is that structures are value types yet classes are reference types. When you assign a structure to another you essentially copy it, but in classes you share it because both instances will point to same address. ??Additionally, classes supports inheritance but structures not.

Feel confused? You shouldn’t. Lets start with the basics. The structure groups relevant elements??in one entity. Imagine a point in a 2D plane. If you have an app and you represent the point having two individual variables is not so easy and practical…try it if you don’t believe! The solution is to use structures (or structs).

Lets define it: [sourcecode language=“objc”] struct Point { var x: Int var y: Int } [/sourcecode] Easy. Use the keyword struct, then the name and inside the curly braces the implementation, means member properties and later methods. So, this is the blueprint of the custom type Point. The creation of a real instance of a point is like that:

[sourcecode language=“objc”] let p1 = Point(x: 1, y: 2) [/sourcecode] Exactly, swift automatically creates a vanilla initialiser. So now you can instantiate your points and access its content using the dot syntax way. So…

[sourcecode language=“objc”] p1.x = 5 [/sourcecode] No! you can’t do this. Don’t forget that p1 is let, which means constant and you don’t have the permission to change it. The correct way is: [sourcecode language=“objc”] var p2 = Point(x: 2, y: 5) p2.x = 3 [/sourcecode] so now the p2 will have x equal to 3 and y as before. By looking to points, personally, it reminds me the tuples. Could I have an initiliazer using tuples? Of course!

[sourcecode language=“objc”] struct Point { var x: Int var y: Int init(point: (x: Int, y:Int)) { self.x = point.x self.y = point.y } } [/sourcecode] And you can use it like: [sourcecode language=“objc”] let p2 = Point(point: (1, 1)) [/sourcecode] At this point if you try to use the first swift-free initializer you will get an error. What happened?? Since you included a custom initializer in your design the free one becomes unavailable and you should implemented by hand. It’s not difficult at all.

[sourcecode language=“objc”] struct Point { var x: Int var y: Int init(point: (x: Int, y:Int)) { self.x = point.x self.y = point.y } init(x: Int, y: Int) { self.x = x self.y = y } } [/sourcecode] Very nice! In case that you noticed self keyword and you want some explanation about that. Lets go the opposite way. Without self keyword the standard initialiser would look like:

[sourcecode language=“objc”] init(x: Int, y: Int) { x = x y = y } [/sourcecode] Sorry, it’s not possible to differentiate if x is the member property or the function’s input parameter. By using self we declare that x and y are the instance’s properties. Now its clear and compiler will not complain.

The point was a simple struct but the real beauty comes when we use simple structs to build more complex. For instance, we can define a struct to represent circle.

[sourcecode language=“objc”] struct Circle { var center: Point var radius: Int } [/sourcecode] In this struct we use Point as member property. The instantiation of two new circles will look like:

[sourcecode language=“objc”] var cir1 = Circle(center: p1, radius: 20.0) var cir2 = Circle(center: Point(x: 1, y: 1), radius: 10.0)[/sourcecode] In case that we want to access the properties of the Point which acts a centre for the circle se should use the dot syntax again:

[sourcecode language=“objc”] let myX = cir2.center.x let myY = cir2.center.y [/sourcecode] Up to this point we haven’t said anything about methods. Yes, structures can own functions which act as methods (like in classes). Every instance can employ its methods to do various calculations. For instance: [sourcecode language=“objc”] struct Circle { var center: Point var radius: Double func area() -> Double { return M_PI * pow(radius, 2) } } [/sourcecode] and we can use it like: [sourcecode language=“objc”] var cir2 = Circle(center: Point(x: 1, y: 1), radius: 10.0) let circleArea = cir2.area() // 314.1592 [/sourcecode] Bonus!

In case that you have knowledge about properties in swift ( if not there is a properties 101 coming!), as you guess it, structs support computed properties as well. The area() of the last example could be easily implemented as such:

[sourcecode language=“objc”] import Darwin // to get access to M_PI struct Circle2 { var center: Point var radius: Double var area: Double { return M_PI * pow(radius, 2) } } var newCir = Circle2(center: Point(x: 1, y: 1), radius: 10.0) let newCircleArea = newCir.area [/sourcecode] Now it’s your turn to experiment and get the hang of it. If you want to use article’s (Attachment missing: (Attachment missing: structures101)) please be my guest!