This workshop will be retired on May 31, 2020.
Strings7:32 with Pasan Premaratne
There are lots of changes to Strings in Swift 4. In this video we're going cover some of the main ones including multi line string literals, collection conformance and string slicing.
In this video, let's take a second to talk about strings. 0:00 Swift 4 takes yet another pass at cleaning up strings, bringing back some of 0:03 the behavior from Swift 2, but with much better implementation details. 0:08 There's several changes here spit across different proposals, so 0:13 let's start with the simpler one. 0:16 We'll put a comment in here, Multi-Line String Literals. 0:18 SEO 163, the proposal, 0:26 brings multi-line string literals to Swift with a very simple syntax. 0:28 Long strings, or multi-line strings, are strings delimited by triple quotes. 0:34 So we can say let json = and then we start with a triple quote, 0:40 and end this multi-line string literal with another triple quote. 0:45 The nice part about these multi-line string literals is that they can contain 0:50 new lines, as well as single quotes, without the need to escape them. 0:54 For example, you can include some sample json to test against, 0:59 without escaping every single quote. 1:02 So in here, I'll just hit Enter and paste, 1:04 now this has stripped all my spacing out, so let's try to format this. 1:08 Okay, so that's it for multiline string literals, pretty simple. 1:15 Now, the next one is a pretty big set of changes, and 1:19 it's got this top level name of string revision, which is what we'll call it. 1:22 Back in the Swift 1 days which feels like a lifetime ago, strings were a collection. 1:30 In Swift 2, collection conformance was dropped, because some of the behavior was 1:35 thought to differ strongly enough from the other types. 1:39 Swift 4 reversed this change, so strings are collection types again. 1:43 In Swift 3, to iterate through string using a for loop, we had to access 1:48 the underlying characters array, we don't have to do that anymore in Swift 4. 1:53 So if we had a simple string literal, let programmingLanguage = "Swift", 1:57 now we can simply do for char in programmingLanguage print(char). 2:04 And this works, we don't have to do programmingLanguage.characters. 2:15 And let me pull this up so you can see better, there we go. 2:21 In Swift 3, despite not being a collection, 2:24 you could still perform slicing operations on a string. 2:27 Slicing a string in Swift 3 returned a string as well, 2:31 string was a string's own subsequence. 2:35 Now this led to some memory issues, and 2:38 one of the bigger changes in Swift 4 is the introduction of the substring type. 2:41 So for example if we do let second 2:46 = ProgrammingLanguage.index(after: 2:49 programmingLanguage.startIndex). 2:55 So here, I'm just getting the index right after the startIndex. 2:59 And then I use that to get a substring that goes 3:03 from the second index all the way to the end. 3:08 When I do this, 3:15 if we inspect the type of substring, you'll see that it is string.subSequence. 3:16 It is not a string, so this is commonly called substring, this type. 3:20 And with the existence of two types, string and 3:25 substring, in order to add functionalities to strings in your code base, 3:28 you have to extend both types individually, which is quite annoying. 3:33 So let's look at a simple example, I'm going to add a quick extension to 3:37 the character type to determine if a character is an uppercase one. 3:41 So extension Character, var isUppercase, and 3:45 this is going to be a boolean computed property, 3:50 and here we'll return String(self) == 3:56 String(self).uppercased(). 4:00 Using this, let's define a stripped uppercase method on string. 4:08 So extension, let's make some room here, extension String, 4:12 func strippedUppercase(). 4:18 And this is going to be a function that returns a string, and 4:24 we'll say return self.filter 4:27 (!$0.isUppercase). 4:31 Notice that now that string is a collection type, 4:38 we get access to methods like filter, map, and 4:40 reduce, without having to query the underlying characters view. 4:43 So now that we have this method, we can use it on a string. 4:47 So I can say programmingLanguage.strippedUppercase, 4:50 and it works. 4:58 So we've removed the uppercase S from our Swift string. 5:00 If we grab a slice of the string, though, so over here we have this substring 5:05 constant that we use to get a slice of the programming language string. 5:10 If we use that, so we say substring.strippedUppercase here. 5:15 You'll see that we get an error, and you can see this in the console. 5:23 It says, value of type String.SubSequence, 5:27 aka Substring, has no member strippedUppercase. 5:30 This means that we only added it to the String type, not the Substring type. 5:34 So clearly, they're both distinct types, when we get a substring of a string, 5:39 we don't get a string back. 5:44 Now, does this mean that we need to go ahead and extend the substring type and 5:47 add this strippedUppercase method as well? 5:51 Thankfully, no, we don't have to do it, Swift 4 also introduces string protocol. 5:54 Both sting and substring conform to this new string protocol type. 6:00 So anywhere we used extend string in your code base, you should now extend 6:05 string protocol instead, to insure that substring gets the same behavior. 6:10 So let's move this method, 6:15 this strippedUppercase method, into an extension of string protocol. 6:17 So, extension here, 6:22 StringProtocol instead of String, when we do this, we get an error. 6:23 And that's because we need to be aware of what self means over here. 6:29 Self can now mean either a string or a substring, 6:34 to ensure that we account for this, we're always going to convert self. 6:38 We're gonna make it a string instance and then do the work we need. 6:42 So if self is already a string, nothing happens here, 6:46 if it is a substring, we'll make it a string and then call filter. 6:51 And now you can see that this works, 6:56 this also indicates that we can't use a substring where a string is expected. 6:59 Now, in Swift 3, you could, because slicing a string returned a string. 7:04 If you have a substring now in Swift 4, you need to use the initializer 7:09 on string to force a copy to create a new string, and you can pass that in. 7:15 Now there are other changes to string, but for 7:20 the most part, this should be what you encounter in your day to day. 7:22 The relevant proposal here is SEO163, read the notes to find out more. 7:26
You need to sign up for Treehouse in order to download course files.Sign up