Stanford cs193p Lecture 1 - lecture note

rloyhvv·2021년 4월 27일
0
post-thumbnail

무작정 파일 생성하기

xcode에서 simple view를 생성하면 hello world를 print가 적힌 뷰가 나온다.
샘플 코드는 아래와 같다.

struct ContentView: View {
    var body: some View {
        Text("Hello World")
    }
}


대충 ContentView는 시뮬레이터에서 하얀 배경(View)이고 안의 내용은 body라는 View이고 body 안에 Text(Hello World)가 있다고 이해하면 될 것 같다.

위 코드는 약간의 키워드가 생략된 형태인데 엄격(?)하게 쓰면 다음과 같다.

struct ContentView: View {
    var body: some View {
        return Text("Hello World")
    }
}

한 줄이 전부라면 return 키워드를 생략해서 쓸 수 있다고 한다.

Some

강의를 보면 'swift에서 모든 variable은 type을 명시해야하고 모든 variable은 value를 가진다' 라는 말이 자주 나온다.

그럼 body에서 View 앞에 있는 'some'은 뭘까?

some keyword that we use here is a switch feature that lets swift infer out inter return type automatically.

some 키워드는 return type을 자동으로 추측할 수 있게 하는 키워드라고 한다. 쉽게 말해서 타입 명시를 불분명하게 만들어주는 것 같다.

참고로 위 코드에서 some을 지우면 이런 error가 발생한다.
Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements

무슨 말인지 모르겠지만 some 없이 View만 사용하면 안 된다는 뜻이다. 만약 some을 쓰지 않고 Hello World를 출력하려면 코드를 이렇게 수정하면 된다.

struct ContentView: View {
    var body: Text {
        Text("Hello World")
    }
}

body의 type을 some View에서 Text로 변경하면 된다. 여기서 인사이트를 얻을 수 있다.
코드 한줄짜리인 body는 결국 Hello World라는 Text를 return하기 때문에 body의 type은 View가 아니라 Text가 된다. 하지만 앞서 봤듯이 some View라고 적어도 에러가 발생하지 않는다.

이 때 some View는 opaque type이다.

Opaque가 뭐냐하면 안에서는 return type을 알지만 밖에서는 모르게 숨기는 것을 말한다. some은 opaque type으로 만들어주는 키워드다.

struct ContentView: View {
    var body: some View {
        Text("Hello World")
    }
}

코드를 다시 살펴보자. 우리는 body가 return하는 것이 Text type임을 알고 있다. 왜냐하면 Text("Hello World")라고 적혀있으니까. 만약 var body: some View가 아니라 var body: Text라고 적혀있었다면 우리는 body의 내부를 보지 않아도 body가 Text type임을 알 수 있다. 하지만 some View라고 적혀있기 때문에 만약 body의 내용을 모른다면 우리는 body가 어떤 type을 return하는지 모른다. 이게 some이 해주는 역할이다.

some View가 줄 수 있는 정보는 결국 'body가 어떤 타입을 return하는지는 모르겠지만 View와 같은 역할을 하는 component이다.' 정도가 된다.

그럼 Text로 concrete하게 명시하지 않고 some View라고 쓰는 이유가 뭘까? body 안에 component를 몇 개 더 넣어보면 이유를 알 수 있다.

struct ContentView: View {
    var body: HStack<TupleView<(Text, Text, Text)>> {
        HStack {
            Text("Hello World")
            Text("This is a Sample Code")
            Text("Goodbye World")
        }
    }
}

type을 concrete하게 명시하면 body 안에 component가 뭐가 들어가는지 하나하나 명시해줘야한다. 하지만 some을 사용해서 body type을 흐리멍텅하게 표현하면 문제를 쉽게 해결할 수 있다.

Lecture 1에서는 카드 4개를 뷰에 띄우는 코드를 작성하였다.

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            ForEach(0..<4) { index in
                CardView(isFaceUp: false)
            }
        }
            .padding()
            .foregroundColor(Color.orange)
            .font(Font.largeTitle)
    }
}

struct CardView: View {
    var isFaceUp: Bool
    var body: some View {
        ZStack {
            if isFaceUp {
                RoundedRectangle(cornerRadius: 10.0).fill(Color.white)
                RoundedRectangle(cornerRadius: 10.0).stroke(lineWidth: 3.0)
                Text("👻")
            } else {
                RoundedRectangle(cornerRadius: 10.0).fill()
            }
        }
    }
}


HStack이니 RoundRectangle이니 하는 것들은 당장 다 보고 외우고 할 필요 없이 코드 실습을 하면서 이런게 있구나~정도로만 알려고 한다. (그래도 괜찮지 않을까?)

그래도 하나를 말해보자면 swiftUI에 ForEach라는 structure가 있다는 점이 눈에 띄었다.
Apple Developer 사이트에서 ForEach structure 관련 설명을 읽을 수 있다.

참고

0개의 댓글