官术网_书友最值得收藏!

String protocol

Back in the days of Swift 1, Strings were a collection. In Swift 2, collection conformance was dropped because some of the behavior was thought to differ strongly enough from other collection types. Swift 4 reverses this change, so Strings are collection types again. One of the examples was described in the previous section where you were able to traverse over String vowels just like a normal array. In Swift 3, despite not being a collection, you could perform slicing operations on a String. Slicing a String in Swift 3 returned a String as well. This String was a String's own SubSequence, which led to some memory issues and one of the bigger changes in Swift 4 is the introduction of the subString types to remove these issues. For example, consider that we do this:

let secondIndex = vowels.index(after: vowels.startindex)
let subString = vowels[secondIndex...]

On doing this, if you inspect the type of subString, you will notice that it is String.SubSequence and not a String. With the existence of two types of String and SubSequence for adding functionality to Strings in your code base, you have to extend both types individually, which is quite cumbersome. Let's take a look at the following example:

We will add an extension to the Character type to determine whether a character is in uppercase:

extension Character {
var isUpperCase : Bool {
return String(self) == String(self).uppercased()
}
}

Using this, let's define a stripped uppercase method on String:

extension String {
func strippedUppercase() -> String {
return self.filter({ !$0.isUppercase})
}
}

So now that we have this method, we can use it on a String. So we can say that vowels.strippedUppercase() will return an empty String since all the characters in the vowels String are already uppercase.

If we grab a slice of the String though, that is, subString that we got earlier in the execution and use subString.strippedUppercase(), we get an error as subString is not a String anymore.

Does this mean that we need to extend the subString type and add this strippedUppercase() method as well? Thankfully NO!

Swift 4 also introduces String protocol. Both String and subString affirms to this new String protocol type. So anywhere we use extend String in our code base, we should now extend String protocol instead to ensure that subString gets the same behavior. So let's move the strippedUppercase() method into an extension of String protocol:

extension StringProtocol {
func strippedUppercase() -> String {
return self.filter({ !$0.isUppercase})
}
}

When we do this, we get an error because we need to be aware of what self means inside the method; self can now mean either a String or subString. To ensure that we always account for this, we will always convert self, make it a String instance, and then do the work we need. So if self is already a String, nothing happens and the function does not throw an error, but if it is a subString, we will make it a String and then call filter, and the preceding function works just fine:

extension StringProtocol {
func strippedUppercase() -> String {
return String(self).filter({ !$0.isUppercase })
}
}

There are more changes in String, but this should be the most used part that we might use from day to day.

主站蜘蛛池模板: 精河县| 甘德县| 松潘县| 四川省| 甘德县| 桐庐县| 陇南市| 安徽省| 隆昌县| 麟游县| 五家渠市| 新巴尔虎左旗| 广南县| 山阳县| 丰宁| 嘉义县| 梅河口市| 长武县| 壤塘县| 柘城县| 慈溪市| 宁武县| 唐山市| 黄骅市| 广西| 东莞市| 东明县| 宝应县| 化德县| 康马县| 隆昌县| 凌海市| 尉犁县| 广德县| 包头市| 美姑县| 汨罗市| 敖汉旗| 岑巩县| 嵊州市| 凤翔县|