Pull to refresh

Swift 5.7: Regex. Shorthands for optional unwrapping. Unlock existentials for all protocols

Level of difficultyMedium
Reading time3 min
Views1K

Shorthands for optional unwrapping

if let workingDirectoryMailmapURL {
    print (workingDirectoryMailmapURL)
}

while let workingDirectoryMailmapURL {
    print (workingDirectoryMailmapURL)
    break
}

guard let workingDirectoryMailmapURL else {
    return
}

print (workingDirectoryMailmapURL)

Improved type inference for complex closures

Swift has recently enhanced its type inference capabilities for closures. It can now automatically infer the return type of complex closures, as demonstrated by the following example:

let scores = [100, 70, 75]

let results = scores.map { score in
    if score >= 75 {
        return "\(score)%: Pass"
    } else {
        return "\(score)%: Fail"
    }
}

In this closure, which uses the map function to transform an array of scores into an array of corresponding pass/fail statements, Swift is now able to accurately infer the return type as String, without requiring explicit type annotations.

Better string parsing with Swift Regex

Regular expressions (Regex) are powerful tools for pattern matching and string manipulation. Regexes, though very compact, can sometimes be difficult to understand and debug.

Here's an example of how to use Swift Regex to extract hashtags from a tweet:

import RegexBuilder

if let regex = try? Regex("#[a-zA-Z0-9_]+") {
    let matches = tweet.matches(of: regex)
    for match in matches {
        let hashTag = tweet[match.range.lowerBound ..< match.range.upperBound]
        print (hashTag)
    }
}

In this example, we import the RegexBuilder library, which provides a convenient way to construct regular expressions in Swift. We then define a regex pattern that matches hashtags (#[a-zA-Z0-9_]+), wrap it in a try? statement to handle any parsing errors that may occur, and apply it to the tweet string using the matches(of:) method.

Creating a Regex with Regex literal

One of the most straightforward methods to create a Regex is using Regex literals. The code below demonstrates how to use Regex literals, which offer compile-time checks. You can learn more about Regex literals here.

import RegexBuilder

let regex = /#[A-Za-z_0-9]+/
let matches = tweet.matches(of: regex)

for match in matches {
    let hashTag = tweet[match.range.lowerBound ..<   match.range.upperBound]
    print (hashTag)
}

Creating a Regex using RegexBuilder

RegexBuilder is a domain-specific language that provides an expressive result-builder-based way to build regular expressions. It is similar to SwiftUI.

To use it, you first need to import the RegexBuilder module. Then, you can create a regular expression using the Regex closure.

As an example, consider creating a regex that matches hashtags in a tweet. The regex should begin with the '#' character, followed by one or more characters from the set [a-z0-9_]. Here's how you can create this regex using RegexBuilder:

import RegexBuilder

let regex = Regex {
    "#"
    OneOrMore {
        CharacterClass(
            ("a" ... "z"),
            ("0" ... "9"),
            ("_" ... "_")
        )
    }
}

let matches = tweet.matches(of: regex)

for match in matches {
    let hashTag = tweet[match.range.lowerBound ..< match.range.upperBound]
    print (hashTag)
}

Unlock existentials for all protocols

The release of Swift 5.7 involves a notable change in the language's protocol handling capabilities. Specifically, there's been a significant relaxation on restrictions previously imposed when using protocols as types with associated type requirements.

To put it simply, this means that codes like the following will now be considered legal:

let tvShow: [any Equatable] = ["London", 99]

Swift Regex Literals
Implemented: Swift 5.7
https://github.com/sergeyleschev/swift-evolution/blob/main/proposals/0354-regex-literals.md

Tags:
Hubs:
Rating0
Comments0

Articles