<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>choijun0_2.log</title>
        <link>https://velog.io/</link>
        <description>Developer가 되고싶은 꿈나무</description>
        <lastBuildDate>Sun, 24 Jul 2022 15:28:55 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>choijun0_2.log</title>
            <url>https://velog.velcdn.com/images/choijun0_2/profile/a0310e54-273c-463e-8090-88510067a23a/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. choijun0_2.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/choijun0_2" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Swift TypeCasting]]></title>
            <link>https://velog.io/@choijun0_2/Swift-TypeCasting</link>
            <guid>https://velog.io/@choijun0_2/Swift-TypeCasting</guid>
            <pubDate>Sun, 24 Jul 2022 15:28:55 GMT</pubDate>
            <description><![CDATA[<h1 id="타입캐스팅">타입캐스팅</h1>
<hr>
<p>스위프트에서 타입캐스팅이란 인스턴스의 타입을 확인하거나 인스턴스를 superClass나 subClass로 취급하는 방법을 의미한다.</p>
<pre><code class="language-swift">var someInt: Int=10;

var someDouble: Double = Double(someInt)</code></pre>
<p>위코드는 Double타입의 init함수를 통해 만들어진 새로운 값에 불과하다. 타입캐스팅 이라고 볼 수 없다.</p>
<h2 id="is">is</h2>
<p>is키워드는 인스턴스가 현재 어떤타입인지 확인할 때 사용한다.
유의할 점은 인스턱스의 부모 클래스 역시 자신이 포함함으로 같은 타입으로 인식한다. 아래코드를 보자</p>
<pre><code class="language-swift">class Person {
    var name: String
    var age: Int
    init(name: String, age:Int){
        self.name=name
        self.age=age
    }
}

//class는 하나의 상위 클래스만을 상속받을 수 있다..
class Student: Person {
    var grade: Int;

    init(name:String, age:Int, grade:Int){
        self.grade=grade
        super.init(name: name, age: age)
    }
}

var someStudent = Student(name: &quot;choi&quot;, age: 23, grade: 3)

//someStudent는 Person타입의 자식 인스턴스 임으로 결과는 true이다
print(someStudent is Person) //true
print(someStudent is Student) //true
</code></pre>
<h2 id="as">as</h2>
<p>as키워드는 특정 인스턴스를 다른 타입으로 치환하여 사용하고 싶을 때 사용한다.
자식타입을 부모타입으로 치환하는 다운캐스팅은 가능하지만 역순으로 할 경우 nil값을 반환한다.</p>
<pre><code class="language-swift">//as? 키워드는 옵셔널 타입을 반환한다
if let person = someStudent as? Person {
    print(&quot;I&#39;m person&quot;)
}
var somePerson = Person(name: &quot;hoon&quot;, age: 21)

//업캐스팅시 nil을 반환한다.
guard let someStu=somePerson as? Student else {
    print(&quot;I&#39;m not student&quot;)
    fatalError()
}</code></pre>
<p>옵셔널 강제추출처럼 다운캐스팅도 강제추출이 가능하다.</p>
<pre><code class="language-swift">let person1 = someStudent as! Person

print(type(of: person1)) //Person</code></pre>
<p>하지만 업캐스팅이 가능한 경우도 있다</p>
<pre><code class="language-swift">class Brain {   
    func say(){
        print(&quot;1&quot;)
    }
}

class Person:Brain{  
    func good() {
        print(2)
    }
}


var var1:Brain = Person() as Brain

var var2:Person=var1 as! Person

var2.good() //2</code></pre>
<p>한번 다운캐스팅된 타입을 다시 업캐스팅하는 것은 가능하다.</p>
<p>특이한 경우가 하나더 있다.
만약 다형성 구현을 한 관계에서 다운캐스팅을 할 경우 다운캐스팅 하였다 할지라도 override된 함수가 호출된다!!! amazing</p>
<pre><code class="language-swift">class Brain {

    func say(){
        print(1)
    }
}

class Person:Brain{

    override func say() {
        print(2)
    }
}


var var1:Brain = Person() as Brain

var1.say() //2
</code></pre>
<hr>
<p>as와 is는 상속뿐만아니라 해당 타입이 어떤 <strong>프로토콜</strong>을 가지는 지 확인할 때도 사용이 가능하다.</p>
<pre><code class="language-swift">protocol SomeProtocol {
    var name: String {get set}
}

class Person: SomeProtocol {
    var name: String = &quot;choi&quot;
}

var person = Person()

print(person is SomeProtocol) //true

if let haveP = person as? SomeProtocol {
    print(&quot;yes&quot;) //yes
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[메모리 구조 모델 정리]]></title>
            <link>https://velog.io/@choijun0_2/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0-%EB%AA%A8%EB%8D%B8-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@choijun0_2/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0-%EB%AA%A8%EB%8D%B8-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 24 Jul 2022 08:17:18 GMT</pubDate>
            <description><![CDATA[<h1 id="64비트와-32비트">64비트와 32비트</h1>
<hr>
<p>글을 시작하기 앞서 64비트 CPU와 32비트 CPU에 대해 설명하겠다. 
CPU는 수많은 레지스터들로 구성되는데 한번에 처리할 수 있는 레지스터 작업량이 정해져 있다. 이때 작업량의 크기에 따라 몇비트CPU인가가 정해진다.
<code>CPU의 작업량의 크기가 메모리 주소의 크기를 결정짓는다.</code></p>
<ul>
<li>32비트 CPU는 메모리 주소가 32비트이다.<ul>
<li>0x00000000~0xFFFFFFFF까지의 메모리 공간만을 사용할 수 있다<ul>
<li>메모리 주소의 제한은 메모리 용량의 제한으로 이어진다.<ul>
<li>메모리 주소들 사이의 간격은 1바이트이다. 따라서 32비트 컴퓨터의 메모리 용량은 최대 4GB이다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>64비트 컴퓨터인 경우는 32비트와 다르게 16자리의 16진수로 표현되며 훨씬 더 큰 메모리 용량을 가질 수 있다. </li>
</ul>
<h2 id="메모리-주소-할당-구조">메모리 주소 할당 구조</h2>
<pre><code class="language-swift">var var1: Int = 10</code></pre>
<p>위와 같이 코드를 작성했다고 생각보자
Integer의 메모리 크기는 4바이트이다.
64비트 CPU에서 메모리주소가 0xFFFFFFFFFFFFFFFF에서 시작한다고 할때 
0xFFFFFFFFFFFFFFFF~0xFFFFFFFFFFFFFFFC 영역을 위변수가 차지하게 된다.</p>
<h1 id="메모리-구조-모델">메모리 구조 모델</h1>
<hr>
<p><img src="https://miro.medium.com/max/1400/1*fwkyPI8Gmzd0Q_XAGM5_eA.png" alt="이미지">
<a href="https://medium.com/@jungkim/%EC%8A%A4%EC%9C%84%ED%94%84%ED%8A%B8-%ED%83%80%EC%9E%85%EB%B3%84-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%B6%84%EC%84%9D-%EC%8B%A4%ED%97%98-4d89e1436fee">이미지 출처</a></p>
<p>프로세스에 할당된 메모리 공간은 기본적으로 위와같은 영역들로 구분된다.</p>
<h2 id="stack">Stack</h2>
<p>스택 영역은 함수스택프레임이 쌓이는 공간이다.
함수스택프레임이란 함수안에 내장된 지역변수들과 리턴타입등이 저장된 하나의 꾸러미이다.</p>
<p>함수가 호출되면 Stack영역으로 push되 실행되면 pop되는 방식으로 작동한다.</p>
<ul>
<li><p>스택프레임내의 변수</p>
<ul>
<li>변수들은 기본적으로 값을 가진다. 컴파일 이전에 정적으로 값이 할당된 변수들은 Stack영역에 값이 기록된다. (변수에 할당되는 것이 값타입 일 때이다.)</li>
</ul>
</li>
<li><p>메모리 주소의 시작점</p>
<ul>
<li>스택 영역의 경우 메모리 주소가 High Address부터 시작된다. 메모리 주소값이 높은 곳에서 낮은곳으로 기록되는 구조이다.<h2 id="heap">Heap</h2>
힙 영역은 스택영역과 달리 런타임시 정적으로 할당된 값들과 참조타입으로 선언된 클래스 인스턴스가 저장된다.</li>
</ul>
</li>
<li><p>메모리 주소의 시작점</p>
<ul>
<li>스택영역과 달리 힙영역은 낮은 곳에서부터 메모리 주소가 시작되 증가된다. </li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[git 작업 흐름]]></title>
            <link>https://velog.io/@choijun0_2/git-%EC%9E%91%EC%97%85-%ED%9D%90%EB%A6%84</link>
            <guid>https://velog.io/@choijun0_2/git-%EC%9E%91%EC%97%85-%ED%9D%90%EB%A6%84</guid>
            <pubDate>Tue, 19 Jul 2022 00:40:51 GMT</pubDate>
            <description><![CDATA[<h1 id="기본개념">기본개념</h1>
<p>깃저장소로 지정된 파일은 깃에의해 3가지의 논리적 저장 공간으로 분류된다</p>
<ul>
<li>작업을 하는 공간(working directory) 
저장소내 파일을 수정하는 공간이다.</li>
<li>스테이지 공간(stage)
수정된 파일의 상태를 임시적으로 저장하는 공간이다.</li>
<li>기록하는 공간
commit을 통해 수정상태를 영구적으로 기록하는 공간이다.</li>
</ul>
<h1 id="기본적인-작업흐름">기본적인 작업흐름</h1>
<h2 id="init">init</h2>
<p><img src="https://firebasestorage.googleapis.com/v0/b/uploadpicturebusket.appspot.com/o/git_init.png?alt=media&token=aa8d74d8-1c39-49d2-ac4e-8065b6727654" alt=""></p>
<p>먼저 로컬깃허브 저장소를 만들고 touch명령어로 텍스트파일을 추가했다.</p>
<hr>
<h2 id="add">add</h2>
<p>add명령어는 워크디렉토리에 있는 작업물을 깃에서 관리할 수 있도록 등록(tracked)상태로 변경하는 역할을 한다. tracked상태가된 파일들은 stage 공간으로 이동해 commit이 되기 직전에 위치한다.</p>
<p>밑의 사진을 보면 파일생성후 status명령어를 실행시키면 파일이 untracked상태인 것을 확인할 수 있다.</p>
<p><img src="https://firebasestorage.googleapis.com/v0/b/uploadpicturebusket.appspot.com/o/%E1%84%89%E1%85%A2%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF%20%E1%84%89%E1%85%A2%E1%86%BC%E1%84%89%E1%85%A5%E1%86%BC%E1%84%92%E1%85%AE%20%E1%84%83%E1%85%B3%E1%86%BC%E1%84%85%E1%85%A9%E1%86%A8.png?alt=media&token=35c63afb-6288-4928-be07-0d937e3a4c59" alt=""></p>
<p>이상태에서 텍스트 파일을 수정해보도록 하겠다.</p>
<p><img src="https://firebasestorage.googleapis.com/v0/b/uploadpicturebusket.appspot.com/o/%E1%84%83%E1%85%B3%E1%86%BC%E1%84%85%E1%85%A9%E1%86%A8%E1%84%83%E1%85%AC%E1%86%AB%20%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF%20%E1%84%89%E1%85%AE%E1%84%8C%E1%85%A5%E1%86%BC.png?alt=media&token=831f5ccf-11f8-4cca-ba7f-66b088c52d23" alt=""></p>
<p><img src="https://firebasestorage.googleapis.com/v0/b/uploadpicturebusket.appspot.com/o/%E1%84%89%E1%85%AE%E1%84%8C%E1%85%A5%E1%86%BC%E1%84%92%E1%85%AE%20untracked%3Aunstage%E1%84%83%E1%85%AC%E1%86%AB%20%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF.png?alt=media&token=4bab1372-dc68-4c45-b0b0-580a5b8cec66" alt=""></p>
<p>등록된(tracked)된 파일을 워킹디렉토리에서 수정하게 되면 unmodified상태에서 modified상태로 회귀하게 된다. 이때 파일은 stage공간에서 배제되고 untracked상태로도 돌아가게 된다.</p>
<pre><code>등록 직후 파일         
- unmodified        
- on stage          
- tracked
- can commit</code></pre><pre><code>등록후 수정된 파일
- modified
- working directory(not on stage)
- untracked
- can&#39;t commit</code></pre><hr>
<h2 id="commit">commit</h2>
<p>깃은 커밋직전 가장 최근에 컷밋된 부모커밋(HEAD포인터에 저장)와 커밋될 스테이지 저장소를 비교후 새로운 커밋 객체를 만든다.</p>
<p>마지막으로 수정된 파일을 다시 등록하고 commit해 보도록하겠다.</p>
<p><img src="https://firebasestorage.googleapis.com/v0/b/uploadpicturebusket.appspot.com/o/%E1%84%8F%E1%85%A5%E1%84%86%E1%85%B5%E1%84%89%E1%85%A5%E1%86%BC%E1%84%80%E1%85%A9%E1%86%BC.png?alt=media&token=75704865-5667-4ab7-8f26-d03968cae8fd" alt=""></p>
<hr>
<h2 id="push">push</h2>
<p>위의 예시는 로컬저장소만을 활용 했음으로 push를 사용하지 못한다.
만약 원격저장소를 로컬로 clone했다면 commit한 내용을 push 명령어로 원격저장소에 업로드 할 수 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Permission denied(publickey)]]></title>
            <link>https://velog.io/@choijun0_2/Permission-deniedpublickey</link>
            <guid>https://velog.io/@choijun0_2/Permission-deniedpublickey</guid>
            <pubDate>Mon, 18 Jul 2022 09:27:37 GMT</pubDate>
            <description><![CDATA[<h1 id="원격저장소-클론">원격저장소 클론</h1>
<p>원격저장소에 있는 Gist파일들을 로컬저장소로 클론해 수정하려고 한다.</p>
<pre><code class="language-git">$ git clone 원격저장소주소</code></pre>
<p>진해한던 도중</p>
<pre><code>it@github.com: Permission denied (publickey)</code></pre><p>위와같은 오류와 마주했다. 
오류가 발생한 이유는 로컬 저장소에 ssh key가 깃허브 계정에 등록되있지않아 발생한 문제이다.</p>
<h2 id="ssh-key-등록-방법">ssh key 등록 방법</h2>
<pre><code>$ ssh-keygen</code></pre><p>명령어를 입력해주면 특정 위치에 <code>id_rsa.pub</code> 이 생성된 것을 화인할 수있다.</p>
<pre><code>$ cat ~/id_rsa.pub</code></pre><p>명령어를 입렵해주면 터미널에 나타는 key를 복사한 후 깃허브계정으로 접속한다.</p>
<p><img src="https://firebasestorage.googleapis.com/v0/b/uploadpicturebusket.appspot.com/o/%E1%84%80%E1%85%B5%E1%86%BA%E1%84%92%E1%85%A5%E1%84%87%E1%85%B3%20sshkey%E1%84%8B%E1%85%B1%E1%84%8E%E1%85%B5.png?alt=media&token=9d52ec8e-8d41-4adf-bfb6-1ebf42ce3bc0" alt="깃허브sshkey관리"></p>
<p>위의 설정으로 들어가 New ssh key를 누르고 나오는 창의 key영역에 복사한 key를 붙여넣기한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Swift class & struct]]></title>
            <link>https://velog.io/@choijun0_2/Swift-class-struct</link>
            <guid>https://velog.io/@choijun0_2/Swift-class-struct</guid>
            <pubDate>Sat, 16 Jul 2022 07:31:36 GMT</pubDate>
            <description><![CDATA[<h1 id="클래스와-구조체-기본">클래스와 구조체 기본</h1>
<h2 id="정의">정의</h2>
<pre><code class="language-swift">struct PersonStruct {
    var name: String
    var age: Int
    //class와 다르게 struct는 기본적으로 멤버와이즈 이니셜라이저가 생성된다.
}


class PersonClass {
    var name: String
    var age: Int
    //멤버와이즈 이니셜라이저
    init(name: String, age: Int){ 
        self.name = name
        self.age = age
    }
}</code></pre>
<p><code>💡클래스와 구조체의 프로퍼티들은 반드시 초기화 되어야 한다.</code></p>
<h2 id="클래스와-구조체의-차이">클래스와 구조체의 차이</h2>
<h3 id="할당-방식의-차이">할당 방식의 차이</h3>
<pre><code class="language-swift">var struct1: PersonStruct = PersonStruct(name: &quot;choi&quot;, age: 22);
let class1: PersonClass = PersonClass(name: &quot;hoon&quot;, age: 21);

var struct2: PersonStruct = struct1;
let class2: PersonClass = class1;

//구조체는 값을 복사해서 전달한다.
struct2.name=&quot;jun&quot;;
print(struct1.name) //choi, 구조체는 각각이 존재한다.

//클래스는 값을 복사하지 않고 인스턴스의 위치를 참조한다.
class1.age = 32
print(class2.age) //32, 같은곳을 참조함으로 함께 변한다

//클래스 참조 식별 연산자 ===
print(class1 === class2) //true
</code></pre>
<p><strong>전달인자(매개변수)</strong>로서 클래스와 구조체가 전달될때 역시 같은 개념이 적용된다.
<code>💡inout매개변수를 활용하면 아래 코드처럼 구조체도 참조방식을 사용할 수 있다.</code></p>
<pre><code class="language-swift">func referStruct(_ refer: inout PersonStuct) -&gt; Void {
    refer.name = &quot;change&quot;;
}
func referClass(_ refer: PersonClass) -&gt; Void {
    refer.name = &quot;change&quot;;
}

referStruct(&amp;struct1); //inout 매개변수 전달방식
referClass(class1);

print(struct1.name) //change
print(class1.name) //change
</code></pre>
<h2 id="구조체의-사용시기">구조체의 사용시기</h2>
<ul>
<li>값의 집합을 캡슐화하는 것만이 목적일때</li>
<li>캡슐화한 값을 참조하는 것보단 복사하는 것이 합당할 때</li>
<li>다른타입의 상속이 불필요할 때</li>
</ul>
<hr>
<h1 id="프로퍼티">프로퍼티</h1>
<h2 id="지연저장프로퍼티">지연저장프로퍼티</h2>
<p>🔎사용시기 </p>
<ul>
<li>인스턴스의 많은양의 프로퍼티가 한번에 생성되는게 비효율적일 경우</li>
<li>모든프로퍼티를 사용할 필요가 없는 경우<pre><code class="language-swift">//lazy 키워드를 프로퍼티 앞에 작성해준다.
struct LazyStruct {
  lazy var lazyVar: String = &quot;lazy man&quot;
}</code></pre>
</li>
</ul>
<p>😲예외사항: 지연저장프로퍼티가 <strong>let</strong>으로 선언됬을 경우</p>
<pre><code class="language-swift">struct LazyStruct {
    lazy let lazyVar: String = &quot;lazy man&quot;
}

let lazyClass: LazyStruct = LazyStruct(); 
print(lazyClass.lazyVar); //cannot use mutating getter on immutable value</code></pre>
<p>lazyClass.lazyVar를 호출할 때 lazyVar에 값이 할당된다. 
<strong>let 키워드로 선언된 프로퍼티는 초기화 시에만 값 할당이 가능</strong>함으로 에러가 발생하게 된다.</p>
<h3 id="📃고려사항">📃고려사항</h3>
<ul>
<li>다중스레드 환경에서 한꺼번에 지연저장프로퍼티를 호출한다면 
값이 여러번 할당되는 현상이 나타날 수 있다.</li>
<li>전역 변수/상수는 호출시에 할당을 실시한다. 
즉, 전역변수/상수는 기본적으로 lazy 키워드 특성을 지니고 있다.</li>
</ul>
<hr>
<h1 id="연산프로퍼티">연산프로퍼티</h1>
<ul>
<li><p>프로퍼티에 대한 접근자와 설정자를 가독성 높게 표현가능하다.</p>
<h2 id="연산프로퍼티와-프로퍼티-감시자">연산프로퍼티와 프로퍼티 감시자</h2>
<pre><code class="language-swift">struct MyInform {
  var name: String
  //연산프로퍼티 sayHello
  var sayHello: String {
      get {
          name + &quot;입니다&quot; //코드가 한줄이라면 return키워드 생략가능
      }

      set(newName) { //전달인자를 작성하지 않으면 newValue를 기본으로 사용가능하다.
          name = newName;
      }
  }

  //age 프로퍼티 감시자
  var age: Int { 
      //값 변경 직전 실행된다.
      //전달인자를 사용하지 않으면 newValue, oldValue를 기본으로 사용가능하다.
      willSet(newOne) {
          print(&quot;age값이 \(newOne)로 변경됩니다.&quot;);
      }
      //값 변경 후 실행된다.
      didSet(oldOne) {
          print(&quot;age값이 \(oldOne)에서 \(age)로 바꼈습니다.&quot;);
      }
  }
}
</code></pre>
</li>
</ul>
<p>var myName: MyInform = MyInform(name: &quot;choi&quot;, age: 22);
print(myName.sayHello);   // choi입니다 (get)
myName.sayHello = &quot;hoon&quot;; // (set)
print(myName.sayHello);   // hoon입니다 (get)</p>
<p>myName.age = 44; //age값이 44로 변경됩니다.(willSet) age값이 22에서 44로 바꼈습니다.(didSet)</p>
<pre><code>`💡프로퍼티의 값이 초기화될때는 프로퍼티 감시자 매서드가 호출 되지 않습니다.😮`

`🔎프로퍼티 감시자, 연산 프로퍼티는 프로퍼티에 쓰였지만 해당기능은` 
`모든 전역, 지역변수가 사용이 가능합니다.`

---

# 타입프로퍼티
c , cpp 언어의 static과 유사한 개념이다.
```swift
struct TypeStruct {
    static let myStaticProp = 100;

    var calcProp: Int {
        get {
            Self.myStaticProp //대문자 Self는 내부에서 타입자체를 가리킨다.
        }
    }
}

//타입을 통해 직접 호출
print(TypeStruct.myStaticProp) //100

var ts: TypeStruct = TypeStruct();
print(ts.calcProp); //100
</code></pre><p><code>💡self는 내부에서 인스턴스를 가리키고 Self는 내부에서 타입자체를 가리킨다.</code></p>
<hr>
<h1 id="self--self">Self &amp; self</h1>
<ul>
<li><p>self는 <strong>모든 인스턴스가 암시적으로</strong> 생성하는 프로퍼티이다. </p>
</li>
<li><p><em>자기 자신을 가리키는 것*</em>으로, 클래스나 구조체 등의 인스턴스 내에서 사용할 수 있다.</p>
</li>
<li><p>구조체나 열거형일 경우, self 프로퍼티를 사용해 자기 <strong>자신으로 교체(치환)가 가능하다</strong>. 
클래스는 참조 타입이라, self 프로퍼티에 다른 참조를 할당할 수 없다.</p>
</li>
<li><p>Self는 <strong>타입</strong>이다. 특정한 타입이 아니라, 타입의 이름을 반복해 작성하지 않고 
현재 타입을 가리키는 코드를 사용할 수 있게 해 준다</p>
</li>
</ul>
<hr>
<h1 id="프로퍼티와-키경로">프로퍼티와 키경로</h1>
<ul>
<li>swift에서 함수를 변수/상수에 저장해 사용하는 것처럼</li>
<li><em>클래스나 구조체의 프로퍼티 위치*</em>를 저장해서 사용할 수 있다.</li>
<li>키경로는 
구조체의 경우 <code>WritableKeyPath&lt;AddressStruct, String&gt;</code>를 사용한다.
클래스의 경우 <code>ReferenceWritableKeyPath&lt;AddressClass, String&gt;</code>를 사용한다.</li>
</ul>
<pre><code class="language-swift">struct AddStruct {
    var home: String
    var email: String
}

class AddClass {
    var home: String = &quot;&quot;
    var email: String = &quot;&quot;
}

// \, . 를 이용해 선언이 가능하다.
var structKeyPath = \AddStruct.home;
var classKeyPath = \AddClass.home;

//구조체와 클래스의 키경로는 다른 타입을 가진다.
print(type(of: structKeyPath)) //WritableKeyPath&lt;AddStruct, String&gt;
print(type(of: classKeyPath)) //ReferenceWritableKeyPath&lt;AddClass, String&gt;

var structInstance: AddStruct = AddStruct(home: &quot;Seoul&quot;, email: &quot;email@naver.com&quot;);

//해당 프로퍼티에 키경로를 전달해 값을 추출할 수 있다.
print( structInstance[keyPath: structKeyPath] ); //Seoul

//해당프로퍼티를 수정할 수 있다. 상수인 경우는 불가능하다.
structInstance[keyPath: structKeyPath] = &quot;Daejun&quot;;
print( structInstance[keyPath: structKeyPath] ); //Daejun

//.self 를 사용해 타입을 유추시킬 수 있다.
print( structInstance[keyPath: \.self.email ] ) //email@naver.com
</code></pre>
<p><code>📝위내용중 [keyPath:]의 사용에 대해서는 서브스크립트 포스팅에서 정리하도록 하겠다.</code></p>
<hr>
<h1 id="매서드">매서드</h1>
<pre><code class="language-swift">struct MyStruct {
    var name: String

    //구조체의 경우 내부프로퍼티의 값을 변경(mutate)하는 매서드는 mutating 키워드를 붙여줘야 한다.
    //클래스는 상관없다.
    mutating func changeName(_ name: String) {.
        self.name = name; //mutating
    }

    mutating func allnewStruct(_ name: String) {
        //구조체의 경우만 self를 사용해 자기자신을 치환시킬 수 있다. 
        self = MyStruct(name: name);
    }

    //인스턴스 함수처럼 호출 할수 있도록 해준다.
    func callAsFunction() {
        print(name);
    }

    //개수제한 없이 생성 가능하다.
    func callAsFunction(_ remark: String) {
        print(&quot;my name is \(name), \(remark)&quot;);
    }
}

var myName: MyStruct = MyStruct(name: &quot;choi&quot;);
myName() //choi
myName.changeName(&quot;hoon&quot;)
myName() //hoon
myName.allnewStruct(&quot;young&quot;)
myName() //young

myName(&quot;nice to meet you.&quot;) //my name is young, nice to meet you.
</code></pre>
<hr>
<h1 id="타입매서드">타입매서드</h1>
<ul>
<li><p>앞의 타입 프로퍼티와 비슷한 개념이다.</p>
</li>
<li><p>class 키워드를 사용한 타입매서드는 상속시 <strong>재정의(overriding)가 가능하다</strong>.</p>
</li>
<li><p>static 키워드를 사용하면 재정의가 불가능하다.</p>
<pre><code class="language-swift">class Aclass {
  static func sayHello(){
      print(&quot;Hello~&quot;)
  }

  class func sayGoodBye() {
      print(&quot;Good Bye&quot;)   
  }

  static func hiAndBye() {
      //타입 매서드에서 self는 인스턴스가 아닌 타입자체를 가리킨다.
      self.sayHello();
      self.sayGoodBye();
  }
}
</code></pre>
</li>
</ul>
<p>class Bclass: Aclass{
    //타입매서드 재정의
    override class func sayGoodBye(){
        print(&quot;Good Bye, see you again!&quot;)
    }
}</p>
<p>Aclass.hiAndBye(); //Hello~ Good Bye</p>
<p>//재정의 됬음으로 재정의전 매서드는 실행되지 않는다.
Bclass.sayGoodBye(); //Good Bye, see you again!</p>
<pre><code>---
# 이니셜라이저
- 옵셔널 타입을 제외한 인스턴스의 모든 프로퍼티는 초기화시 값을 가져야한다.
- 상수 프로퍼티의 경우 기본값사용하거나 이니셜라이저에서 초기화가 가능하다.

## 실패가능한 이니셜라이저
- 프로퍼티 초기화시 전달인자의 오류 등으로 의도치않은 생성을 막기위해 사용된다.
- init 함수 뒤에 ?를 붙여 선언한다.
- 초기화에 실패한경우 nil을 반환해 실패사실을 알린다.
```swift
struct School {
    var name: String;

    init?(_ name: String){
        if name.isEmpty {
            return nil;
        }
        self.name = name;
    }
} 

var mySchool: School? = School(&quot;&quot;)
print(mySchool) //nil

//열거형 활용
enum SchoolAge: String{
    case elementary=&quot;초등학생&quot;
    case middle=&quot;중학생&quot;

    init?(_ age: Int){
        switch(age){
            case 8...13:
                //self를 사용하여 자신 지정
                self = .elementary
            case 14...16:
                self = .middle
            default:
                return nil
        }
    }
}

//초기화 실패시 옵셔널값을 받아야 함으로 옵셔널타입으로 선언한다.
var choi: SchoolAge? = SchoolAge(22);
print(choi == Optional&lt;SchoolAge&gt;.none); //true</code></pre><p><code>💡열거형 항목을 rawValue로 조회하는 방법은 실패가능한 이니셜라이저의 예시이다.</code></p>
<pre><code class="language-swift">enum ForSearch: Int{
    case zero, one

    init?(value: Int){
        switch value {
        case 0:
            self = .zero
        case 1:
            self = .one
        default:
            return nil;
        }
    }
}

//value를 rawValue로 바꾸기만 하면 기존 매서드랑 일치한다.
var test: ForSearch? = ForSearch(value: 2)

print(test); //nil</code></pre>
<h2 id="클로저를-활용한-초기화-방법">클로저를 활용한 초기화 방법</h2>
<p>초기화 클로저 내부 유의사항</p>
<ul>
<li>인스턴스의 <strong>다른 프로퍼티, 매서드가 초기화 전</strong>임으로 사용이 불가능하다.</li>
<li>self 프로퍼티 역시 사용이 불가능하다.</li>
<li>반환하는 값의 타입이 <strong>프로퍼티 타입과 일치해야 한다</strong>.<pre><code class="language-swift">struct ClosureStruct {
  var name: String = {
      () -&gt; String in //생략가능한 표현
      return &quot;choi&quot;  //프로퍼티 타입인 String
  }() //클로저를 실행값을 반환해야 함으로 ()붙여 실행문으로 작성한다.
}
</code></pre>
</li>
</ul>
<p>var me: ClosureStruct = ClosureStruct();
print(me.name); //choi</p>
<pre><code>`🔎클로저는 클로저 포스팅에서 자세하게 설명하겠다.`

---

# 인스턴스 소멸
- 클래스 인스턴스에서만 구현가능하다.
- 사용목적은 예를들어 클래스가 어떤 파일을 열고 소멸된다면 파일은 열린채로 방치된다. 
이런 상황을 막기위해 사용한다.
- deinit 이름으로 선언되며 모든 프로퍼티에 접근 가능하다.
```swift
class SomeClass{
    deinit {
        print(&quot;good bye&quot;);
    }
}

var test: SomeClass? = SomeClass();

//인스턴스가 어느곳에도 참조되있지 않음으로 소멸된다.👉deinit호출
test = nil; //good bye</code></pre><hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Swift enum class]]></title>
            <link>https://velog.io/@choijun0_2/Swift-enum-class</link>
            <guid>https://velog.io/@choijun0_2/Swift-enum-class</guid>
            <pubDate>Sun, 10 Jul 2022 05:42:12 GMT</pubDate>
            <description><![CDATA[<h1 id="basic-knowledge">Basic knowledge</h1>
<ul>
<li>한번 선언한 열거형의 항목은 추가 및 수정이 불가능하다.</li>
<li>선언한 열거형은 고유의 타입으로 인식된다.</li>
</ul>
<hr>
<h1 id="기본형">기본형</h1>
<pre><code class="language-swift">enum Food {
    case spagetti
    case hamburger
    case coke
    case cake, pizza, susi //연속적인 항목선언 가능
}

let b: Food = Food.spagetti
let a: Food = .spagetti //타입이 지정됬다면 열거형 이름은 생략이 가능하다.

print(a, b) //spagetti spagetti</code></pre>
<p>아래코드에 주목해보자</p>
<pre><code class="language-swift">let a: Food = .spagetti</code></pre>
<p>a변수에 타입을 Food라고 지정해주면 .spagetti를 부여할 때 Food 생략 가능한 것을 알 수 있다.
주의해야할 점은 .spagetti앞에는 반드시 <strong>공백이 존재해야한다는 점이다</strong>.
공백을 지정하지 않으면 오류가 발생한다
추가적으로 swift의 <code>=</code> 대입연산자는 양옆항이 같은 공백영역을 가져야 한다.</p>
<pre><code class="language-swift">//오류가 발생하는 경우
let a: Food= .spagetti
let a: Food =.spagetti
let a: Food=.spagetti

//올바른경우
let a: Food = .spagetti</code></pre>
<hr>
<h1 id="원시값을-가지는-열거형">원시값을 가지는 열거형</h1>
<pre><code class="language-swift">enum Food2: String {
    case pizza=&quot;bread&quot;
    case hamburger=&quot;meal&quot;
    case chicken=&quot;animal&quot;,soda=&quot;juice&quot;
    case steak //지정값은 선택사항이다.
}

let meal = Food2.pizza;
print(meal.rawValue); //bread</code></pre>
<h2 id="지정값이-없는-경우">지정값이 없는 경우</h2>
<pre><code class="language-swift">//지정값 타입이 String인 경우는 각항목의 이름이 지정값이 된다.
print (Food2.steak.rawValue); //steak 

//타입이 Int의 경우 앞의 항목부터 0부터 오름차순으로 자동 지정된다.
enum TestInt: Int{
    case zero
    case one
    case two
}

print(TestInt.zero.rawValue, TestInt.one.rawValue, TestInt.two.rawValue) //0 1 2</code></pre>
<h2 id="지정값을-사용해-항목-찾기">지정값을 사용해 항목 찾기</h2>
<pre><code class="language-swift">//옵셔널 바인딩 사용
if let bind = Food2(rawValue: &quot;bread&quot;){
    print(bind) //pizza
}
else {
    print(&quot;해당하는 원시값을 가진 항목이 없습니다.&quot;)
}</code></pre>
<hr>
<h1 id="연관값을-가지는-열거형">연관값을 가지는 열거형</h1>
<p>위의 지정값과 다르게 항목마다 다른 타입의 값을 가질수 있다.</p>
<pre><code class="language-swift">enum Date {
    case birthday(year: Int, month: Int, date: Int) //튜플형
    case birth_year(Int) //이름을 명시하지 않아도 된다
}

let myDay:Date = .birthday(year: 2002, month: 4, date: 32)
let myYear:Date = .birth_year(2002);

print(myDay) //birthday(year: 2002, month: 4, date: 32)
print(myYear) //birth_year(2002)</code></pre>
<h2 id="연관값의-활용">연관값의 활용</h2>
<h3 id="switch">Switch</h3>
<p>🔍<a href="https://velog.io/@choijun0_2/Swift-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95">Swift Switch포스팅</a></p>
<pre><code class="language-swift">enum Cooking {
    case rare, medium, wellDone
}
enum Sauce {
    case ketchap, mustard, redWine
}
enum Food {
    case steak(_ level: Cooking, _ sauce: Sauce, _ animal: String)
}

func steakOlder(_ data: Food){
    switch(data){
        case .steak(Cooking.medium, Sauce.mustard, &quot;Beaf&quot;):
        print(&quot;That&#39;t my steak.&quot;)
        case .steak(Cooking.medium, Sauce.mustard, _):
        print(&quot;Well, give to me.&quot;)
        case .steak(Cooking.medium, Sauce.redWine, let animal):
        print(&quot;I dont mind where it came from, give me that \(animal) steak.&quot;)
        case let .steak(level, sauce, animal): //모든 연관값을 바인딩할 때
        print(&quot;\(level) \(sauce) \(animal) steak well, give me.&quot;);
    }
}

steakOlder(Food.steak(Cooking.medium, Sauce.mustard, &quot;Beaf&quot;)) //That&#39;t my steak.
steakOlder(Food.steak(Cooking.medium, Sauce.mustard, &quot;Pork&quot;)) //Well, give to me.
steakOlder(Food.steak(Cooking.medium, Sauce.redWine, &quot;Pork&quot;)) 
//I dont mind where it came from, give me that Pork steak.
steakOlder(Food.steak(Cooking.rare, Sauce.ketchap, &quot;Chicken&quot;)) 
//rare ketchap Chicken steak well, give me.</code></pre>
<hr>
<h1 id="프로토콜과-열거형">프로토콜과 열거형</h1>
<h2 id="항목순회-프로토콜">항목순회 프로토콜</h2>
<pre><code class="language-swift">enum School: CaseIterable {
    case elementary, middle, high, university
}

//지정값이 있는 경우
enum School: String, CaseIterable {
    case elementary=&quot;초등학교&quot;
    case middle=&quot;중학교&quot;
}</code></pre>
<p>+위 내용에 대해서는 map/reduce 학습후 추가로 포스팅 하겠다.(22.7.10)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Swift operator]]></title>
            <link>https://velog.io/@choijun0_2/swift%EC%96%B8%EC%96%B4-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@choijun0_2/swift%EC%96%B8%EC%96%B4-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Sun, 19 Jun 2022 08:18:06 GMT</pubDate>
            <description><![CDATA[<p>swift에서 사용되는 연산자들중 다른어언들과 차이점을 중심으로 작성하였다.</p>
<h1 id="연산자">연산자</h1>
<h2 id="범위-연산자">범위 연산자</h2>
<pre><code class="language-swift">var arr1: Array&lt;Int&gt; = [0,1,2,3,4,5];

//Index범위를 지정해 subArr를 만들 수 있다.
print(arr1[0...3]); //[0, 1, 2, 3
//인덱스0부터 6미만가지
print(arr1[0..&lt;6]); //[0, 1, 2, 3, 4, 5]
//인덱스0을 시작으로 끝가지
print(arr1[0...]); //[0, 1, 2, 3, 4, 5]
//제일앞부터 3까지
print(arr1[...3]); //[0, 1, 2, 3]
//제일앞부터 3미만까지
print(arr1[..&lt;3]); //[0, 1, 2]</code></pre>
<hr>
<h2 id="연산자-우선순위와-결합방향">연산자 우선순위와 결합방향</h2>
<p>swift의 연산자들은 <strong>우선순위</strong>와 <strong>결합방향</strong>을 기준으로 연산을 진행한다.</p>
<h3 id="우선순위">우선순위</h3>
<p>swift 연산자의 우선순위는 <strong>상대적 순위</strong>로 결정된다. 연산자 재정의 부분에서 다루겠다.</p>
<h3 id="결합방향">결합방향</h3>
<ul>
<li><p>왼쪽 : ( ( (1 + 2) + 3) + 4)</p>
</li>
<li><p>오른쪽 : (1 + ( 2 + (3 + 4) ) ) </p>
</li>
</ul>
<hr>
<h2 id="연산자-사용자-정의">연산자 사용자 정의</h2>
<h3 id="주의사항">주의사항</h3>
<ul>
<li>정의가 불가능한 연산자 <pre><code>토큰 (=  -&gt;  //  /*  */  .), 
전위연산자 (&lt;  &amp;  ?)
중위연산자 (?)
후위연산자(&gt;  !  ?)</code></pre><code>💡 &#39; . &#39; 를 포함한 연산자를 정의할 경우 &#39; . &#39; 는 반드시 가장처음에 위치해야합니다.</code></li>
<li>사용자 정의 연산자는 아래 아스키문자의 결합으로 사용
<code>| = - + ! * % &lt; &gt; &amp; \ ^ ? ~</code></li>
</ul>
<hr>
<h3 id="전위-연산자-정의">전위 연산자 정의</h3>
<h4 id="존재하지-않던-연산자-정의">존재하지 않던 연산자 정의</h4>
<pre><code class="language-swift">//기존에 없음으로 선언해준다
prefix operator ++;
//함수 형식으로 연산자에 기능을 부여한다. 전위연산자의 대상은 매개변수로 전달된다.
prefix func ++ (value: String) -&gt; String {
    return value + &quot; &quot; + value;
}

var testString: String = &quot;I&#39;m iOS&quot;;

print(++testString); //I&#39;m iOS I&#39;m iOS</code></pre>
<p><code>💡 swift에서는 ++, --연산자는 사용되지 않는다.</code></p>
<h4 id="기존에-존재하던-연산자에-역할-추가">기존에 존재하던 연산자에 역할 추가</h4>
<pre><code class="language-swift">//기존에 존재하는 연산자는 선언문을 작성하지 않는다.
prefix func ! (value: String) -&gt; Bool {
    return value.isEmpty;
}

var original: Bool = false;

print(!original); //true

var newFunction1: String = &quot;Hello&quot;;
var newFunction2: String = &quot;&quot;;

print(!newFunction1); //false
print(!newFunction2) //true</code></pre>
<p>🙄만약 기존의 기능과 추가된 기능을 중복하면 어떻게 될까?</p>
<pre><code class="language-swift">prefix func ! (value: Bool) -&gt; String {
    return &quot;newFunction&quot;;
}

var test1: Bool = false;

print(!test1) //error: ambiguous use of operator &#39;!&#39;</code></pre>
<p>위와같이 기존의 기능과 구분이 안되 에러가 발생한다. </p>
<hr>
<h3 id="후위-연산자-정의">후위 연산자 정의</h3>
<pre><code class="language-swift">postfix operator &amp;*;

postfix func &amp;* (value: Int) -&gt; Int {
    return value * 100;
}

var test: Int = 5;

print( test&amp;* ) //500</code></pre>
<hr>
<h3 id="중위-연산자-정의">중위 연산자 정의</h3>
<p>중위 연산자는 위의 두개의 연산자와 달리 우선순위를 명시할 수 있다.</p>
<ul>
<li>우선순위그룹정의<pre><code>precedence 새로운우선수위그룹이름 {
  higherThan: 더낮은우선수위그룹
  lowerThan: 더높은우선수위그룹
  associativity: 결합방향(left/right/none)
  assignment: 할당방향 사용(옵셔널 체이닝에서 다룸)
}</code></pre></li>
<li>사용예시
<code>💡 중의 연산자는 구현 함수에 func를 쓰지 않는다.</code>
<code>💡 결합방향이 none이면 연속으로 사용할 수 없다</code><pre><code class="language-swift">precedencegroup myPrecedence {
  associativity: left
}
</code></pre>
</li>
</ul>
<p>//우선순위를 부여하지 않으면 DefaultPrecedece가 자동부여된다
infix operator &amp;&amp;&amp; : myPrecedence; </p>
<p>//중위연산자 구현 함수에는 func를 쓰지 않는다.
func &amp;&amp;&amp; (first: String, second: String) -&gt; String {
    first + &quot; | &quot; + second
} </p>
<p>let result = &quot;1&quot;&amp;&amp;&amp;&quot;2&quot;&amp;&amp;&amp;&quot;3&quot;&amp;&amp;&amp;&quot;4&quot;&amp;&amp;&amp;&quot;5&quot;&amp;&amp;&amp;&quot;6&quot;;</p>
<p>print(result);//1 | 2 | 3 | 4 | 5 | 6 </p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Swift Collection Type]]></title>
            <link>https://velog.io/@choijun0_2/Swift-Collection-Type</link>
            <guid>https://velog.io/@choijun0_2/Swift-Collection-Type</guid>
            <pubDate>Mon, 06 Jun 2022 09:59:55 GMT</pubDate>
            <description><![CDATA[<h2 id="컬렉션-공통매서드">컬렉션 공통매서드</h2>
<pre><code class="language-swift">.isEmpty //컬레션이 비었는지 확인
.count //컬렌션에 들어있는 요소 개수</code></pre>
<hr>
<h2 id="span-stylecolorf1c40farrayspan"><span style="color:#f1c40f">Array</span></h2>
<h3 id="span-stylecolor-f1c40fcreatespan"><span style="color: #f1c40f"><strong>Create</strong></span></h3>
<pre><code class="language-swift">var arr1: Array&lt;String&gt; = [&quot;jun&quot;, &quot;yoeng&quot;, &quot;choi&quot;];
print(arr1); //[&quot;jun&quot;, &quot;yoeng&quot;, &quot;choi&quot;]

var arr2: [String] = [&quot;jun&quot;, &quot;yoeng&quot;, &quot;choi&quot;];
print(arr2); //[&quot;jun&quot;, &quot;yoeng&quot;, &quot;choi&quot;]

var arr3: [Any] = [];
print(arr3.isEmpty, arr3.count, arr3); //true 0 []
</code></pre>
<h4 id="배열의-크기-지정선언">배열의 크기 지정선언</h4>
<ul>
<li><code>Array.init(reapeating:count:) 이니셜라이저를 사용하여 선언이 가능하다.</code><pre><code class="language-swift">var arr = Array.init(repeating: &quot;초기화값&quot;, count: 5)
print(arr) </code></pre>
</li>
</ul>
<pre><code>[&quot;초기화값&quot;, &quot;초기화값&quot;, &quot;초기화값&quot;, &quot;초기화값&quot;, &quot;초기화값&quot;]</code></pre><h3 id="span-stylecolor-f1c40freadspan"><span style="color: #f1c40f"><strong>Read</strong></span></h3>
<pre><code class="language-swift">var names: [String] = [&quot;junyeong&quot;, &quot;changhoon&quot;, &quot;minjae&quot;];
print(names[0], names[1], names[2]); //junyeong changhoon minjae
print(names.first, names.last); //Optional(&quot;junyeong&quot;) Optional(&quot;minjae&quot;)
</code></pre>
<p>💡이름으로 인스턴스 인덱스 찾기</p>
<pre><code class="language-swift">//앞에서부터 찾아서 가장 먼저발견한 인덱스
print(names.firstIndex(of: &quot;junyeong&quot;)) //Optional(0) 
names.append(&quot;junyeong&quot;);
//뒤에서부터 찾아서 가장 먼저발견한 인덱스
print(names.lastIndex(of: &quot;junyeong&quot;)) //Optional(3)
</code></pre>
<h3 id="span-stylecolor-f1c40fupdatespan"><span style="color: #f1c40f"><strong>Update</strong></span></h3>
<pre><code class="language-swift">var countries: [String] = [];
countries.append(&quot;Kor&quot;);

print(countries); //[&quot;Kor&quot;]

//추가하고싶은 인스턴스가 많을경우 &#39;contentsOf&#39;인수에 배열로 전달하면 된다,

countries.append(contentsOf: [&quot;America&quot;, &quot;Japan&quot;, &quot;China&quot;]);

print(countries); //[&quot;Kor&quot;, &quot;America&quot;, &quot;Japan&quot;, &quot;China&quot;]

var numbers: [Int] = [1,4,5];
//at인수에는 인덱스를 전달한다, 기존에 요소는 뒤로밀린다.
numbers.insert(contentsOf: [2,3], at: 1); 
print(numbers); //[1, 2, 3, 4, 5]</code></pre>
<h3 id="span-stylecolor-f1c40fdeletespan"><span style="color: #f1c40f"><strong>Delete</strong></span></h3>
<pre><code class="language-swift">numbers.remove(at: 4) //at에 인덱스를 전달하면 해당 인덱스 요소를 삭제하고 반환한다
print(numbers) //[1, 2, 3, 4]
numbers.removeFirst(); //마찬가지로 삭제되는 요소를 반환
numbers.removeLast();
print(numbers); //[2, 3]</code></pre>
<ul>
<li>범위연산자 사용예시<pre><code class="language-swift">print(numbers[0...2]) //[1, 2, 3]
numbers[0...4] = [5,4,3,2,1];
print(numbers); //[5, 4, 3, 2, 1]
</code></pre>
</li>
</ul>
<pre><code>
### &lt;span style=&quot;color: #f1c40f&quot;&gt;**Iterable**&lt;/span&gt;

#### 배열의 요소 순회

- `범위연산자를 활용해 index로 배열요소에 접근할 수 있다.`
```swift
for i in 0..&lt;array.count {
    print(arr[i])
}</code></pre><ul>
<li><code>배열을 집적넣어줘 요소를 순회할 수 있다.</code><pre><code class="language-swift">for element in arr {
  print(&quot;element: \(element)&quot;)
}</code></pre>
</li>
<li><code>indices나 enumerated 매서드를 활용하여 index에 접근이 가능하다.</code><pre><code class="language-swift">for index in arr.indices {
  print(&quot;index: \(index)&quot;)
}
</code></pre>
</li>
</ul>
<p>for (index, element) in arr.enumerated() {
    print(&quot;index: (index), element: (element)&quot;)
}</p>
<pre><code>- `foreach문은 클로저를 매개변수로 전달받아 클로저에게 요소를 전달한다.`
```swift
arr.forEach({
    print($0)
})</code></pre><hr>
<h2 id="span-stylecolor2ecc71dictionaryspan"><span style="color:#2ecc71">Dictionary</span></h2>
<ul>
<li><strong>Key : Value</strong> 형태의 집합이다.</li>
</ul>
<h3 id="span-stylecolor-2ecc71createspan"><span style="color: #2ecc71"><strong>Create</strong></span></h3>
<pre><code class="language-swift">//키의 이름은 중복불가 == 유일한 식별자
//데이터타입에 &#39;,&#39;가 중간에 들어가는 것 주의!! 
var dic1: Dictionary&lt;String, Int&gt; = [&quot;jun&quot; : 1, &quot;chang&quot; : 2];
print(dic1); //[&quot;chang&quot;: 2, &quot;jun&quot;: 1]
//축약
var dic2 :[String:Int] = [&quot;dong&quot; : 3];
print(dic2) //[&quot;dong&quot;: 3]

//[String:Int]는 딕셔너리 축약 타입임으로 별칭화 가능하다.
typealias stringIntDic = [String: Int];
var dic3: stringIntDic = stringIntDic();
print(dic3)//[:]
</code></pre>
<ul>
<li>Any타입을 활용한 딕셔너리
<code>key, value 타입을 자유롭게 사용가능하다.</code><pre><code class="language-swift">var dic: [String: Any] = [&quot;name&quot; : &quot;choi&quot;, &quot;age&quot; : 23]
</code></pre>
</li>
</ul>
<p>guard let name=dic[&quot;name&quot;] as? String else {
    fatalError()
}</p>
<p>guard let age=dic[&quot;age&quot;] as? Int else {
    fatalError()
}</p>
<p>print(&quot;이름: (name), 나이: (age)&quot;)</p>
<pre><code>
### &lt;span style=&quot;color: #2ecc71&quot;&gt;**Read**&lt;/span&gt;
```swift
var dic4: stringIntDic = [&quot;jun&quot;:98];

print(dic4[&quot;jun&quot;]); //Optional(98)

//만약 키의 존재여부를 모를때 &#39;default: 값&#39;을 함께적으면 키를 찾지못했을 때 값이 반환된다.
print(dic4[&quot;dong&quot;, default: 404]); //404</code></pre><h3 id="span-stylecolor-2ecc71updatespan"><span style="color: #2ecc71"><strong>Update</strong></span></h3>
<pre><code class="language-swift">typealias stringIntDic = [String : Int] 

//생성
var dic5: stringIntDic = stringIntDic();
dic5[&quot;jun&quot;] = 98;
dic5[&quot;chang&quot;] = 84;
print(dic5); //[&quot;jun&quot;: 98, &quot;chang&quot;: 84]
//업데이트
dic5[&quot;jun&quot;] = 123;
print(dic5); //[&quot;jun&quot;: 123, &quot;chang&quot;: 84]</code></pre>
<h3 id="span-stylecolor-2ecc71deletespan"><span style="color: #2ecc71"><strong>Delete</strong></span></h3>
<pre><code class="language-swift">var dic6: [String:Int] = [&quot;a&quot; : 26, &quot;b&quot; : 27];
dic6.removeValue(forKey: &quot;a&quot;);
print(dic6); //[&quot;b&quot;: 27]</code></pre>
<h3 id="span-stylecolor-2ecc71extraspan"><span style="color: #2ecc71"><strong>Extra</strong></span></h3>
<p>딕셔너리의 키가 되려면 Hashable 프로콜을 채택해하는 타입이어야 한다.
스위프트의 기본 타입들(String, Int ..)들은 모두 이 프로토콜을 채택한다. 
하지만 구조체나 클래스, 열거형을 키로 사용할 수 없을까?
<img src="https://velog.velcdn.com/images/choijun0_2/post/f71f5a2a-9d36-4bd3-8a83-422f7d8011ff/image.png" alt="">
위 에러를 보면 구조체가 Hashable 프로토콜을 conform(순응하다, 따르다)하지 않는다고 말한다.</p>
<pre><code class="language-swift">struct StructKey: Hashable {
    var prop1:String
    var prop2:Int
}

var dic1:[StructKey:Int]=Dictionary()

let key=StructKey(prop1: &quot;choi&quot;, prop2: 23)

dic1[key]=100

print(dic1[key]!) //100
</code></pre>
<p>하지만 Hashable 프로토콜을 채택하면 위와같이 key로 사용이 가능하다.
하지만 여기서도 조건이 있다.
구조체의 프로퍼티 역시 모두 Hashable프로토콜을 채택해야 한다는 점이다.</p>
<p>하지만 클래스의 경우 Hashable 프로토콜을 채택하는 것만으로는 key값으로 사용할 수 없다.</p>
<pre><code class="language-swift">class ClassKey: Hashable {
    var prop1:String
    var prop2:Int
    init(prop1:String, prop2:Int){
        self.prop1=prop1
        self.prop2=prop2
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(prop1)
        hasher.combine(prop2)
    }

    static func == (lhs:ClassKey, rhs:ClassKey)-&gt;Bool{
        return lhs.prop1==rhs.prop1 &amp;&amp; lhs.prop2==rhs.prop2
    }

}

var dic1:[ClassKey:Int]=Dictionary()

let key=ClassKey(prop1: &quot;choi&quot;, prop2: 23)

dic1[key]=100

print(dic1[key]!) //100
</code></pre>
<p>위 코드처럼 hash함수와 ==연산자를 직접 구현해 주어야 한다.
hasher.combine의 전달인자는 모둔 Hashable 프로토콜을 채택해야한다.</p>
<hr>
<h2 id="span-stylecolor9b59b6setspan"><span style="color:#9b59b6">Set</span></h2>
<ol>
<li><strong>순서가 중요하지 않은</strong> 유일한값들의 집합이다.</li>
</ol>
<h3 id="span-stylecolor-9b59b6createspan"><span style="color: #9b59b6"><strong>Create</strong></span></h3>
<pre><code class="language-swift">//다른 컬렉션타입들과 다르게 Set는 축약표현이 없다.
var student: Set&lt;String&gt; = [&quot;choi&quot;, &quot;lee&quot;, &quot;kim&quot;];
print(student); //[&quot;lee&quot;, &quot;kim&quot;, &quot;choi&quot;]

var elite: Set&lt;String&gt; = [&quot;choi&quot;, &quot;lee&quot;, &quot;han&quot;];

//교집합(A ∩ B)
var intersection: Set&lt;String&gt; = student.intersection(elite);
print(intersection); //[&quot;lee&quot;, &quot;choi&quot;]

//여집합의 합(A ∪ B - A ∩ B))
var symmetricDiffSet: Set&lt;String&gt; = student.symmetricDifference(elite);
print(symmetricDiffSet); //[&quot;han&quot;, &quot;kim&quot;]

//합집합(A ∪ B)
var union: Set&lt;String&gt; = student.union(elite);

//차집합(A - B)
var subtracting: Set&lt;String&gt; = student.subtracting(elite);

print(&quot;교집합: \(union), 차집합: \(subtracting)&quot;) 
//교집합: [&quot;lee&quot;, &quot;kim&quot;, &quot;han&quot;, &quot;choi&quot;], 차집합: [&quot;kim&quot;]</code></pre>
<h3 id="span-stylecolor-9b59b6readspan"><span style="color: #9b59b6"><strong>Read</strong></span></h3>
<pre><code class="language-swift">//Set은 순서가 의미가없어 인덱스로 값을 읽지 못한다
let foodSet: Set&lt;String&gt; = [&quot;chicken&quot;, &quot;bugger&quot;, &quot;americano&quot;];
print(foodSet, &quot;type: \(type(of: foodSet))&quot;) 
//[&quot;americano&quot;, &quot;chicken&quot;, &quot;bugger&quot;] type: Set&lt;String&gt;

//sorted매서드를 이용하면 Set을 정렬된 배열로 바꿔 반환한다.(Set은 변하지 않는다) 
let foodArray: [String] = foodSet.sorted();
print(foodArray, &quot;type: \(type(of: foodArray))&quot;) 
//[&quot;americano&quot;, &quot;bugger&quot;, &quot;chicken&quot;] type: Array&lt;String&gt;</code></pre>
<h3 id="span-stylecolor-9b59b6updatespan"><span style="color: #9b59b6"><strong>Update</strong></span></h3>
<pre><code class="language-swift">var foodSet: Set&lt;String&gt; = [&quot;chicken&quot;, &quot;bugger&quot;, &quot;americano&quot;];
foodSet.insert(&quot;cake&quot;);

print(foodSet); //[&quot;bugger&quot;, &quot;americano&quot;, &quot;cake&quot;, &quot;chicken&quot;]
</code></pre>
<h3 id="span-stylecolor-9b59b6deletespan"><span style="color: #9b59b6"><strong>Delete</strong></span></h3>
<pre><code class="language-swift">var foodSet: Set&lt;String&gt; = [&quot;chicken&quot;, &quot;bugger&quot;, &quot;americano&quot;];
foodSet.remove(&quot;bugger&quot;); //contentsOf 인수가 사용되지 않는다.

print(foodSet); //[&quot;americano&quot;, &quot;chicken&quot;]</code></pre>
<hr>
<h2 id="span-stylecolore74c3cenumspan"><span style="color:#e74c3c">Enum</span></h2>
<ol>
<li>열거형은 연관된 항목들을 묶어서 표현할 수 있는 타입이다. </li>
<li>처음지정된 항목값을 <strong>추가/수정이 불가</strong>능하다.</li>
<li>열거형 항목의 이름이 곧 <strong>고유의 값</strong>이다. (내부적으로 치환되지 않음)</li>
<li>항목자체도 고유값이지만 <strong>항목의 원시 값(Raw Value)도 가질 수 있다</strong>.<h3 id="span-stylecolor-e74c3ccreatereadspan"><span style="color: #e74c3c"><strong>Create/Read</strong></span></h3>
<pre><code class="language-swift">//일반형 
enum menu {
 case pasta
 case pizza
 case juice
}
</code></pre>
</li>
</ol>
<p>//축약
enum menu2 { case pasta, pizza, juice}</p>
<p>//각 항목은 지정값을 가질 수 있다.
//항목에 원시값을 주지않는 경우 String은 항목이름이 부여된다.
//Int는 0부터 오름차순으로 부여된다.
enum menu3: String {
    case pasta = &quot;로제&quot;
    case pizza = &quot;마르게리타&quot;
    case juice
}
print(menu3.juice.rawValue, type(of: menu3.juice.rawValue)); //juice String</p>
<p>var food: menu3 = .pasta; //열거형 이름 생략가능
print(food, food.rawValue); //pasta 로제</p>
<p>//원시값의 타입을 항목마다 다르게 부여할 수 있다.
enum menu4 {
    case pasta(flavor: String)
    case pizza(dough: String, size: Int)
    case juice(String) //타입만 적어도됨
}</p>
<p>var food2: menu4 = .pasta(flavor: &quot;rose&quot;); 
print(food2) //pasta(flavor: &quot;rose&quot;)</p>
<p>var food3: menu4 = .juice(&quot;grape&quot;);
print(food3) //juice(&quot;grape&quot;)</p>
<p>```</p>
<ul>
<li>열거형에대해서는 추후에 더깊은 내용을 포스팅하겠다.</li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Swift common grammer]]></title>
            <link>https://velog.io/@choijun0_2/Swift-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@choijun0_2/Swift-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Mon, 06 Jun 2022 08:11:41 GMT</pubDate>
            <description><![CDATA[<h1 id="변수와-상수">변수와 상수</h1>
<ol>
<li>생성 키워드</li>
</ol>
<p><strong>var/let [변수명]: [데이터타입] = [값]</strong>
💡var: 변수 let: 상수</p>
<pre><code class="language-swift">let name: String = &quot;Junyeong Choi&quot;; //상수
var number: Int = 23; //변수</code></pre>
<p>💡변수, 상수, 함수, 메서드, 타입 등의 이름은 <strong>유니코드 지원 문자</strong>면 상관없이 사용가능
<code>예외사항: 예약어, 키워드, 연산자, 숫자시작문자열, 공백포함문자열</code></p>
<hr>
<h1 id="주석">주석</h1>
<ul>
<li>일반주석<pre><code class="language-swift">//한줄주석 예시입니다.
</code></pre>
</li>
</ul>
<p>/*
여러줄 주석 예시입니다.
여러줄 주석 예시입니다.
*/</p>
<pre><code>- 마크업문법 활용 문서화 주석
**Xcode퀵헬프**를 통해 볼수 있는 Description입니다.
함수바로위에 공간에 작성함으로써 사용가능합니다.
```swift
///한줄예시입니다. 마크업으로 작성가능합니다. (함수1의 Discription에 표시)
함수1

/**
여러줄 예시입니다.
마크업으로 작성가능합니다. (함수2의 Discription에 표시)
**/
함수2</code></pre><hr>
<h1 id="타입별칭">타입별칭</h1>
<p><strong>기존에 존재하는 타입</strong>의 별칭을 지정할 수 있다.</p>
<pre><code class="language-swift">typealias 별칭 = String; 

let name: 별칭 = &quot;junyeong&quot;;
let school: String = &quot;Hongik Univ&quot;;

print(name, school); //junyeong Hongik Univ</code></pre>
<hr>
<h1 id="튜플">튜플</h1>
<p>튜플타입은 기존타입들을 간편하게 묶어낼 수 있다</p>
<pre><code class="language-swift">let name: String = &quot;junyeong&quot;;
let school: String = &quot;Hongik Univ&quot;;

let 나만의튜플: (name: String, univ: String) = (name, school);

print(나만의튜플); //(name: &quot;junyeong&quot;, univ: &quot;Hongik Univ&quot;)

typealias myTuple = (name: String, univ: String); //튜플도 타입이다
var 나만의튜플2: myTuple = (name, school);

print(나만의튜플2); //(name: &quot;junyeong&quot;, univ: &quot;Hongik Univ&quot;)

//Update
나만의튜플2.name = &quot;Dongsu&quot;;
나만의튜플2.univ = &quot;Seoul Univ&quot;;

print(나만의튜플2); //(name: &quot;Dongsu&quot;, univ: &quot;Seoul Univ&quot;)
</code></pre>
<hr>
<h1 id="switch">Switch</h1>
<ul>
<li>break 키워드 사용은 선택적이다.</li>
<li>타입에 구에받지 않고 사용가능하다.</li>
<li>모든경우가 존재하지 않는다면 반드시 default 키워드를 사용해야한다.<h2 id="기본형">기본형</h2>
<pre><code class="language-swift">func myAgeReaction(_ age: Int) {
  switch age {
      case 23:
      print(&quot;yes, my age!&quot;)
      case 10...15, 25...32: //*한번에 여러번 비교가 가능하다.
      print(&quot;Are you serious?&quot;)
      fallthrough  //아래의 case조건과 관계없이 아래 case구문을 실행한다.
      case 18...22:
      print(&quot;thank you&quot;)
      default: //일치하는 case가 없을수 있음으로 default를 작성해준다.
      print(&quot;answer again plz..&quot;) 
  }
}
myAgeReaction(19) //thank you
myAgeReaction(12) //Are you serious? thank you *fallthrough사용예시
myAgeReaction(26) //Are you serious? thank you
myAgeReaction(56) //answer again plz..</code></pre>
<code>💡위의 case 10...15, 25...32를 아래처럼 작성할 수 없다.</code><pre><code class="language-swift">case 10...15:
case 25...32:
execute code
</code></pre>
</li>
</ul>
<p>case아래에는 반드시 실행구문이 와야하기 때문이다.</p>
<ul>
<li>break도 실행구문이다.<pre><code>
</code></pre></li>
</ul>
<h2 id="튜플-타입과-바인딩">튜플 타입과 바인딩</h2>
<pre><code class="language-swift">typealias myTuple = (name: String, age: Int)

func findMyInform(_ data: myTuple) {
    switch(data){
        case (&quot;choi&quot;, 23):
        print(&quot;정답이야!&quot;)
        case (&quot;choi&quot;, _):  //_(와읻드카드) 를 사용할 경우 사용부분을 고려하지 않는다.
        print(&quot;이름은 아는구나?&quot;)
        case (_, 20...25):  //범위연산자 사용가능
        print(&quot;나이는 비슷하게 맞췄네..&quot;)
        case (let name, let age):  //주어지는 겂을 바인딩해 사용이 가능하다.
        print(&quot;내이름이 \(name)이고 나이가 \(age)세라고?? 장난치냐?&quot;)
    }
}

findMyInform((&quot;park&quot;, 23)) //나이는 비슷하게 맞췄네..
findMyInform((&quot;choi&quot;, 16)) //이름은 아는구나?
findMyInform((&quot;park&quot;, 26)) //내이름이 park이고 나이가 26세라고?? 장난치냐?
findMyInform((&quot;choi&quot;, 23)) //나이는 비슷하게 맞췄네.</code></pre>
<pre><code>💡switch문은 상위 case부터 순차적으로 조건을 검사한다. 
따라서 _사용하면 특정값에 대한 case를 실행하고 싶어도 _문이 실행될 수 있다.
그러므로 _을 사용하는 case는 하위에 작성하는 것을 권장한다.

💡값을 바인딩하는 조건문은 _를 사용한 문과 조건이 일치한다.
위의 case (let name, let age): 는 사실상 case (_, _): 과 같다.</code></pre><hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Functional programming paradigm]]></title>
            <link>https://velog.io/@choijun0_2/Functional-programming-paradigm</link>
            <guid>https://velog.io/@choijun0_2/Functional-programming-paradigm</guid>
            <pubDate>Sat, 04 Jun 2022 07:53:56 GMT</pubDate>
            <description><![CDATA[<h3 id="간략한-소개">간략한 소개</h3>
<pre><code>함수형 프로그래밍 패러다임은 프로그램이 상태의 변화없이 
데이터 처리를 수학의 함수 계산처럼하는 패러다임이다. </code></pre><p>💡여기서 수학적 함수란 <strong>X값의 조작에 의해서만</strong> Y값이 도출되는 f(X) = Y를 의미한다. </p>
<hr>
<h3 id="명령형-프로그래밍과의-차이점">명령형 프로그래밍과의 차이점</h3>
<p><code>함수형 프로그래밍 방식은 값, 상태변화를 배제하고 함수자체의 응용을 중시한다</code></p>
<ul>
<li>명령형 프로그래밍은 메모리 참조값이 함수에 사용되어 같은 인자를 전달하여도 결과값이 인자 이외의 값에 간섭을 받을 수 있다.➡<strong>함수의 독립성을 고려하지 않는다.</strong>👩‍👩‍👦
반면에 함수형 프로그래밍 방식은 <strong>순수하게 함수에 전달된 인자</strong>만이 결가값에 영향을 주도록 설계하는 방식이다. ➡<strong>함수가 독립적으로 실행된다.</strong>😀↔👩‍🦰</li>
</ul>
<hr>
<pre><code class="language-javascript">//명령형 프로그래밍
let var1 = 4;
const plusVar1 = () =&gt; {
  var1+=1;
}
const func1 = (arg1) =&gt; {
  return var1 + arg1; //결과값이 외부영향을 받음
}

//함수형 프로그래밍
const func2 = (arg1) =&gt; {
  const var1 = 4;
  return var1 + arg1; //결과값이 외부영향을 받지않음
}
</code></pre>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[iOS developer roadmap]]></title>
            <link>https://velog.io/@choijun0_2/%EB%82%98%EC%9D%98-iOS%EA%B0%9C%EB%B0%9C-%EB%A1%9C%EB%93%9C%EB%A7%B5</link>
            <guid>https://velog.io/@choijun0_2/%EB%82%98%EC%9D%98-iOS%EA%B0%9C%EB%B0%9C-%EB%A1%9C%EB%93%9C%EB%A7%B5</guid>
            <pubDate>Mon, 30 May 2022 09:57:21 GMT</pubDate>
            <description><![CDATA[<h3 id="1-인사말">1. 인사말</h3>
<p>안녕하세요 iOS개발자가 되고싶은 대학생입니다.😀
<strong><em>iOS developer Jung Kim님의 로드맵</em></strong>을 따라 공부를 해나갈 생각입니다.
<a href="https://github.com/godrm">🚀Jung Kim님의 깃허브방문</a></p>
<h3 id="2-로드맵">2. 로드맵</h3>
<p><code>해당 로드맵의 출처는 Jung Kim님의 mobile-developer-roadmap 레포지토리 입니다.</code>
<a href="https://github.com/godrm/mobile-developer-roadmap">🚀mobile-developer-roadmap</a></p>
<ul>
<li><strong>iOS roadmap</strong>
<img src="https://raw.githubusercontent.com/godrm/mobile-developer-roadmap/master/Images/iOS_roadmap_v1.0.png" alt="ios roadmap"></li>
<li><strong>Swift roadmap</strong>
<img src="https://raw.githubusercontent.com/godrm/mobile-developer-roadmap/master/Images/Swift_programming_roadmap_v0.9.png" alt="Swift roadmap"></li>
</ul>
<p><strong>해당 로드맵 포함된 키워드들을 따라 게시물을 작성해 나가겠습니다🧐</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[주간 생활사용영어번역(week22)]]></title>
            <link>https://velog.io/@choijun0_2/%EC%A3%BC%EA%B0%84-%EC%83%9D%ED%99%9C%EC%82%AC%EC%9A%A9-%EC%98%81%EC%96%B4%EB%B2%88%EC%97%ADweek22</link>
            <guid>https://velog.io/@choijun0_2/%EC%A3%BC%EA%B0%84-%EC%83%9D%ED%99%9C%EC%82%AC%EC%9A%A9-%EC%98%81%EC%96%B4%EB%B2%88%EC%97%ADweek22</guid>
            <pubDate>Mon, 30 May 2022 09:40:13 GMT</pubDate>
            <description><![CDATA[<h3 id="1-작성이유🧐">1. 작성이유🧐</h3>
<p><code>영어회화 독학을 위하여 이 글을 꾸준히 작성하기로 마음먹었다.</code></p>
<p>하루에 5개씩(월-금) <strong>내가 일상에서 사용한 말</strong>을 번역하기로 하였다. 
작성간격은 <strong>주간</strong>으로 기록할 것이며 
 <strong>단순히 구글번역기와 파파고에 글을 입력하는 것이 아닌</strong> 위 두번역기에서 번역한 내용을 구글에 검색하여 실제로 쓰이는 표현인지 확인하는 과정을 거쳤다. </p>
<h3 id="2-list📜">2. List📜</h3>
<p> 첫주차는 시작일이 월요일 아니라서 <strong>20개</strong>의 문장을 번역하였다.</p>
<pre><code> 1. 좋은 아침입니다, 오늘의 몸상태는 어떤가요?
 🔎:Good morning, How do you feel today?</code></pre><p> <code>How are you feeling today는 듣는이의 건강상태를 묻는 표현이다.</code></p>
<pre><code> 2. 어제 무리한 운동으로인해 몸이조금 뻐근합니다.
 🔎:I&#39;m not feeling well because I exercised too much yesterday.</code></pre><pre><code> 3. 오늘 아침메뉴가 뭔지 알아?
🔎:Do you know what&#39;s on the menu this morning?</code></pre><pre><code> 4. 맛없네.. 난안먹을레
🔎:It is not good, I won&#39;t eat</code></pre><pre><code> 5. 재미있는 영상 틀어줘
🔎:Play something fun</code></pre><pre><code> 6. 오늘 주식시장은 어땠어? 하락장이야? 상승장이야?
🔎:How did the stock market do today? Is it a bear or bull market?</code></pre><pre><code> 7. ~퍼센트 하락/상승 했어
🔎:The Kospi fell/declined/dropped ~points or ~%.
🔎:The Nasdaq jump/climbed/ ~points or ~%.</code></pre><pre><code> 8. 루나코인 대폭락에 대해 어떻게 생각해?
🔎:How do you think of Luna crash?</code></pre><pre><code> 9. 치명적일수 있는 단점이 있었고 그게 터졌다고 생각해
🔎:There was a problem that could be fatal, I think it blew up.</code></pre><p> <code>&quot;문제가 터졌다&quot; 표현에는 problem arise/blows up 등이 있다.</code></p>
<pre><code> 10. 환절기 알레르기 대문에 고생중이에요.
🔎:I&#39;m suffering seasonal allegies.</code></pre><pre><code> 11. 어떤분야의 전문가가 되고싶으세요? / 어떤분야의 전문가 이신가요?
🔎:what feild do you want to become a expert in? / what is your feild of expertise? </code></pre><p> <code>expertise : a high level of knowledge or skill.</code></p>
<pre><code> 12. ios 개발자가 되고싶습니다.
🔎:I want to become an ios developer.</code></pre><pre><code> 13. ios 개발자가 되려면 어떤것을 해야할까요?
🔎:How to become an is developer?</code></pre><pre><code> 14. 주위에 사람이 많은 좋은 사람이 되고싶습니다. 
🔎:I want to be a good person with mny people around me.</code></pre><pre><code> 15. 치킨이 너무 먹고싶지만 다이어트 때문에 참겠습니다. 
🔎:I want to eat chicken so much, but I&#39;m on diet, so I will refrain from eating it. </code></pre><pre><code> 16. 곤약젤리로 포만감을 채우고 있습니다. 
🔎:I&#39;m filling my stomach with konjac jelly.</code></pre><pre><code> 17. 오늘 체력다련실에서 20분동안 2.5km를 다렸습니다. 
🔎:I ran 2.5km in 20min at the gym today.</code></pre><pre><code> 18. 언제나 안다치는 것이 가장 중요해.
🔎:Always the most important thing is not to get hurt.</code></pre><pre><code> 19. 같인 브롤스타즈(게임) 하자! 들어와!
🔎:Let&#39;s play Brawlstarts together, get in!</code></pre><pre><code> 20. 아무리 뽑기를 하여도 좋은 것이 안나와.. 난 운이 없나봐
🔎:No matter how hard i try, I fail, I&#39;m out of luck.</code></pre><ul>
<li><strong>저만의 기록장이라 아무도 안볼꺼라 생각합니다😅 하지만 이글을 보고 문제점을 발견하신다면 알려주시면 감사하겠습니다😁</strong></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>