Opaque types: Masking your concrete types

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello guys welcome to another video if you have followed my channel recently you maybe wonder why we talk about protocols and generic in that order it turns out that all the things we explore in swift tips are not a coincidence i prepare for you a series of videos about protocols and generics because today we want to talk a special concept that requires those previous concepts if you haven't watched those series i will leave in the description the series of protocols and generics for you but today we're going to talk about opaque types opac types is a really important concept in swift especially because it's the enabler of swift ui yeah we're going to explore that and also we're going to find out why we require that zone view return type in our body in swift ui so let's get started and before that i wanted to share something really interesting this video is very special for me because it was the foundation of creating this channel so let's get started my name is pete and this this is swift tips [Music] all right let's start first talking about oppac types what are object types well in a short sentence oppac types basically hide a concrete type information returned by a function or a computer property okay that sounds cool but how we can apply that in our real development let's start with the most common example that we can found right now which is using swift ui and specifically using body because body is a computer property that is using some view which means that this thing is returning an apac type but yeah swift ui was introduced along with swift 5.1 because that version of swift introduced some keyword and at the same time oppac types but let's imagine for a moment we don't have some keyword and we don't have a backtypes so then what are our options before swift 5.1 only basically we have one option which is use view directly however if you already watched my previous videos you cannot do that because this is a special protocol yeah we use a protocol and is using an associated type body which is the type of this verb computed property body so no that's not possible so the only remaining thing we have here is returning the concrete type here so in this case we have a text then if we return text yeah we're good to go let's try that in the preview yeah it's working nothing happens cool but now what will happen if we add a b stack for example and we want to display a list let's see that in action yeah look at that we are getting an error because yeah i'm saying that this thing b stack double b blah blah blah blah is not a text yeah it's right we are sending here that we're returning a body with type t but actually this is not a text not a text anymore yeah text is inside of this b stack but now the exposed type concrete type is a p stack of couple of things here a couple of pills so yeah okay let's transform this into into the concrete type okay now yeah we have a b stack double b with a pair of text and list with never for oh my god okay yeah you may notice two things here one since that we are working with generics yeah generics are all around and yeah the options here about b stack list and other kind of views yeah contains generics inside because we can transform and create any kind of view yeah we have this thing here this concrete type swift in first all these types and then we actually end with a massive long concrete type but yeah but this is not practical law that's one thing and the second thing is do we actually need to expose this to recolor so for example imagine that you export this or let's imagine that we don't have opaque types at all this will be your other option so yeah this kind of thing is kind of a private api so it's a part of an internal transformation that you have and we shouldn't care about that right this is a view so that's the only thing we care but even worse if you actually modify this just like this now your turn type is invalid again yeah so complex for xcode to invert this yeah this is not convenient at all but fortunately we have object types to the rescue yeah so here the purpose of opaque types like i mentioned before is hiding this concrete implementation when we explicitly say some view what we have to do is just make in some kind of reference that this thing is confirming view we are not working with a protocol this is actually a concrete type as you saw earlier but this thing is kind of a mask of your concrete type so in other words the color of this body shouldn't care about the concrete type so the only thing we will see is that this is some view which view i don't care because the only thing we care is that we are working with a view that's it that's a very important difference because if you use explicity a protocol and we will see that in a moment when you work with protocol type that's one thing but here the main difference between that and oppac types is that you are working with a concrete type but you don't want to expose the final transformation of your concrete type or your private api you don't want to expose that in this case we are just saying this is some view pretty cool but this is only valid for gpi of course not this is part of the swift language not the framework let's see more examples that don't require actually swift ui alright let's move on to an example that is not including swift ui let's transform an array of strings into ins if it's possible alright let's work on that and let's figuring out the actual result value provided by the method we will create ok we want to return the array or transformed after other operations now the question is what are operations well let's use in this example something called lazy lacy for this array will provide operations on demand what that means is that we're not going to apply all the operations for example map or something else to the horror array at that time we will wait until someone else will require a specific numbers of elements in the array that's a great way to save time especially if you are leading with a big array okay so we have lazy here but we want to convert this array of strings into ins so for that let's use compact map compact map is an operation that will filter all the nil values and we want that because some strings could be wars or something else symbols but not actually numbers so here i'm sending in a closure what is the transformation operation so the only thing is just casting to it okay that's cool so the only last thing is we want to drop we want to drop some values depending if the condition we provide is true or false so for that the only thing and for this example we want to drop all elements below 10. and that's it but as you can see we have an error because yeah we are returning a value but this uh transform to int function is not returning anything so yeah we need to specifically say that we want to return something but the question is what is there to value let's put something random here and see what is the error yeah as you saw earlier in swift ui demo in this case we have a gigantic type oh my god i need an ultra wide screen to read this in one line yeah this is a lazy drop while sequins lacy map sequel okay i'm so lazy to read this but yeah you got the idea you don't want to expose this to the color why should i care about this i mean these are only operations internal operations i want to transform this and i want to return you know i want to get an array of strings so yeah i don't i don't shouldn't care about this these elements so okay what are the options well one option is use this which is not convenient again but the only thing is mask this concrete type without types and to do that let's find out what is the pattern here what is the actual protocol that we can use well if you might notice all of these things are sequenced so all of these operations confirms to sequence so instead of this let's transform this into some sequence and that's pretty cool let me go back just for a moment to the previous computer type if you had more properties here with this implementation look at this yeah we receive another error here because this concrete type is not valid anymore so for every action you should also change certain values so yeah that's no good okay cool let's try this and see where is the result okay as you can see we have 20 here and makes sense because compact map basically drops bit name here and we are dropping also with this condition all things below 10 so the only remaining value is 20 and the actual type is some sequence which is great we shouldn't care about what is the all transformation behind this this method so the color in this case value is not taking consideration about that but the great thing is that we are using a concrete type which is a great advantage for swift because we can get optimizations for the compiler yeah pretty cool in the last episode we saw this challenge we created a merge function that provides two containers which both parameters confirms stack protocol and we return at the end an oppac type of some stack but what is the magic behind this well as i mentioned earlier this opaque type is hiding what is the concrete type in this case we are talking about new container which is type of my stack container one dot element and all those things are you know using the word clause that we saw in the previous episode okay i want to just clarify what will happen here let me go back here if you don't remember this code we have a protocol here stack with an associated type element and then we have this concrete implementation confirming stack so one little big thing here is that we have a protocol with associated type but as we mentioned many times earlier we cannot directly send any return type in this way because this protocol contains a necessary type and we are missing information we are not providing the information to swift to infer what is associated type in this case okay but with this opac type we are not actually providing that protocol we are not sending a protocol however we are sending a concrete type and that concrete type specifically is confirming stack so in other words swift already knows that we are sending a concrete type this is basically like if we if we do this yeah as you can see everything is working but we are hiding that information to the color in this case which is awesome you finally can send any protocol with the associated type in this way but just remember again you are not sending the protocol type you are sending a concrete implementation and let me show you that here we have the the colors from the last episode and here we have stack six that is calling merge so let me show you with type of what is the actual type of stack 6 there you go we have a my stack of int int is inferred by swift because we are providing work clauses here and yeah both containers should be the same so in this case we are sending two main stack of int then at the end we are dealing with a my stack of int too but this is protected this is headed for the color and we are just showing some stack by default so in other words if we want to force this to other thing for example my stack i don't know string let's see the error xcode it's saying that we cannot convert some stack to a specific type my stack of hint but what will happen if we change this to int let's see that oh look at that we cannot do that even that this is the correct type for this concrete implementation but let's see the error yeah this is because again we are protecting to the color to modify or return type or or complete implementation because that was made by the function itself and this is really cool if the well depending of your requirements this is called reverse generics probably you could not understand this right away but it's really simple for example here you could actually write this declaration in this way because here this is my stack but we are dealing with our generic item however we are giving the color the option to modify or you know specify what is the concrete type for this generic type this is cool and this is the normal way to use generics however in this case we are doing the opposite because in the previous example here my stack is depending on the color to figure out the type right which in this case yeah we are saying oh this is the int value for for my stack but here no no yeah the kali in this case is getting the control of what is the right type to send to the color yeah in the color shouldn't care about just using the type and that's it which is pretty cool so it's one technique that you can use in your implementation if it's required pretty cool right all right let's talk a little more about protocols versus opaque types there are a big difference and let me show you a couple of use cases depending of your implementation here we have protocol animal and we have two structs dog cat so what we want to do is create two methods one with the back types and one returning a protocol and see what's the difference all right as you can see in both cases we got cat in the print statement however there are two main difference one yeah we are returning a protocol a regular protocol and if we see that in pet 2 yeah this is an animal however but one is some animal but as we talked earlier the big difference here is that this still has a protocol for swift so swift needs to figure out that at runtime however here we're working with a concrete type and remember this sum animal is masking the concrete type is equivalent to do that in some way so yeah that's a big difference and some optimization happens here at the compilation time but what will happen if we want to return multiple types in both functions let's see that let's create a random boolean just to send a doc in one case and i get another one okay yeah here we have a problem this is not possible because we are making reference to a concrete type here so we have two resin types from different concrete types this is not possible however here with the protocol since that anything that could fit the conforming animal protocol can be returned there's no problem at all so yeah this is one big limitation with opaque types but honestly it will depends of your requirements because i'm not saying this is totally wrong so both approaches are okay but will depend of your requirements just think about that let me show you one more thing we saw that sending a protocol as a type is so flexible but that flexibility comes with a trade-off and what will happen for example if we want to compare two protocols so if we want to do that let's see what happened we know already that pet 2 and pet 3 are equivalent so let's see that whoops yeah here we cannot compare directly because we need the protocol equitable for this action so okay let's do that let's put equitable and confirm animal to acquittal protocol however yep we got this issue again we cannot do that directly so yeah that's it so what we can do here well actually it will depends of what you want to do but yeah if you want to flexibility then you can not compare two different types at the same time i just wanted to show you this because could be important in some situations and if you know this already before implementing your code will be better and maybe save you a lot of time i will leave in the description more information if you want to read more articles and especially the proposal for swift when this was introduced when we create any view in swift ui we are getting by default this body okay and this body has some view we saw earlier why we have this but i don't know if you noticed that at the beginning let's go back here to protocol view and as you can see we are not saying anything about some view here or some whatever this is because you cannot use some or you cannot use actually oppac types in protocols at this moment in swift 5.3.3 we cannot do that probably in the future we can see this in action in swift but for now just think about it it's something that i wanted to show you so instead of then seeing this associated type body xcode is providing you the template for some view this is where you can modify some view or return the concrete implementation the concrete return type here and you still getting a good signal from mexico because you are not breaking your protocol requirements this is not part of the of the requirement this is something additional that xcode is providing you that's it for this video remember opaque types are really great if you want to protect or hide concrete implementation in your apis it's very specific for some kind of problems but is a greater region especially because we have swift ui nowadays if you really know this information about opec types and this video was useful for you please let me know in the comments and don't forget to subscribe and leave your like because it's for me a signal that those videos are really useful for you so that's it for me and don't forget to follow me on twitter swiftontips thank you so much and have a great day you
Info
Channel: Swift and Tips
Views: 789
Rating: 4.9024391 out of 5
Keywords: swift and tips, swift && tips, Opaque types, swift, swiftlang, swift 5.1, some View, hide your private api, protocols, generics, ViewBuilder, reverse generics, SwiftUI, protocols vs opaque types, swift language
Id: C4WQFU7QrmM
Channel Id: undefined
Length: 22min 17sec (1337 seconds)
Published: Sat Apr 17 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.