<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>change-challenge.log</title>
        <link>https://velog.io/</link>
        <description>도전하고, 바꾸고</description>
        <lastBuildDate>Mon, 17 Apr 2023 06:00:44 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>change-challenge.log</title>
            <url>https://velog.velcdn.com/images/change-challenge/profile/85633aa0-aafa-4be6-82fc-93047c3cebd0/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. change-challenge.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/change-challenge" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[SwiftUI) ForEach (feat. forEach(_:)) 톺아보기 02 | change-challenge]]></title>
            <link>https://velog.io/@change-challenge/SwiftUI-ForEach-feat.-forEach-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0-02-change-challenge</link>
            <guid>https://velog.io/@change-challenge/SwiftUI-ForEach-feat.-forEach-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0-02-change-challenge</guid>
            <pubDate>Mon, 17 Apr 2023 06:00:44 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-swift">struct ForEach&lt;Data, ID, Content&gt; where Data : RandomAccessCollection, ID : Hashable</code></pre>
<p>우리는 전 <a href="https://velog.io/@change-challenge/SwiftUI-ForEach-feat.-forEach-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0#%EB%A9%94%EC%86%8C%EB%93%9C--foreach_">블로그</a>을 통해 </p>
<ol>
<li>forEach(:_)와 ForEach의 차이점</li>
<li>ForEach 프로토타입을 보면서 아래와 같은 특징들을 찾았다.</li>
</ol>
<blockquote>
<p><strong>[ 구조체 ForEach의 특징 ]</strong> 
1️⃣. &lt;Data, ID, content&gt;
2️⃣. where Data: RandomAccessCollection, ID : Hashable
3️⃣. RandomAccessCollection (랜덤 엑세스 콜렉션)
4️⃣. Hashable (해쉬블)</p>
</blockquote>
<p>자, 이제는 ForEach의 예시를 통해 <strong>어떻게 사용했는 지</strong> 확인해보자!</p>
<hr>
<h2 id="🔥-foreach-예문">🔥 ForEach 예문</h2>
<p>애플 공식 홈페이지에 나와있는 <a href="https://developer.apple.com/tutorials/app-dev-training/creating-a-navigation-hierarchy">예문</a>으로 돌아가보자. </p>
<p><img src="https://velog.velcdn.com/images/change-challenge/post/1ff72c12-c752-4199-a849-328f04e46cff/image.png" alt=""></p>
<p>UI 실행은 위와 같이 된다. 
이것의 예시 코드는 아래와 같다.</p>
<pre><code class="language-swift">Section(header: Text(&quot;Attendees&quot;)) {
                ForEach(scrum.attendees) { attendee in
                    Label(attendee.name, systemImage: &quot;person&quot;)
                }
            }</code></pre>
<h3 id="⭐️-이-때-드는-의문이-있다⭐️-">*<em>⭐️ 이 때 드는 의문이 있다.⭐️ *</em></h3>
<ol>
<li>구조체인데 무슨 메소드처럼 적으면 실행이 되는 것이냐? 
<del>(forEach(:_)랑 툭 까놓고 다르지 않네?)</del><ol start="2">
<li>scrum.attendees의 Type은 어떻게 될까?
(RandomAccessCollection하고, Hashable하는가)</li>
</ol>
</li>
</ol>
<p>의문을 하나 하나 풀어나가보자! </p>
<hr>
<h3 id="❓-구조체인데-무슨-메소드처럼-적으면-실행이-되는-것이냐">❓ 구조체인데 무슨 메소드처럼 적으면 실행이 되는 것이냐?</h3>
<p>이때 짚고 넘어가야할 점은
C/C++에 익숙해있다보면 도대체 왜 구조체를 생성하였는데 View가 만들어지지? 라고 생각하기 쉬운데, SwiftUI에서 List처럼 View를 만들어주는 <strong>View Container역할</strong>을 하는 구조체라고 생각해야한다. </p>
<p>공식문서를 보면 List도 모두 <strong>Structure</strong> 되어있다. 
<img src="https://velog.velcdn.com/images/change-challenge/post/6166e45d-4ac3-48d4-9420-ab8811a67f5b/image.png" alt=""></p>
<p>이름은 forEach(:_)와 비슷하기에 반복문이라고 생각하기 쉬운데, 
그런 의도로 이름을 그렇게 지은 듯 하지만 내부 Data를 기반으로 View를 계산해서 보여주는 것이다. </p>
<p>애플 공식문서 ForEach 안에 다양한 init가 있고, 이 중에 하단의 init을 사용하여 실행되었다. </p>
<p><img src="https://velog.velcdn.com/images/change-challenge/post/852bb3a6-e937-4668-b4dc-c3db5438344e/image.png" alt=""></p>
<hr>
<h3 id="❓-scrumattendees의-type은-어떻게-될까brrandomaccesscollection하고-hashable하는가">❓ scrum.attendees의 Type은 어떻게 될까?<br>(RandomAccessCollection하고, Hashable하는가)</h3>
<pre><code class="language-swift">ForEach(scrum.attendees) { attendee in
    Label(attendee.name, systemImage: &quot;person&quot;)
}</code></pre>
<p>다시 위의 예시를 보면서 이야기를 하면, </p>
<p>첫번 째 인자로 <strong>Data</strong>는 _<strong>scrum.attendees</strong>_이 된 것이고, 
두번 째 인자로서 <strong>((Data.Element) -&gt; Content) 클로저</strong>로 </p>
<pre><code class="language-swift">{ attendee in
    Label(attendee.name, systemImage: &quot;person&quot;)
}</code></pre>
<p>를 받은 것이다. </p>
<p>그러면 _<strong>scrum.attendees</strong>_가 어떤 Type인 지 보자.
Data은 Hashable 프로토콜을 채택해야한다. </p>
<p>위에 SwiftUI 예제에서 <strong>scrum.attendees</strong>이 <strong>var attendees: [Attendee]</strong> 이다.</p>
<p><img src="https://velog.velcdn.com/images/change-challenge/post/69b14613-e217-4cce-ba07-879718d617c2/image.png" alt=""></p>
<p><strong>scrum.attendees</strong>는 <strong>Array</strong>이기에 <strong>RandomAccessCollection</strong>를 충족한다. </p>
<p>다음 조건은 충족하는 가?</p>
<blockquote>
<p>Hashable이 아니라 Identifiable 프로토콜을 채택하였다??</p>
</blockquote>
<p>-&gt; Identifiable 프로토콜은 내부적으로 Hashable 프로토콜을 채택하고 있기 때문에, Identifiable 프로토콜을 사용하는 경우에는 ID 타입이 Hashable 프로토콜을 채택하면 된다. </p>
<blockquote>
<p>그렇다고 ID는 Hashable 프로토콜을 채택하지 않았는데??</p>
</blockquote>
<p>-&gt; Identifiable 프로토콜을 채택한 객체에서 ID 타입은 Hashable 프로토콜을 채택해야 하지만, 이를 구현할 때 UUID 타입을 사용할 수 있습니다. Identifiable 프로토콜을 채택한 객체에서 ID 타입을 UUID 타입으로 지정하여 구현하면, 이를 사용하는 SwiftUI의 List나 ForEach와 같은 뷰에서도 모델의 고유성을 보장할 수 있다고 한다. </p>
<p>Identifiable 프로토콜은 각 데이터가 각자를 식별할 수 있는 무언가를 가지고 있는 경우에 충족한다고 볼 수 있다.</p>
<p><strong>scrum.attendees</strong>는 <strong>Identifiable</strong>를 충족한다. </p>
<hr>
<h2 id="마치면서">마치면서</h2>
<p>이를 통해 ForEach가 어떤 Data를 충족하는 지 확인해보았다. 
ForEach를 쓰는데 도대체 Hashable과 Identificable을 어떻게 처리해야하나 고민했는데 조금 더 수월하게 사용할 수 있지 않을까 싶다. 
애플 스유 Documentation을 그냥 슬렁 슬렁 넘어가면 그냥 타자연습 밖에 안되지만 하나 하나 뜯어보면 분명 더 많이 얻을 수 있을 것 같다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SwiftUI) ForEach (feat. forEach(_:)) 톺아보기 01 | change-challenge]]></title>
            <link>https://velog.io/@change-challenge/SwiftUI-ForEach-feat.-forEach-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@change-challenge/SwiftUI-ForEach-feat.-forEach-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Fri, 14 Apr 2023 07:58:27 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/change-challenge/post/cf86d7f0-1332-45ce-bae0-2b28b0206be4/image.png" alt=""></p>
<p>SwiftUI를 한번 맛보기 위해 <a href="https://developer.apple.com/tutorials/app-dev-training">iOS APP Dev Tutorials</a>를 한번 돌리고 있는 중에 ForEach를 사용하려면 요소들을 identifiable하게 만들어야한다고 한다. 
<img src="https://velog.velcdn.com/images/change-challenge/post/06f42c1e-e925-4327-a3a2-36319c42547a/image.png" alt=""></p>
<p>아니 도대체 반복문 돌리는데 왜 <strong>identifiable</strong>하게 만들어야한다는거야???
고민하다가 반복문 할 때 사용하는 메소드 <strong>forEach(_:)</strong>와 다르다는 것을 깨달았다...</p>
<p>심지어 하나는 Structure이고, 하나는 Method이다. </p>
<p>내가 알았던 것은 아래의 <strong>forEach(_:)</strong>이고, </p>
<p><img src="https://velog.velcdn.com/images/change-challenge/post/4fc9d3bc-0916-4895-b3b1-1500aeef5810/image.png" alt=""></p>
<p>이것이 SwiftUI에서 사용하는 <strong>ForEach</strong>이다.
<img src="https://velog.velcdn.com/images/change-challenge/post/090c5b8a-8a68-4b8f-bdd8-5187c622e8c8/image.png" alt=""></p>
<p><del>(도대체.. 왜 이름을 같게 한거야..)</del></p>
<hr>
<h2 id="메소드--foreach_">메소드 : forEach(_:)</h2>
<p>먼저 우리가 잘 아는 친구부터 보자. </p>
<p>forEach는 For-in을 쉽게 사용할 수 있는 메소드로 사용된다. 
<img src="https://velog.velcdn.com/images/change-challenge/post/958c67b0-b830-414b-950d-41e5b6256276/image.png" alt=""></p>
<p>애플 공식 documentation에서는 위와 같이 정의 되어있다. </p>
<p>내부를 살펴보면 <strong>forEach</strong>는 하나의 <strong>throw 클로저</strong>를 받는 메소드이다. 
(throw 클로저가 아니여도 가능합니다.)</p>
<p>하지만, <strong>throw 클로저</strong>를 인자로 넘긴다면 어떻게 해야할까?
<strong>rethrows</strong> 키워드를 쓰고 있기에, 클로저 내부에서 에러 발생 시, 클로저 내부에서 직접 처리하지 않고 해당 <strong>forEach를 호출한 쪽</strong>으로 에러를 전달합니다.</p>
<p><strong>forEach를 호출한 쪽</strong>에서 <strong>try문</strong>이나 <strong>do-catch문</strong>을 작성해줘야합니다.</p>
<pre><code class="language-swift">예시)

enum CalculationError: Error {
    case divideByZero
}

func divide(_ a: Int, _ b: Int) throws -&gt; Int {
    guard b != 0 else {
        throw CalculationError.divideByZero
    }
    return a / b
}

let numbers = [10, 20, 30, 0, 40]

// 클로저가 에러를 던지지 않는 경우, try-catch 블록을 사용하지 않아도 됩니다.
numbers.forEach { number in
    let result = try? divide(100, number)
    print(result ?? &quot;Error&quot;)
}</code></pre>
<pre><code>&lt;출력 값&gt;

10
5
3
Error
2</code></pre><p>이것이 우리가 자주 쓰는 forEach이다. </p>
<p>짧게 특징까지 이야기하면,</p>
<ol>
<li>for-in문이 아니기 때문에 <strong>break</strong>와 <strong>continue</strong>는 쓰지 못한다.</li>
<li>클로저 내부에서 <strong>return</strong>을 쓰게 되면 한 순서만 끝나는 것이다. 모든 forEach 메소드가 끝나는 것이 아니다.</li>
</ol>
<pre><code>예시)

let numbers = [1, 2, 3, 4, 5]

numbers.forEach { number in
    if number == 3 {
        return
    }
    print(number)
}

</code></pre><pre><code>&lt;출력 값&gt;

1
2
4
5</code></pre><p><strong>forEach</strong>에서 <strong>return</strong>을 <strong>continue</strong>처럼 쓸 수 있다고 생각하면 될 것 같다.</p>
<hr>
<h2 id="구조체--foreach">구조체 : ForEach</h2>
<p>일반적으로 SwiftUI에서 ForEach는 주어진 collection을 기반으로 View를 반복해서 만들어준다. 
<del>(헷갈리게 스펠링에서 f의 대문자 하나 다르다.)</del></p>
<p>애플 공식 documentation에서는 아래와 같이 프로토타입이 정해져있다. </p>
<p><img src="https://velog.velcdn.com/images/change-challenge/post/8a20381e-0fc0-43f0-83e3-4c572e4e156b/image.png" alt=""></p>
<p>프로토타입을 해석하는 것을 즐거워하기에 하나씩 해석을 해보겠습니다!</p>
<h3 id="1️⃣-data-id-content">1️⃣. &lt;Data, ID, content&gt;</h3>
<p><strong>제네릭 변수 Data, ID, Content</strong>를 사용하겠다는 것이다. 
C++에서는 &lt; T &gt;라고도 적는데 Swift에서는 명확한 이름을 사용해 가독성을 높이고 있습니다.</p>
<h3 id="2️⃣-where-data-randomaccesscollection-id--hashable">2️⃣. where Data: RandomAccessCollection, ID : Hashable</h3>
<p>먼저 <strong>where 키워드</strong>는 제네릭 타입 매개변수에 대한 제약 조건을 추가하는 역할을 합니다.
즉, 이 키워드를 사용하면 특정 조건을 만족하는 타입만을 받아들일 수 있도록 제한할 수 있습니다.</p>
<p>예를 들어, 이 곳에서는 </p>
<blockquote>
<p><strong>Data</strong>는 <strong>RandomAccessCollection</strong> 프로토콜 준수하고
<strong>ID</strong>는 <strong>Hashable</strong> 프로토콜을 준수한 타입만 받아드리겠다는 것이다.</p>
</blockquote>
<h3 id="3️⃣-randomaccesscollection-랜덤-엑세스-콜렉션">3️⃣. RandomAccessCollection (랜덤 엑세스 콜렉션)</h3>
<p> Swift에서 RandomAccessCollection은 Collection 프로토콜을 상속받는 프로토콜입니다.<br> RandomAccessCollection은 Collection 프로토콜의 모든 요구사항을 충족하면서, 해당 컬렉션의 모든 요소를 O(1) 시간 내에 접근할 수 있는 요구사항을 추가적으로 갖습니다.
 즉, 바로 <strong>linked List</strong>말고 바로 []로 접근가능한 것들이 RandomAccessCollection입니다. </p>
<p> 가장 가까운 예시로는 <strong>Array</strong>가 있습니다. 
 애플 공식 Documentation에서 보면 아래와 같이 <strong>random-access collection</strong>이라고 적혀있습니다. 
 <img src="https://velog.velcdn.com/images/change-challenge/post/18ca79b6-41fe-4e34-bd67-4d2e214b8839/image.png" alt=""></p>
<p> 빠르게 접근할 수 있고, 데이터를 검색하거나 정렬하는 등의 작업에서 효율적입니다. </p>
<h3 id="4️⃣-hashable-해쉬블">4️⃣. Hashable (해쉬블)</h3>
<p> <strong>Hashable 프로토콜</strong>은 Swift의 표준 라이브러리에서 제공하는 프로토콜 중 하나로, 객체를 <strong>해싱(Hashing)</strong> 가능하게 만드는 데 사용됩니다. </p>
<p><strong>해싱</strong>은 임의의 길이의 데이터를 고정된 길이의 값으로 매핑하는 것을 말하며, 
<strong>해시(Hash)</strong>는 이러한 매핑된 값을 의미합니다.</p>
<p>이것을 이해하려면 이런 상황을 떠올리면 좋다.</p>
<blockquote>
<p>Person이라는 Struct가 있다 
Person 내부 변수로 대략 1,000개가 있다고 하자. </p>
<p>이 PersonA와 PersonB를 같나 틀리나라는 operator==를 쓰려고하는데
하나 하나 다 검사하는 것이 효율적일까?</p>
</blockquote>
<p> 해시는 <strong>데이터의 고유한 식별자</strong>를 만들어내는 것으로, 객체를 해싱 가능하게 만들면, <strong>해당 객체를 빠르게 비교하고 검색</strong>할 수 있습니다. 
해시를 사용하면, 위에 Person과 같은 상황도 빠르게 처리할 수 있습니다. </p>
<p>Set이나 Dictionary의 key값도 중복이 되면 안되고, 이것을 빠르게 처리하기 위해 <strong>Hash table</strong>을 사용한다고 한다. </p>
<p><del>(낄낄낄.. 이제 프로토타입의 기본을 안 것이다.)</del></p>
<p>길이 엄청 길어지네.. 역시 깊게 공부하려고 노력하면 재밌는데 길어진다. 
가독성을 위해 두 번째 글을 작성해보겠습니다.🙋🏻‍♂️</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Swift) Class(클래스) vs Struct(구조체) 차이점 | change-challenge]]></title>
            <link>https://velog.io/@change-challenge/iOS-Class%ED%81%B4%EB%9E%98%EC%8A%A4-vs-Struct%EA%B5%AC%EC%A1%B0%EC%B2%B4-%EC%B0%A8%EC%9D%B4%EC%A0%90-change-challenge</link>
            <guid>https://velog.io/@change-challenge/iOS-Class%ED%81%B4%EB%9E%98%EC%8A%A4-vs-Struct%EA%B5%AC%EC%A1%B0%EC%B2%B4-%EC%B0%A8%EC%9D%B4%EC%A0%90-change-challenge</guid>
            <pubDate>Wed, 12 Apr 2023 04:33:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/change-challenge/post/d6861029-5ffd-43bb-8e28-36a4daeb6473/image.png" alt="">
C/C++를 하게 되면 class나 struct 모두 상관없이 정적할당이나 동적할당으로 Stack영역 혹은 Heap영역으로 저장이 된다.
하지만, Swift는 기본적으로 다른 곳에 할당이 된다고 한다.</p>
<p>추가적으로 차이점들도 많기에 익숙하지 않은 개념을 제대로 잡아보려고 한다. </p>
<h2 id="참조타입ref-vs-복사타입value">참조타입(ref) vs 복사타입(value)</h2>
<blockquote>
<p>Swift에서 Class는 참조형 / struct는 복사형</p>
</blockquote>
<p>이렇게 되버리면 어떤 경우가 생길 수 있냐면 </p>
<pre><code class="language-swift">class Person {
    var name: String
    init(name: String) {
        self.name = name
    }
}

var Person_A = Person(name: &quot;Change-Chanllenge&quot;)
var Person_B = Person_A // Person_B에 Person_A 주소 값을 복사한다.

Person_B.name = &quot;Hey&quot; 
// Person_B의 name만 바꾼 것 같지만 Person_A의 name도 바뀌게 된다. (ref이기에)
print(&quot;Person_A의 이름 : \(Person_A.name)  | Person_B의 이름 : \(Person_B.name)&quot;)
// Person_A의 이름 : Hey  | Person_B의 이름 : Hey
</code></pre>
<p>혹은 
다른 함수나 다른 파일에서 class 인스턴트 안에 값을 잘못바꿔 변경된 값을 사용할 수도 있다. 아래 예시는 다른 함수에서 값을 바꿔버리는 경우이다. </p>
<pre><code class="language-swift">class MyClass {
    var myProperty: String

    init(myProperty: String) {
        self.myProperty = myProperty
    }
}

func hello(myClass: MyClass) {
    myClass.myProperty = &quot;Hello, world!&quot;
}

let myInstance = MyClass(myProperty: &quot;Original value&quot;)
hello(myClass: myInstance) // 값이 바껴버린다. 
print(myInstance.myProperty) // &quot;Hello, world!&quot;</code></pre>
<h2 id="let과-mutating-키워드">let과 Mutating 키워드</h2>
<p>이 또한 ref와 value에 대한 차이로 야기되는 문제이다. </p>
<p>만약 Person이라는 Struct가 있고, 이를 let으로 인스턴트를 만들었다고 하자. 
그때, Struct는 인스턴트 내부 변수를 바꿀 수가 없다. </p>
<pre><code class="language-swift">struct Person {
    var name: String
}
let P = Person(name: &quot;change-challenge&quot;)
P.name = &quot;Hey&quot; // 컴파일 오류! </code></pre>
<p>왜냐면 let으로 선언하였기에 Struct 인스턴트 안에 모든 변수는 <strong>immutable</strong>하기 때문이다.</p>
<p>하지만 Class는 가능하다!</p>
<pre><code class="language-swift">class Person {
    var name: String?
}
let P = Person()
P.name = &quot;Hey&quot; // 잘된다! </code></pre>
<p>class에서 let으로 선언하는 것은 <strong>인스턴스 참조 자체가 변경될 수 없도록 하기 위한 것</strong>이지, 인스턴스 내부의 값이 변경될 수 없도록 하는 것이 아니기 때문이다. </p>
<p>예를 들어, 아래와 같이 인스턴트 내부의 값은 변경이 가능하지만, 참조 자체가 변경될 수 없는 것을 볼 수 있다. </p>
<pre><code class="language-swift">let person1 = Person(name: &quot;Alice&quot;, age: 20)
person1 = Person(name: &quot;Bob&quot;, age: 30) // 컴파일 오류
person1.age = 25 // 가능

var person2 = Person(name: &quot;Hey&quot;, age: 25)
person2 = person1 // 가능, person2는 인스턴트 참조하는 변수가 없어져서 메모리 해제! 
</code></pre>
<p>즉, Struct의 let은 인스턴트 내부의 값 자체에 const가 되는 것이고, 
Class의 let은 인스턴트 참조 자체가 const되는 것이다. </p>
<p>하지만, <strong><em>struct는 var로 선언해도 값 타입이기에 변수의 값을 변경할 수 없다!!!!!</em></strong></p>
<p>이렇기에 Struct에서도 인스턴트 내부의 값을 변경하려면 <strong>Mutating</strong> 키워드를 써야한다.</p>
<pre><code class="language-swift">struct Person {
    var name: String

    mutating func changeName(_ name: String) {
        self.name = name
    }
}
let P1 = Person(name: &quot;change-challenge&quot;)
var P2 = Person(name: &quot;change-challenge&quot;)
// P1.changeName(&quot;Hey&quot;) &lt;- 이게 이미 안된다! 
print(&quot;what is my name : \(P2.name))
P2.changeName(&quot;Hey&quot;)
print(&quot;what is my name : \(P2.name))</code></pre>
<pre><code>결과값) 
what is my name : change-challenge
what is my name : Hey</code></pre><h2 id="class--소멸자deinit--상속inheritance">Class : 소멸자(deinit) / 상속(Inheritance)</h2>
<p>class는 C++와 같이 소멸자와 상속이 가능하다. 
struct는 이 부분이 불가능하다. </p>
<p>아래의 예시와 같다. </p>
<pre><code class="language-swift">1. 소멸자 불가
struct Person {
    var name: String
    deinit { 
    }
}
// 소멸자에서 컴파일 오류! </code></pre>
<pre><code class="language-swift">2. 상속 불가
struct Person {
    var name: String
}
struct Me : Person {
}
// 상속에서 컴파일 오류! </code></pre>
<h2 id="struct--memberwise-init멤버별-초기화-구문">Struct : Memberwise init(멤버별 초기화 구문)</h2>
<p>위에 &#39;let과 Mutating 키워드&#39;예시를 잘 보면,
뭔가 비슷한데 class와 struct가 다르게 정의되어 있고, 선언하는 것을 볼 수 있다. </p>
<p>Class 먼저 보자. </p>
<pre><code class="language-swift">class Person {
    var name: String?
}

let P = Person()
P.name = &quot;Hey&quot; // 잘된다! </code></pre>
<p>Class는 기본적으로 <strong>가지고 있는 변수 중 하나라도 기본값을 가지지 않는 경우에는 직접 init을 구현</strong> 해줘야한다.</p>
<p>Class의 name은 일단 옵셔널로 선언이 되어있다.
옵셔널로 선언하지 않으면 어떻게 될까? <strong>컴파일 오류</strong>가 뜬다!</p>
<blockquote>
<p>error: class &#39;Person&#39; has no initializers</p>
</blockquote>
<p>라고 뜰 것이다. 이유가 뭘까? 
옵셔널은 nil값을 가질 수 있기에 자동적으로 초기화 동안 &quot;아직 값 없음&quot;이라는 의미에서 nil값으로 자동 할당된다. 
즉, 옵셔널 타입이 아닌 경우에는 init를 직접 구현해줘야하는 것이다. </p>
<pre><code class="language-swift">class Person {
    var name: String
    init(name: String) {
        self.name = name
    }
}

let P = Person(name: &quot;what&quot;)
P.name = &quot;Hey&quot;</code></pre>
<p>name을 옵셔널이 아닌 변수로 만들려면 위와 같이 init을 구현해줘야한다.</p>
<p>Struct를 보자, </p>
<pre><code class="language-swift">struct Person {
    var name: String
}

let P = Person(name: &quot;change-challenge&quot;)
P.name = &quot;Hey&quot; // 컴파일 오류! </code></pre>
<p>Struct는 memberwise init이라고 기본적으로 init를 구현해준다. 
struct안에 </p>
<pre><code class="language-swift">init(name: String) {
    self.name = name
}</code></pre>
<p>가 숨어있는 것이라고 생각하면 된다. 
그렇기에 Person(name: &quot;change-challenge&quot;) 이라고 <strong>인수라벨</strong>도 붙을 수 있는 것이다. </p>
<h3 id="결론">결론</h3>
<p>이와 같이 class와 struct가 다른 점을 조금 살펴보았다. 
익숙하지 않은 언어를 깊게 파보는 것은 코딩 선조들이 과거에 있던 문제점을 해결하려고 했던 노력을 볼 수 있기에 재밌다.</p>
<blockquote>
<p>class vs struct 차이점을 위해 참고한 사이트
<a href="https://bbiguduk.gitbook.io/swift/language-guide-1/initialization">https://bbiguduk.gitbook.io/swift/language-guide-1/initialization</a>
<a href="https://jayb-log.tistory.com/216">https://jayb-log.tistory.com/216</a>
<a href="https://saad-eloulladi.medium.com/swift-enums-vs-structures-vs-classes-938a4cd76c0d">https://saad-eloulladi.medium.com/swift-enums-vs-structures-vs-classes-938a4cd76c0d</a></p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>