<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Generics on Kelly Dev</title><link>https://kelly-chui.github.io/tags/generics/</link><description>Recent content in Generics on Kelly Dev</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 26 Jan 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://kelly-chui.github.io/tags/generics/index.xml" rel="self" type="application/rss+xml"/><item><title>The Swift Programming Language. Generics (1)</title><link>https://kelly-chui.github.io/posts/the-swift-programming-language-43-generics-1/</link><pubDate>Tue, 01 Aug 2023 00:00:00 +0000</pubDate><guid>https://kelly-chui.github.io/posts/the-swift-programming-language-43-generics-1/</guid><description>&lt;figure class="theme-image"&gt;
&lt;img
class="theme-image__image theme-image__image--light"
src="https://kelly-chui.github.io/images/assets/swift-logo-light.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;img
class="theme-image__image theme-image__image--dark"
src="https://kelly-chui.github.io/images/assets/swift-logo-dark.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;/figure&gt;
&lt;h2 id="generics"&gt;Generics&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;제네릭 코드(Generic code)&lt;/em&gt; 는 정의한 요구사항을 만족하는 모든 타입과 함께 작업할 수 있는 유연하고 재사용성 높은 함수나 타입을 작성하게 해준다. 코드의 중복을 피하고, 의도를 추상적이고 명확한 방법으로 표현할 수 있다.&lt;/p&gt;
&lt;p&gt;제네릭은 스위프트의 강력한 특징 중 하나이며, 많은 스위프트의 표준 라이브러리는 제네릭 코드로 빌드 되어있다. 사실 인지하지 못했어도 Language Guide 내내 제네릭 코드를 사용했다. 예를 들어, 스위프트의 &lt;code&gt;Array&lt;/code&gt;와 &lt;code&gt;Dictionary&lt;/code&gt; 타입은 둘 다 제네릭 컬렉션이다. &lt;code&gt;Int&lt;/code&gt; 값을 저장하는 배열, &lt;code&gt;String&lt;/code&gt; 값을 저장하는 배열, 혹은 스위프트에서 만들 수 있는 어떠한 다른 타입이라도 저장하는 배열 등을 생성할 수 있다. 비슷하게, 어떤 타입이든지 간에 특정한 타입을 저장하는 딕셔너리를 만들 수 있다.&lt;/p&gt;</description></item><item><title>The Swift Programming Language. Generics (2)</title><link>https://kelly-chui.github.io/posts/the-swift-programming-language-44-generics-2/</link><pubDate>Wed, 02 Aug 2023 00:00:00 +0000</pubDate><guid>https://kelly-chui.github.io/posts/the-swift-programming-language-44-generics-2/</guid><description>&lt;figure class="theme-image"&gt;
&lt;img
class="theme-image__image theme-image__image--light"
src="https://kelly-chui.github.io/images/assets/swift-logo-light.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;img
class="theme-image__image theme-image__image--dark"
src="https://kelly-chui.github.io/images/assets/swift-logo-dark.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;/figure&gt;
&lt;h3 id="generic-types"&gt;Generic Types&lt;/h3&gt;
&lt;p&gt;제네릭 함수와 다르게, 스위프트는 제네릭 타입도 정의할 수 있게 해준다. 이는 &lt;code&gt;Array&lt;/code&gt;나 &lt;code&gt;Dictionary&lt;/code&gt;처럼 모든 타입과 함께 작업할 수 있는 커스텀 클래스, 스트럭처, 열거형이다.&lt;/p&gt;
&lt;p&gt;이 섹션은 스택이라는 제네릭 컬렉션 타입을 작성하는 방법을 보여준다. 스택은 배열과 비슷하게 순서가 있는 값들의 집합이다, 하지만 스위프트의 &lt;code&gt;Array&lt;/code&gt; 타입보다 더 제한된 작업을 한다. 배열은 배열의 어느 위치에서나 값을 삽입하거나 제거할 수 있지만, 스택은 컬렉션의 끝 부분에서만 삽입(&lt;em&gt;pushing&lt;/em&gt;)이나 삭제(&lt;em&gt;popping&lt;/em&gt;)을 할 수 있다.&lt;/p&gt;</description></item><item><title>The Swift Programming Language. Generics (3)</title><link>https://kelly-chui.github.io/posts/the-swift-programming-language-45-generics-3/</link><pubDate>Fri, 04 Aug 2023 00:00:00 +0000</pubDate><guid>https://kelly-chui.github.io/posts/the-swift-programming-language-45-generics-3/</guid><description>&lt;figure class="theme-image"&gt;
&lt;img
class="theme-image__image theme-image__image--light"
src="https://kelly-chui.github.io/images/assets/swift-logo-light.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;img
class="theme-image__image theme-image__image--dark"
src="https://kelly-chui.github.io/images/assets/swift-logo-dark.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;/figure&gt;
&lt;h3 id="type-constraints"&gt;Type Constraints&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;swapTwoValues(_:_:)&lt;/code&gt; 함수와 &lt;code&gt;Stack&lt;/code&gt; 타입은 어떠한 타입으로도 작업할 수 있다. 하지만 특정한 &lt;em&gt;타입 제약조건(type constraints)&lt;/em&gt; 을 강제하여 제네릭 함수나 제네릭 타입이 사용할 수 있는 타입을 지정하는 것이 유용할 때가 있다. 타입 제약조건은 타입 파라미터가 특정한 클래스를 상속 받거나, 특정 프로토콜을 준수해야 하도록 지정한다.&lt;/p&gt;
&lt;p&gt;예를 들어, 스위프트의 &lt;code&gt;Dictionary&lt;/code&gt; 타입은 딕셔너리의 키로 사용할 수 있는 타입에 제한을 둔다. 딕셔너리의 키로 사용될 타입은 반드시 &lt;em&gt;hashable&lt;/em&gt; 해야한다. 즉, 스스로를 유니크하게 구분할 수 있어야 한다.&lt;/p&gt;</description></item><item><title>The Swift Programming Language. Generics (4)</title><link>https://kelly-chui.github.io/posts/the-swift-programming-language-46-generics-4/</link><pubDate>Mon, 07 Aug 2023 00:00:00 +0000</pubDate><guid>https://kelly-chui.github.io/posts/the-swift-programming-language-46-generics-4/</guid><description>&lt;figure class="theme-image"&gt;
&lt;img
class="theme-image__image theme-image__image--light"
src="https://kelly-chui.github.io/images/assets/swift-logo-light.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;img
class="theme-image__image theme-image__image--dark"
src="https://kelly-chui.github.io/images/assets/swift-logo-dark.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;/figure&gt;
&lt;h3 id="associated-types"&gt;Associated Types&lt;/h3&gt;
&lt;p&gt;프로토콜을 정의할때, 프로토콜의 정의의 일부로 하나 혹은 그 이상의 &lt;em&gt;연관 타입(associated type)&lt;/em&gt; 을 선언하는 것이 유용할 때가 있다. 연관 타입은 프로토콜의 일부로 사용되는 타입에게 플레이스홀더 이름을 부여한다. 해당 연관 타입이 될 실제 타입은 프로토콜이 적용될 때 까지 지정되지 않는다. 연관 타입은 associatedtype 키워드로 특정할 수 있다.&lt;/p&gt;
&lt;h3 id="associated-types-in-action"&gt;Associated types in Action&lt;/h3&gt;
&lt;p&gt;다음은 연관 타입으로 &lt;code&gt;Item&lt;/code&gt;을 선언하는 프로토콜 &lt;code&gt;Container&lt;/code&gt;의 예시이다:&lt;/p&gt;
&lt;div class="code-theme-github"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-swift" data-lang="swift"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;protocol&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;associatedtype&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;mutating&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;_&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kr"&gt;get&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;subscript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kr"&gt;get&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Container&lt;/code&gt; 프로토콜은 모든 컨테이너가 반드시 제공해야할 세 개의 필수 요구사항을 정의한다.&lt;/p&gt;</description></item><item><title>The Swift Programming Language. Generics (5)</title><link>https://kelly-chui.github.io/posts/the-swift-programming-language-47-generics-5/</link><pubDate>Tue, 08 Aug 2023 00:00:00 +0000</pubDate><guid>https://kelly-chui.github.io/posts/the-swift-programming-language-47-generics-5/</guid><description>&lt;figure class="theme-image"&gt;
&lt;img
class="theme-image__image theme-image__image--light"
src="https://kelly-chui.github.io/images/assets/swift-logo-light.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;img
class="theme-image__image theme-image__image--dark"
src="https://kelly-chui.github.io/images/assets/swift-logo-dark.svg"
alt="Swift logo"
loading="lazy"
decoding="async"
&gt;
&lt;/figure&gt;
&lt;h3 id="generic-where-clauses"&gt;Generic Where Clauses&lt;/h3&gt;
&lt;p&gt;타입 제약조건을 사용하면 제너럴 함수, 서브스크립트, 타입에 관련된 타입 파라미터의 요구사항을 정의할 수 있다.&lt;/p&gt;
&lt;p&gt;이는 연관 타입의 제약 조건을 정의하는데에도 유용하며, 제네릭 where 절을 정의하여 할 수 있다. 제네릭 &lt;code&gt;where&lt;/code&gt;절은 연관 타입이 반드시 특정 프로토콜을 준수하게 하거나, 특정한 타입 파라미터와 연관 타입이 반드시 같아야 함을 요구할 수 있다. 제네릭 &lt;code&gt;where&lt;/code&gt;절은 &lt;code&gt;where&lt;/code&gt; 키워드로 시작하고, 뒤에 연관 타입의 제약조건이나 타입 파라미터와 연관 타입의 동등 관계를 작성한다. 제네릭 where절은 타입이나 함수의 본문의 여는 중괄호 바로 앞에 작성한다.&lt;/p&gt;</description></item><item><title>Swift. Associated Type</title><link>https://kelly-chui.github.io/posts/swift-associated-type/</link><pubDate>Sun, 26 Jan 2025 00:00:00 +0000</pubDate><guid>https://kelly-chui.github.io/posts/swift-associated-type/</guid><description>&lt;h2 id="소개"&gt;소개&lt;/h2&gt;
&lt;p&gt;Swift의 프로토콜은 구현이 아니라 요구사항만 정의한다. 그런데 어떤 프로토콜은 사용할 타입을 미리 알 수 없는 경우가 있다.&lt;/p&gt;
&lt;p&gt;예를 들어, 아래와 같은 &lt;code&gt;Container&lt;/code&gt; 프로토콜을 만든다고 생각해 보자.&lt;/p&gt;
&lt;div class="code-theme-github"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-swift" data-lang="swift"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;protocol&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;_&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;???)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;append&lt;/code&gt;가 받을 타입은 무엇이어야 할까?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Int&lt;/code&gt;일 수도 있고, &lt;code&gt;String&lt;/code&gt;일 수도 있으며, 사용자가 직접 만든 타입일 수도 있다. 하지만 프로토콜이 특정 타입에 종속되면 재사용성이 크게 떨어진다.&lt;/p&gt;
&lt;p&gt;이럴 때 사용하는 것이 Associated Type이다. 처음에는 Generic으로도 해결할 수 있을 것 같다는 생각이 들었는데, 프로토콜은 Generic을 사용할 수 없다.&lt;/p&gt;</description></item></channel></rss>