{"id":17387,"date":"2017-03-10T13:47:08","date_gmt":"2017-03-10T18:47:08","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=17387"},"modified":"2017-03-10T13:47:08","modified_gmt":"2017-03-10T18:47:08","slug":"making-swift-enums-and-structs-equatable","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2017\/03\/10\/making-swift-enums-and-structs-equatable\/","title":{"rendered":"Making Swift Enums and Structs Equatable"},"content":{"rendered":"<p><a href=\"https:\/\/oleb.net\/blog\/2017\/03\/enums-equatable-exhaustiveness\/\">Ole Begemann<\/a>:<\/p>\n<blockquote cite=\"https:\/\/oleb.net\/blog\/2017\/03\/enums-equatable-exhaustiveness\/\"><p>The downside of not having a default case is, of course, more boilerplate to write. [&#8230;] This isn&#x2BC;t fun to write, and it would get even worse with more cases. The number of states the <code>switch<\/code> statement must distinguish grows quadratically with the number of cases in the enum.<\/p>\n<p>[&#8230;]<\/p>\n<p>You can make this considerably more manageable with some intelligent application of the <code>_<\/code> placeholder pattern. While we saw above that a single default clause is not enough, <em>one pattern per case<\/em> is.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/oleb.net\/blog\/2017\/03\/dump-as-equatable-safeguard\/\">Ole Begemann<\/a>:<\/p>\n<blockquote cite=\"https:\/\/oleb.net\/blog\/2017\/03\/dump-as-equatable-safeguard\/\">\n<p>Unfortunately, like the enum example I talked about <a href=\"\/blog\/2017\/03\/enums-equatable-exhaustiveness\/\">in the previous post<\/a>, this conformance to <code>Equatable<\/code> is very fragile: every time you add a property to the struct, you have to remember to also update the implementation of the <a href=\"https:\/\/developer.apple.com\/reference\/swift\/equatable\/1539854\"><code>==<\/code> function<\/a>. If you forget, your <code>Equatable<\/code> conformance will be broken, and depending on how good your tests are this bug has the potential to go undetected for a long time &mdash; the compiler won&#x2BC;t be able to help you here.<\/p>\n<p>[&#8230;]<\/p>\n<p>It occurred to me to use the standard library&#x2BC;s <a href=\"https:\/\/developer.apple.com\/reference\/swift\/1641218-dump\"><code>dump<\/code><\/a> function as a safeguard. <code>dump<\/code> is interesting because it uses <a href=\"https:\/\/developer.apple.com\/reference\/swift\/mirror\">Swift&#x2BC;s reflection capabilities<\/a> to create a string representation of a value or object that includes all storage fields.<\/p>\n<p>[&#8230;]<\/p>\n<p>The biggest drawback of the solution might be that <code>dump<\/code> is not a perfectly reliable way to determine equality. It should be pretty good at avoiding <a href=\"https:\/\/en.wikipedia.org\/wiki\/False_positives_and_false_negatives#False_negative_error\">false negatives<\/a>, but you&#x2BC;ll probably see some <a href=\"https:\/\/en.wikipedia.org\/wiki\/False_positives_and_false_negatives#False_positive_error\">false positives<\/a>, i.e. values that really <em>are equal<\/em> but whose <code>dump<\/code> outputs are different.<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Ole Begemann: The downside of not having a default case is, of course, more boilerplate to write. [&#8230;] This isn&#x2BC;t fun to write, and it would get even worse with more cases. The number of states the switch statement must distinguish grows quadratically with the number of cases in the enum. [&#8230;] You can make [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[71,901],"class_list":["post-17387","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/17387","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=17387"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/17387\/revisions"}],"predecessor-version":[{"id":17388,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/17387\/revisions\/17388"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=17387"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=17387"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=17387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}