{"id":387398,"date":"2024-06-29T07:17:46","date_gmt":"2024-06-29T07:17:46","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=387398"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T07:17:46","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=387398","title":{"rendered":"<span>Swift 5.7: Regex. Shorthands for optional unwrapping. Unlock existentials for all protocols<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>Shorthands for optional unwrapping<\/h3>\n<pre><code class=\"swift\">if let workingDirectoryMailmapURL {     print (workingDirectoryMailmapURL) }  while let workingDirectoryMailmapURL {     print (workingDirectoryMailmapURL)     break }  guard let workingDirectoryMailmapURL else {     return }  print (workingDirectoryMailmapURL) <\/code><\/pre>\n<h3>Improved type inference for complex\u00a0closures<\/h3>\n<p>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:<\/p>\n<pre><code class=\"swift\">let scores = [100, 70, 75]  let results = scores.map { score in     if score >= 75 {         return \"\\(score)%: Pass\"     } else {         return \"\\(score)%: Fail\"     } }<\/code><\/pre>\n<p>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.<\/p>\n<h3>Better string parsing with Swift\u00a0Regex<\/h3>\n<p>Regular expressions (Regex) are powerful tools for pattern matching and string manipulation. Regexes, though very compact, can sometimes be difficult to understand and debug.<\/p>\n<p>Here&#8217;s an example of how to use Swift Regex to extract hashtags from a tweet:<\/p>\n<pre><code class=\"swift\">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 ..&lt; match.range.upperBound]         print (hashTag)     } }<\/code><\/pre>\n<p>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.<\/p>\n<h3>Creating a Regex with Regex literal<\/h3>\n<p>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\u00a0<a href=\"https:\/\/github.com\/sergeyleschev\/swift-evolution\/blob\/main\/proposals\/0354-regex-literals.md\" rel=\"noopener noreferrer nofollow\"><u>here<\/u><\/a>.<\/p>\n<pre><code class=\"swift\">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 ..&lt;   match.range.upperBound]     print (hashTag) }<\/code><\/pre>\n<h3>Creating a Regex using RegexBuilder<\/h3>\n<p>RegexBuilder is a domain-specific language that provides an expressive result-builder-based way to build regular expressions. It is similar to SwiftUI.<\/p>\n<p>To use it, you first need to import the RegexBuilder module. Then, you can create a regular expression using the Regex closure.<\/p>\n<p>As an example, consider creating a regex that matches hashtags in a tweet. The regex should begin with the &#8216;#&#8217; character, followed by one or more characters from the set [a-z0-9_]. Here&#8217;s how you can create this regex using RegexBuilder:<\/p>\n<pre><code class=\"swift\">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 ..&lt; match.range.upperBound]     print (hashTag) }<\/code><\/pre>\n<h3>Unlock existentials for all protocols<\/h3>\n<p>The release of Swift 5.7 involves a notable change in the language&#8217;s protocol handling capabilities. Specifically, there&#8217;s been a significant relaxation on restrictions previously imposed when using protocols as types with associated type requirements.<\/p>\n<p>To put it simply, this means that codes like the following will now be considered legal:<\/p>\n<pre><code class=\"swift\">let tvShow: [any Equatable] = [\"London\", 99]<\/code><\/pre>\n<hr\/>\n<p>Swift Regex\u00a0Literals<br \/>Implemented: Swift 5.7<br \/><a href=\"https:\/\/github.com\/sergeyleschev\/swift-evolution\/blob\/main\/proposals\/0354-regex-literals.md\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/github.com\/sergeyleschev\/swift-evolution\/blob\/main\/proposals\/0354-regex-literals.md<\/u><\/a><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/718772\/\"> https:\/\/habr.com\/ru\/articles\/718772\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>Shorthands for optional unwrapping<\/h3>\n<pre><code class=\"swift\">if let workingDirectoryMailmapURL {     print (workingDirectoryMailmapURL) }  while let workingDirectoryMailmapURL {     print (workingDirectoryMailmapURL)     break }  guard let workingDirectoryMailmapURL else {     return }  print (workingDirectoryMailmapURL) <\/code><\/pre>\n<h3>Improved type inference for complex\u00a0closures<\/h3>\n<p>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:<\/p>\n<pre><code class=\"swift\">let scores = [100, 70, 75]  let results = scores.map { score in     if score >= 75 {         return \"\\(score)%: Pass\"     } else {         return \"\\(score)%: Fail\"     } }<\/code><\/pre>\n<p>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.<\/p>\n<h3>Better string parsing with Swift\u00a0Regex<\/h3>\n<p>Regular expressions (Regex) are powerful tools for pattern matching and string manipulation. Regexes, though very compact, can sometimes be difficult to understand and debug.<\/p>\n<p>Here&#8217;s an example of how to use Swift Regex to extract hashtags from a tweet:<\/p>\n<pre><code class=\"swift\">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 ..&lt; match.range.upperBound]         print (hashTag)     } }<\/code><\/pre>\n<p>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.<\/p>\n<h3>Creating a Regex with Regex literal<\/h3>\n<p>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\u00a0<a href=\"https:\/\/github.com\/sergeyleschev\/swift-evolution\/blob\/main\/proposals\/0354-regex-literals.md\" rel=\"noopener noreferrer nofollow\"><u>here<\/u><\/a>.<\/p>\n<pre><code class=\"swift\">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 ..&lt;   match.range.upperBound]     print (hashTag) }<\/code><\/pre>\n<h3>Creating a Regex using RegexBuilder<\/h3>\n<p>RegexBuilder is a domain-specific language that provides an expressive result-builder-based way to build regular expressions. It is similar to SwiftUI.<\/p>\n<p>To use it, you first need to import the RegexBuilder module. Then, you can create a regular expression using the Regex closure.<\/p>\n<p>As an example, consider creating a regex that matches hashtags in a tweet. The regex should begin with the &#8216;#&#8217; character, followed by one or more characters from the set [a-z0-9_]. Here&#8217;s how you can create this regex using RegexBuilder:<\/p>\n<pre><code class=\"swift\">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 ..&lt; match.range.upperBound]     print (hashTag) }<\/code><\/pre>\n<h3>Unlock existentials for all protocols<\/h3>\n<p>The release of Swift 5.7 involves a notable change in the language&#8217;s protocol handling capabilities. Specifically, there&#8217;s been a significant relaxation on restrictions previously imposed when using protocols as types with associated type requirements.<\/p>\n<p>To put it simply, this means that codes like the following will now be considered legal:<\/p>\n<pre><code class=\"swift\">let tvShow: [any Equatable] = [\"London\", 99]<\/code><\/pre>\n<hr\/>\n<p>Swift Regex\u00a0Literals<br \/>Implemented: Swift 5.7<br \/><a href=\"https:\/\/github.com\/sergeyleschev\/swift-evolution\/blob\/main\/proposals\/0354-regex-literals.md\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/github.com\/sergeyleschev\/swift-evolution\/blob\/main\/proposals\/0354-regex-literals.md<\/u><\/a><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/718772\/\"> https:\/\/habr.com\/ru\/articles\/718772\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-387398","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/387398","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=387398"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/387398\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=387398"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=387398"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=387398"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}