{"id":9344,"date":"2023-12-08T21:36:03","date_gmt":"2023-12-08T21:36:03","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=9344"},"modified":"2023-12-08T21:36:03","modified_gmt":"2023-12-08T21:36:03","slug":"experiments-with-swift-generics","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/experiments-with-swift-generics\/","title":{"rendered":"Experiments with Swift Generics"},"content":{"rendered":"<p><em>Note: I\u2019m going through draft posts that go back to 2014 and publishing where they still may have value. They may not be 100% upto date but better published late than never.<\/em><\/p>\n<p>Generics are interesting within Swift. Syntactically they look the same as most other languages which supports generics. So, we have the syntax below<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass Policy&lt;TResult&gt; {\r\n}\r\n<\/pre>\n<p><strong>Generic and non-generic types of the same name<\/strong><\/p>\n<p>In C# we can essentially create a generic and non generic type and the compiler works out which we meant to use. Sadly this doesn&#8217;t exist in Swift (or Java or maybe many other implementations). But then, rather interestingly we can (assuming no constraint on the generic parameter) actually create a generic of type Void, i.e. <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass Test&lt;TResult&gt; {\r\n  func run(_ action: () -&gt; TResult) -&gt; TResult {\r\n    return action()\r\n  }\r\n}\r\n<\/pre>\n<p>and then write code like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nlet a1 = Test&lt;String&gt;()\r\nlet a2 = a1.run({ return &quot;Hello&quot; })\r\n\r\nlet b1 = Test&lt;Void&gt;()\r\nlet b2 = b1.run({ return })\r\n<\/pre>\n<p>What about, if we looked at this problem from the perspective of creating a <em>default<\/em> type for the generic. Swift doesn&#8217;t support this but we can (sort of) create something like this using <em>init<\/em>. Where we take an argument of the generic type, so for example if we have <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass Test&lt;T&gt; {\r\n  init(value: T) {\r\n  }\r\n}\r\n<\/pre>\n<p>Okay so we can now declare our variables like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nlet t1 = Test(value: 42)\r\nlet t2 = Test(value: &quot;Hello&quot;)\r\n<\/pre>\n<p>I know, this doesn&#8217;t have a default implementation at all, so instead we&#8217;ll create an extension which does the defaulting for us <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nextension Test where T == Person {\r\n    convenience init() {\r\n        self.init(value: Person())\r\n    }\r\n}\r\n<\/pre>\n<p>Now we create an instance like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nlet t3 = Test()\r\n<\/pre>\n<p>See <a href=\"https:\/\/stackoverflow.com\/questions\/42015081\/can-i-assign-a-default-type-to-generic-type-t-in-swift\" rel=\"noopener\" target=\"_blank\">Can I assign a default type to generic type T in Swift?<\/a> for further information on this one.<\/p>\n<p><strong>Adding constraints<\/strong><\/p>\n<p>We can add a constraint, for example the generic type must a a type of Error, like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass Test&lt;TError: Error&gt; {\r\n}\r\n<\/pre>\n<p>We can also create constraints against properties of a type, for example at a function level we can check or (as above) on extensions using the <em>where<\/em> clause. So in the example<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nextension Test where T == Person {\r\n}\r\n<\/pre>\n<p>The extension implicitly knows that there&#8217;s a generic parameter T and so we don&#8217;t need to redeclare it, instead we&#8217;re simply saying this extension works for <em>Test<\/em> where T is a Person. This sort of technique can also be used within functions.<\/p>\n<p><strong>Default value<\/strong><\/p>\n<p>If you come from a C# background, you&#8217;ll probably be used to using <em>default(T)<\/em> or the shortened version simply <em>default<\/em>. Swift doesn&#8217;t include such a keyword. Instead you&#8217;ll either need to use optionals, i.e. returned a .some or .none, or ofcourse you might create a function of class to imitate such functionality yourself.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Note: I\u2019m going through draft posts that go back to 2014 and publishing where they still may have value. They may not be 100% upto date but better published late than never. Generics are interesting within Swift. Syntactically they look the same as most other languages which supports generics. So, we have the syntax below [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[286],"tags":[],"class_list":["post-9344","post","type-post","status-publish","format-standard","hentry","category-swift"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9344","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=9344"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9344\/revisions"}],"predecessor-version":[{"id":10320,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9344\/revisions\/10320"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=9344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=9344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=9344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}