안녕하세요. 

블록체인 전공서적을 같이 읽어서 인증하는 스터디 모임을 개설했습니다. 

전공 공부팀 카톡 오픈 채팅방 바로 가기

처음 책으로는 비트코인, 블록체인과 금융의 혁신 책입니다. 

원제로는 mastering bitcoin 1판 입니다. 현재 2판까지 나왔지만 번역은 아직 안된 상태입니다. 


http://www.yes24.com/24/Goods/22357437?Acode=101


책이 다소 두껍지만 내용은 정말 좋다고 생각합니다. 입문서로는 딱이라고 봅니다. 

대상은 블록체인 처음 입문하시는 개발자분이거나 개념적으로 좀 더 공부를 하고 싶으신 분입니다.

블록체인에 항상 관심만 있으신 분도 오셔서 같이 인증도 하시고 토론도 해보시는 자리가 되셨으면 합니다. 

  1. 인증 방법은 카톡 오픈 채팅방으로 먼저 오십니다. ( 입장하기 )
  2. 슬랙으로 들어오셔서 해당 이름으로 된 채널에 입장하셔서 매일 또는 주기적으로 인증해주시면 됩니다. 
현재 매일 전공 공부팀도 같이 활동중입니다. 혹시 관심이 있으시면 같이 참가하셔도 됩니다. 








Golang 으로 CRUD Restfual Api 만들기

최근 블록체인을 공부하면서 이더리움 코어를 보고 싶다는 생각이 자주 들었다. 그리고 하이퍼레저에서 스마트 계약 개발시 Go 로 짜고 있는 걸 보고 고랭을 배워야 겠다는 마음을 먹고 하나씩 보고 있습니다.

언어를 제일 배우고 제일 먼저 해보는 건 무엇보다 게시판 하나 짜보는 거겠죠?

그래서 Restful Api 를 먼저 구성해보고 화면단을 만들어서 해보도록 합니다.

어설픈 TDD 방식으로 하나씩 짜보도록 하겠습니다.

우선 Go 가 아직 설치가 안되신 분은 https://golang.org/dl/ 으로 가셔서 받으시길 바랍니다.

그리고 환경 설정을 해줍니다.

혹시 Gopath 와 Gopath bin 설정이 안되신 분은 여기 에서 따라해보시면 됩니다.

현재 DB는 몽고디비를 사용중이며 도커로 연동중입니다.

그럼 우선 처음 시작은 main.go 로 구성해보죠.

# main.go

package main

import "fmt"

func main() {
    fmt.Println("Hello Go")
}

>>> Hello Go
> go run main.go //실행

그리고 App 파일을 만들어서 서버 관리를 위임하도록 합니다.

main.go 에서 App 인스턴스를 생성해서 서버쪽을 실행하고 DB도 연결하도록 합니다.

# app.go

package main

type App struct {
}

func (a *App) Initialize(serverIp, dbName, collectionName string) {

}
func (app App) Run(port string) {

}

그럼 main 에서는 어떻게 호출 하면 될까요?

package main

func main() {
    app := App{}
    app.Initialize(
        "192.168.99.100",
        "godb",
        "movies",
    )

    app.Run("8000")
}
  • App 인스턴스를 만들고
  • 초기화를 하고
  • App Run 함수를 통해서 실행을 합니다.

일단 제일 기본 뼈대는 진행된 것 같네요. 그럼 TDD로 먼저 테스팅을 작성해봅니다.

참고로 저도 고랭 처음이기도 해서 아주 어설프게 진행하니 양해부탁드립니다. ^^

그럼 main_test.go 를 하나 생성해줍니다. 그리고 샘플 예제를 하나 넣어서 테스트를 해봅니다.

혹시 유닛 테스팅 방법이 궁금하시면 여기 로 가셔서 참고하시길 바랍니다.

package main_test

import (
    "fmt"
    "github.com/restapi"
    "os"
    "testing"
)

var a main.App

var ip, dbName, collectionName = "192.168.99.100", "godb", "movies"

func TestMain(m *testing.M) {
    a = main.App{}
    a.Initialize(
        ip,
        dbName,
        collectionName,
    )

    prevTesting()

    code := m.Run()

    postTesting()

    os.Exit(code)
}

func prevTesting() {
    fmt.Println("prevTesting....")
}

func postTesting() {
    fmt.Println("postTesting....")
}

func TestExam(t *testing.T) {

    fmt.Println("TestExam inside")
}
prevTesting....
=== RUN   TestExam
TestExam inside
--- PASS: TestExam (0.00s)
PASS
postTesting....

내용은 보시면 아무것도 없습니다.

단지 테스팅을 하는데 TestExam을 실행시 항상 TestMain에서 전처리 후처리를 거쳐서 진행한다는 게 중요합니다.

자바로 생각하면 before와 after로 보시면 되겠네요. 보통 DB를 열어서 더미 데이트들을 넣어주고 마지막엔 지워주는 역할을 해도 되거나 DB연결을 도와줘도 됩니다.

일단 저는 다음에 쓰도록 하고 먼저 CRUD 서비스를 개발을 해보겠습니다.

이 예제는 크게 5가지 기능을 가집니다.

  • AddMovie
  • GetMovie
  • UpdateMovie
  • DeleteMovie
  • GetMovies

그럼 테스팅 클래스에 먼저 TestAddMovie함수를 정의 해봅시다. 영화를 추가하는 기능을 테스팅합니다.

func TestAddMovie(t *testing.T) {
    //TODO 영화 더미 데이터 하나를 가져온다.
    //TODO String으로 Json을 이용해서 변환해준다.
    //TODO Body 에 넣어서 Post 로 보내본다.
    //TODO 그리고 결과가 정상적으로 StatusCreated 코드가 떨어지는 지 본다.
    //TODO 입력 값을 JSON 으로 출력해서 정상적으로 입력되었는지 하나씩 체크
}

그럼 실제 코드로 옮겨보면 다음과 같이 만들수 있겠네요.

func TestAddMovie(t *testing.T) {

    //TODO 영화 더미 데이터 하나를 가져온다.
    darkNight := getMovieDummy()

    //TODO String으로 Json을 이용해서 변환해준다.
    darkNightMarshel, err := json.Marshal(darkNight)

    if err != nil {
        panic(err)
    }

    //TODO Body 에 넣어서 Post 로 보내본다.
    req, _ := http.NewRequest("POST", "/movie", bytes.NewBufferString(string(darkNightMarshel)))
    response := executeRequest(req)

    //TODO 그리고 결과가 정상적으로 StatusCreated 코드가 떨어지는 지 본다.
    checkResponseCode(t, http.StatusCreated, response.Code)

    //TODO 입력 값을 JSON 으로 출력해서 정상적으로 입력되었는지 하나씩 체크
    var m main.Movie
    json.Unmarshal(response.Body.Bytes(), &m)

    if darkNight.Name != m.Name {
        t.Errorf("Its not name equal %v", m.Name)
    }

    if darkNight.Year != m.Year {
        t.Errorf("Its not Year equal %v", m.Year)
    }

    if !cmp.Equal(darkNight.Directors, m.Directors) {
        t.Errorf("Its not Directors equal %v", m.Directors)
    }

    if !cmp.Equal(darkNight.Writers, m.Writers) {
        t.Errorf("Its not Writers equal %v", m.Writers)
    }

    if !cmp.Equal(darkNight.BoxOffice, m.BoxOffice) {
        t.Errorf("Its not BoxOffice equal %v", m.BoxOffice)
    }
}

그리고 더미 데이터는 임의로 만들어서 리턴을 해줍니다.

func getMovieDummy() *main.Movie {
    return &main.Movie{
        Name:      "The Dark Knight",
        Year:      "2008",
        Directors: []string{"Christopher Nolan"},
        Writers:   []string{"Jonathan Nolan", "Christopher Nolan"},
        BoxOffice: main.BoxOffice{
            Budget: 185000000,
            Gross:  533316061,
        },
    }
}

이 데이터 방식은 몽고 디비 컬렉션에 들어갈 내용입니다.

그러면 DB 연동 하고 실제 AddMovie함수를 만들어봐야 겠군요.

app.go 에 DB 연동 부분을 추가를 해줍니다.

type App struct {
    Router     *mux.Router
    session    *mgo.Session
    collection *mgo.Collection
}

func (a *App) Initialize(serverIp, dbName, collectionName string) {
    session, err := mgo.Dial(serverIp)
    a.session = session
    a.collection = a.session.DB(dbName).C(collectionName)

    if err != nil {
        panic(err)
    }
    //defer session.Close()

    a.Router = mux.NewRouter()
    a.initializeRoutes()
}

하단에 라우팅을 추가하는 함수가 있네요.

func (a *App) initializeRoutes() {
    //영화 추가
    a.Router.HandleFunc("/movie", a.addMovie).Methods("POST")
}

그리고 지금 당장은 안쓰지만 후에 서버를 실행할려면 다음과 같이 하단에 넣어주셔야 합니다.

func (a *App) Run(port string) {
    log.Fatal(http.ListenAndServe(":"+port, a.Router))
}

현재 mux 와 몽고 디비 라이버리를 가져와서 사용을 하고 있습니다. 명령어를 통해서 소스를 받아와서 연동을 해주도록 합니다.

go get github.com/gorilla/mux
go get gopkg.in/mgo.v2

그럼 영화 추가 로직을 넣기 위해선 model.go 을 만들어서 실제 DB핸들링 하는 건 다시 빼서 위임을 시켜보도록 하죠.

# model.go

type Movie struct {
    ID        bson.ObjectId `json:"id" bson:"_id,omitempty"`
    Name      string        `json:"name" bson:"name"`
    Year      string        `json:"year" bson:"year"`
    Directors []string      `json:"directors" bson:"directors"`
    Writers   []string      `json:"writers" bson:"writers"`
    BoxOffice BoxOffice     `json:"boxOffice" bson:"boxOffice"`
}

type BoxOffice struct {
    Budget uint64 `json:"budget" bson:"budget"`
    Gross  uint64 `json:"gross" bson:"gross"`
}

우선 Movie와 BoxOffice를 정의를 합니다.

# model.go

//영화 정보를 입력함
func (m *Movie) AddMovie(db *App) (string, error) {

    m.ID = bson.NewObjectId()
    var name = db.collection.Name
    fmt.Println(name)
    err := db.collection.Insert(m)
    if err != nil {
        return "", err
    }

    return m.ID.Hex(), nil
}

아이디를 생성해서 DB에 입력하는 로직입니다.

그리고 추후 입력된 내용에 대해 ID 를 리턴해서 다시 핸들링 (업데이트 및 삭제) 하게끔 할수 있습니다.

그럼 이 모델 로직을 가져와서 사용하는 곳을 만들어봐야겠네요.

실제 라우팅되서 처리되고 모델에 있는 로직함수가 실행된다고 보면 됩니다.

Test -> main - app - model

# app.go

func (a *App) addMovie(w http.ResponseWriter, r *http.Request) {
    var movie Movie
    postBody, err := ioutil.ReadAll(r.Body)
    if err != nil {
        respondWithError(w, http.StatusBadRequest, "parsing error")
        return
    }
    json.Unmarshal(postBody, &movie)

    defer r.Body.Close()

    if _, err := movie.AddMovie(a); err != nil {
        respondWithError(w, http.StatusInternalServerError, err.Error())
        return
    }

    respondWithJSON(w, http.StatusCreated, movie)
}

응답에 대한 오류와 성공 처리는 respond를 통해서 하고 있습니다.

# app.go

func respondWithError(w http.ResponseWriter, code int, message string) {
    respondWithJSON(w, code, map[string]string{"error": message})
}

func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) {
    response, _ := json.Marshal(payload)

    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(code)
    w.Write(response)
}

이제 AddMovie 쪽이 완성이 되었네요. 그럼 영화정보를 가져와야겠네요.

우선 테스팅 코드에 입력을 한다음

# main_test.go

func TestGetMovie(t *testing.T) {
    //id := bson.NewObjectId()
    id := addDommyMovie(getMovieDummy())
    req, _ := http.NewRequest("GET", "/movie/"+id, nil)
    response := executeRequest(req)
    checkResponseCode(t, http.StatusOK, response.Code)

    var m main.Movie
    json.Unmarshal(response.Body.Bytes(), &m)
}

라우팅 처리하는 곳 가서 GetMovie함수를 추가해줍니다.

func (a *App) getMovie(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)

    movie := Movie{ID: bson.ObjectIdHex(vars["id"])}
    if err := movie.GetMovie(a); err != nil {
        switch err {
        case mgo.ErrNotFound:
            respondWithError(w, http.StatusNotFound, err.Error())
        default:
            respondWithError(w, http.StatusInternalServerError, err.Error())
        }

        return
    }

    respondWithJSON(w, http.StatusOK, movie)
}

로직을 담당하는 model.go에서 GetMovie를 추가해줍니다.

//영화를 가져오는 함수
func (m *Movie) GetMovie(db *App) error {

    //var movie Movie
    err := db.collection.Find(bson.M{"_id": m.ID}).One(&m)
    if err != nil {
        return err
    }

    return nil
}

네. 사실 한줄 씩 테스팅 코드를 짜는 게 맞지만 대략적인 흐름만 알려드렸네요.

그럼 업데이트, 삭제, 전체 리스트 가져오기도 이런식으로 추가해서 진행할 수 있습니다.

그럼 다음에는 이 기능들을 이용해서 프론트단(React) 개발 및 연동을 해보겠습니다.

고랭 가즈아~~

현재 매일 15분 이상 전공공부팀 제 2기를 시작했으며 관심있으신 분은 참가하셔서 같이 공부를 하시길 바랍니다. 

매일 15분 전공공부팀 2기 안내글 바로가기


100일 성공 기록 목록들


최근 전공 팀 공부를 매일 15분이상(?)씩 해서 5월 초에 100일 성공을 했습니다. 

이 공부팀에 대해서 간단하게 설명하면 매일 카톡 오픈 채팅방에 15분이상 공부한 내용을 인증을 하면 됩니다. 

앱개발이 제 전문분야인데 웹이랑 블록체인을 주로 공부를 한 것 같네요. 

로그들을 한번 정리를 해보았습니다. 

수지아빠
108일

1일 / RxJava 그룹핑 예제 공부 / https://goo.gl/RfuQUY / 30분

2일차 / 개인앱 개발 및 마켓 출시 완료 / 90분 /https://play.google.com/store/apps/details?id=pe.kr.mhwguide

3일차 / RxKotlin Collection 공부 / 90분 / https://goo.gl/PbxYzo

4일차 / 스터디 자동 인증시스템 구축 및 테스팅 / 5시간

5일차 / 리엑트 네이티브 유데미 강좌 섹션 6,7 / 30분

6일차 / 리엑트 네이티브 유데미 강좌 29~45 (150개중) / 40분

7일차 / 개인 앱 업데이트/ 40분

8일차 / 유데미 rn 강의 / 3시간

9일차 / 유데미 rn 강의 / 2시간

10일차 / 유데미 rn 강의 / 90분

10일차 추가인증 / RN 예제 실습하기 #1 / https://github.com/bear2u/RN_study/tree/master / 2시간

11일차 / RN 예제 실습하기 #1 (완료) / https://github.com/bear2u/RN_study / 1시간

12일차 / RN 예제 실습하기 #2 로그인실습 (완료) / https://github.com/bear2u/rn-auth-example / 3시간

추가인증 / RN 리덕스 유데미 강의 / 1시간

13일차 / RN 예제 실습하기 #3 리덕스 연동해보기 / https://github.com/bear2u/rn-redux-exam / 2시간 30분

14일차 / RN 예제 실습하기 #3 리덕스 연동해보기 완료/ https://github.com/bear2u/rn-redux-exam / 1시간

노드 크롤링 프로젝트 / 1시간

15일차 / RN 예제 실습하기 #4 최종 예제 리덕스 연동 시작부분 / https://github.com/bear2u/RN_study2 / 2시간

추가인증 / 컨테이너 기반 가상화 플랫폼 ‘도커(Doker)’의 이해 온라인 강의 / 1시간 30분

16일차 / 도커 실행 강의 / 30분

17일차 / 블록체인 udemy 강좌 / https://github.com/bear2u/dApp-web3-examl1
/ 9시간

추가인증 / 블록체인 udemy 강좌 ~ 66까지 / 2시간

18일차 / 블록체인 웹서버에 추첨서비스 배포해보기 완료 (~99) / 8시간

추가인증 / 도커 이미지 만들기 온라인 강의 (티아카데미) / 2시간

https://github.com/bear2u/ether-lottery-exam

19일차 / 퀵스타트를 블록체인으로 만들어보자 예제#1 (100~121) / 3시간

https://gist.github.com/bear2u/7d42151c1a1126309d73669e0e6547a7

20일차 / Hyperledger 설치 삽질 / 2시간 30분

21일차 / 퀵스타트를 블록체인으로 만들기 실습 / 3시간 / https://github.com/bear2u/kickstarter-blockchain-exam

22일 / 블록체인 사설 구축 문서 리딩/1시간

23일 / 도커문서리딩 / 30분

24일 / 클린 코더 #1 / 20분

25일 / aws cloudfront 리딩 / 30분

26일 / 클린 코더스 #1,#2,#3 / 120분

27일 / 클린 코더스 #4 / 60분

추가인증 / 퀵스타터 블록체인 실습 진행중 / 60분 / https://github.com/bear2u/kickstarter-blockchain-exam

28일 / 퀵스타터 블록체인 실습 약 30프로 진행중 / 120분 / https://github.com/bear2u/kickstarter-blockchain-exam

29일 / 퀵스타터 블록체인 실습 약 50프로 진행중 / 40분 / https://github.com/bear2u/kickstarter-blockchain-exam

30일 / markdown 오픈소스 올려보기(rxjava2 변환완료) / 60분 / https://github.com/EveryDay-15min-Study-Team/MarkdownEditors

31일 / markdown 에디터 분석 / 60분

32일 / 퀵스타터 블록체인 실습 60프로 진행 / 40분 / https://github.com/bear2u/kickstarter-blockchain-exam

33일차/퀵스타터 블록체인 실습 70프로 진행 / 60분 / https://github.com/bear2u/kickstarter-blockchain-exam/commit/b8ba369270e9cec2627f4107c9ce100d596c4c03

34일차 / 코틀린인액션 ( 고차함수 ) / 60분

35일차 / 코틀린인액션 ( 인라인 람다 ) / 60분 /

36일차 / 퀵스터타를 블록체인으로 만들어보자 70프로 / 120분 /

37일차 / 솔리디티 문서 정독 / 30분

38일차 / 이더리움 지갑 만들기/ 30분

39일차 / 솔리디티로 좀비 만들기 / 60분

40일차 / 퀵스타터를 블록체인 형식으로 만들기 92% 완료 / 90분 / https://github.com/bear2u/kickstarter-blockchain-exam

41일차 / 퀵스타터를 블록체인 형식으로 만들기 완료 / 150분 / https://github.com/bear2u/kickstarter-blockchain-exam

42일차 / 커니의 안드로이드 대거편 / 30분

43일차 / 크립토좀비(블록체인) 레벨 2 따라해보기 / 2시간 / https://github.com/bear2u/til/blob/master/blockchain/test/c880-be44-b808-c2a8-2.md

44일차 / 크립토좀비 레벨2 완료 / 30분 / https://github.com/bear2u/til/blob/master/blockchain/dApp/zombie3.md

45일차 / 블록체인 코인뒤집기 설계 / 1시간

추가인증 / Hexo 블로그 생성 및 관리 / 1시간

46일차 / 블록체인 크립토좀비 레벨 3 완료 / 2시간 / https://github.com/bear2u/til/blob/master/blockchain/dApp/zombie3.md

47일차 / 블록체인 동전뒤집기 준비 / 30분

48일차 / 크립토좀비 레벨5(중간) 진행 / 4시간 / https://github.com/bear2u/til/blob/master/blockchain/zombies/zombie5.md

49일차 / Proof of Wook (블록체인 증명 시스템 알고리즘) 공부 / 1시간

50일차 / ERC20 코인 만들기 실습 / 2시간

ERC 827 코인 이론 공부 / 30분

52일차 / node and redux (full stack) 유데미 강좌 하루쿠 서버 올려보기 / 2시간 / https://github.com/bear2u/til/blob/74fb1341c5d168d24fc4a32b144a7802f1c4be91/node/fullstack_day1.md

53일차 / 블록체인 원리 공부 / 20분

54일차 / 블록체인 클론해보기 동강 / 5시간 / https://github.com/bear2u/nomadcoin

55일차 / 비트코인 클론해보기 동강 / 1시간 / https://github.com/bear2u/nomadcoin

추가인증 / mvp 크로님 rxjava 추가하기 / 30분

추가인증 / 비트코인 클론 소스 분석 / 20분

56일차 / 비트코인 클론 동강 / 1시간

추가인증 / 크로님 mvp dagger 적용 / 1시간

추가인증 / 좀비 요약본 정리 / 30분

57일차 / 비트코인 클론 동강 / 2시간 / https://github.com/bear2u/nomadcoin

추가인증 / mvp dagger2 적용 / 1시간

추가인증 / 기술 블로그 번역 연습 (1일차) / 1시간
https://github.com/bear2u/til/blob/master/android/Dagger2/binds_contributesAndroidInjector.md

58일차 / 모닝 비트코인 클론 동강 / 30분 / https://github.com/bear2u/nomadcoin

58일차 추가 / Dart 코드랩 및 flutter 앱 실행 / 2시간 / https://github.com/bear2u/til/blob/master/dart/Java_to_dart_codelab.md

59일차 / flutter 문서 실습 / 1시간
추가 / CSS 이론 수업 / 30분
추가 / 비트코인 클론 동강 / 25분
추가 / 기술블로그 독해연습 / 30분 / https://github.com/bear2u/til/blob/fa33793b60db979ad57a5840d6edc0505a2980ce/android/Dagger2/binds_contributesAndroidInjector.md#3%EC%9D%BC%EC%B0%A8

60일 / CSS 실습 / 1시간 / https://github.com/bear2u/til/blob/c2b747df950165bfa63d2c8ee59c8a32723ac324/web/README.md

61일 / CSS 카톡 처럼 만들기 / 1시간

추가 / dapp truffle 프레임 테스팅 및 디버깅 공부 / 1시간

62일 / dapp truffle 프레임워크 기초 공부 / 1시간

63일 / dapp truffle 프레임워크 펫샵 분석 / 2시간

64일 / 카톡 css 공부 / 1시간

65일 / 카톡 css 공부 / 2시간

66일 / 크립토 좀비 레벨 6 공부 / 30분

TIL Docker
https://github.com/bear2u/til/blob/master/server/docker/installing_wordpress_with_mysql.md

67일 / 크립토 좀비 레벨 6 공부, Docker로 워드프레스 세팅 / 20분, 2시간

TIL 좀비 6
https://github.com/bear2u/til/blob/master/blockchain/zombies/zombie6.md
추가인증 / 좀비6 공부하기 / 30분
추가인증 / 도커 동강 / 1시간 30분

68일차 / 이진탐색 알고리즘 정리 / 1시간 / http://javaexpert.tistory.com/931?category=699716

69일차 / 도커 책 훝어보기 / 1시간

추가 / 선택정렬 정리하기 / 1시간 / http://javaexpert.tistory.com/932

70일차 / 블록체인 dapp 이베이 구현 공부 / 2시간

71일차 / 블록체인 dapp 이베이 IPFS 서버 연결 공부 / 2시간

72일차 / 블록체인 이베이 ipfs 연결 및 에스크로 기능 구현 / 2시간 추가인증 / bootstrap 유데미 동강 / 6시간 / https://github.com/bear2u/boostrap_sandbox

73 일차 / 스팀잇 구조 분석 / 2시간

74 일차 / 부트스트랩 동강 실습 / 1시간

75 일차 / 블록체인 하이퍼레저 실습해보기 / 8시간

76 일차 / 블록체인 틱택톡 게임 개발해보기 실습 / 완료 / 8시간 / https://bear2u.github.io/tictoc_games_in_dapp_deployed/index.html

77일차 / 블록체인 raiden 설치 및 운영 삽질 / 실패 / 3시간

78일차 / 블록체인 공부 / 2시간

79일차 / 블록체인 + React 공부 / 2시간

80일차 / 고랭 언어 배우기 50% / 2시간

추가인증 / 블체복권을 truffle로 재구성 / 2시간 / https://github.com/bear2u/truffle_lottery

이더리움 해커톤

그림으로 이해하는 알고리즘 책 완독 / 4시간

그림 알고리즘 책 4장 ~ 완독 / 4시간

84 일차 / 리엑트 리덕스 공부 / 2시간

85 일차 / aws blockchain 삽질 / 4시간

86일차 / aws ALB 분석 / 3시간

7일차 / aws vpn 분석 / 3시간

88일차 / 고랭 문법 공부 / 40분

89일차 / 개인 플젝 / 4시간

90일차 / 개인 플젝 / 10시간

91일차 / 개인 프로젝트 / 5시간

92일차 / Flutter 기본 공부 / 2시간

93일 / flutter 공부하기 / 9시간 / https://github.com/bear2u/flutter_cat_box

94일 / 이더리움 코어 분석 / 1시간

95일 / React & Redux 게시판 개발 해보기 / 2시간

96일 / 부트스트랩 유데미 강의 / 1시간

97일 / React 기본 공부 / 1시간

98일/비트코인 분석 동강 공부/2시간

99일 / 이더리움 지갑 android 오픈 소스 분석 / 1시간

100일 / React Router 응용 부분 실습 / 1시간

101 / 블록체인 리엑트 개인 프로젝트 개발 / 10시간

102/리엑트웹 플젝 개발/13시간

103/블록체인 댑 스터디/2시간

104/react 스터디/2시간

105/bitcoin 책 정독/1시간

106/erc20 token project 개발/ 2시건

107 / Golang 스터디 준비 / 2시간

108 / Golang 스터디 준비 / 1시간

109/고랭 스터디/3시간/5.22

110/DAPP 개발 스터디/3시간/5.23

111/GoLang restApi 구축 공부/3시간/https://github.com/bear2u/til/tree/master/golang/restfulapi/5.24

참 많이도 공부를 했네요. ^^ 뿌듯합니다. 

100일 동안 같이 공부하면서 서로 자극도 많이 받고 위로도 되고 도움도 되었던 것 같습니다. 

혼자 가면 외롭고 힘들지만 같이 가면 끝까지 갈 수 있단 걸 다시 느낀 자리였던것 같습니다. 

100일 동안 블록체인 위주로 공부를 했네요. 아직 갈 길이 멀지만 다시 2기방에서 불 태워서 꼭 블록체인 전문가가 되는 그날까지..^^


현재는 진행중인 도전 목록들

  • 매일 15분 원서 읽기 도전 30일째
  • 일주일에 3회 블록체인 스터디 리딩 중(고랭, 이더리움, 하이퍼레저)
읽어주셔서 감사합니다. 더욱 더 열심히 노력하는 멋있는 아빠가 되도록 하겠습니다. ^^


출처 : https://stackoverflow.com/questions/29478751/how-to-cancel-an-emcascript6-vanilla-javascript-promise-chain

While there isn't a standard way of doing this in ES6, there is a library called Bluebird to handle this.

There is also a recommended way described as part of the react documentation. It looks similar to what you have in your 2 and 3rd updates.

const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then((val) =>
      hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
    );
    promise.catch((error) =>
      hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};

const cancelablePromise = makeCancelable(
  new Promise(r => component.setState({...}}))
);

cancelablePromise
  .promise
  .then(() => console.log('resolved'))
  .catch((reason) => console.log('isCanceled', reason.isCanceled));

cancelablePromise.cancel(); // Cancel the promise

Taken from: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

https://ethereum.stackexchange.com/questions/28703/full-list-of-geth-terminal-commands

By running geth and entering the start of each of the global objects I'm aware of I can get the following lists, but I won't mark this as the correct answer as I'm sure there is documentation out there somewhere.

> eth.

eth._requestManager            eth.getBlockUncleCount         eth.getWork                    
eth.accounts                   eth.getCode                    eth.hashrate                   
eth.blockNumber                eth.getCoinbase                eth.iban                       
eth.call                       eth.getCompilers               eth.icapNamereg                
eth.coinbase                   eth.getGasPrice                eth.isSyncing                  
eth.compile                    eth.getHashrate                eth.mining                     
eth.constructor                eth.getMining                  eth.namereg                    
eth.contract                   eth.getPendingTransactions     eth.pendingTransactions        
eth.defaultAccount             eth.getProtocolVersion         eth.protocolVersion            
eth.defaultBlock               eth.getRawTransaction          eth.resend                     
eth.estimateGas                eth.getRawTransactionFromBlock eth.sendIBANTransaction        
eth.filter                     eth.getStorageAt               eth.sendRawTransaction         
eth.gasPrice                   eth.getSyncing                 eth.sendTransaction            
eth.getAccounts                eth.getTransaction             eth.sign                       
eth.getBalance                 eth.getTransactionCount        eth.signTransaction            
eth.getBlock                   eth.getTransactionFromBlock    eth.submitTransaction          
eth.getBlockNumber             eth.getTransactionReceipt      eth.submitWork                 
eth.getBlockTransactionCount   eth.getUncle                   eth.syncing                    

> personal.

personal._requestManager personal.getListWallets  personal.newAccount      
personal.constructor     personal.importRawKey    personal.sendTransaction 
personal.deriveAccount   personal.listAccounts    personal.sign            
personal.ecRecover       personal.listWallets     personal.unlockAccount   
personal.getListAccounts personal.lockAccount     

> admin.

admin.addPeer              admin.importChain          admin.startRPC             
admin.constructor          admin.isPrototypeOf        admin.startWS              
admin.datadir              admin.nodeInfo             admin.stopRPC              
admin.exportChain          admin.peers                admin.stopWS               
admin.getDatadir           admin.propertyIsEnumerable admin.toLocaleString       
admin.getNodeInfo          admin.removePeer           admin.toString             
admin.getPeers             admin.sleep                admin.valueOf              
admin.hasOwnProperty       admin.sleepBlocks          

> miner.

miner.constructor          miner.setEtherbase         miner.toLocaleString       
miner.getHashrate          miner.setExtra             miner.toString             
miner.hasOwnProperty       miner.setGasPrice          miner.valueOf              
miner.isPrototypeOf        miner.start                
miner.propertyIsEnumerable miner.stop      


'링크모음 > BlockChain News' 카테고리의 다른 글

크립토 키티 소스  (0) 2018.04.30
블록체인 공부 모음 링크  (0) 2018.04.13
SMT 백서  (0) 2018.04.12
블록체인 관련 참조 사이트 모음  (0) 2018.02.12

5월 21일. 핫한 IT, 개발, Blockchain, 노마드 뉴스 TOP5

1. TOP 10 자바스크립트 에러
(5월 16일. code burst.)
- 가장 흔한 자바스크립트 탑10 에러!
- can not read property!
- 어떻게 에러를 피하는지 팁 공개​

2. 재택근무? 집에서 효율적으로 일하는 5가지 방법
(4월17일. Medium.)
- 디지털노마드, 프리랜서라서 집에서 일하는 당신을 위한 팁
- 1번. 잠옷입고 일하지 마라
- 린이 추천합니다.

3. 봇을 만들며 알게된 7가지 레슨
(5월 18일. Hacker Noon.)
- 트위터봇을 만든 개발자가 배운 7가지 레슨
- 1번. 타잎스크립트 까먹지마
 
4. 구글 자바스크립트 스타일 가이드 13가지 신박한 가이드
(3월 27일. free code camp)
- 역시 구글 갓
- 드르륵 하지말고 괜춘한거 줍줍 하길

5. 리액트 네이티브로 애니메이션 만들기
(3월 21일. Medium. 좋아요 4.3K)
- 오오- 스무스한데?


5월 첫재주 뉴스

1. 풀스택 개발자가 되기위한 테크트리 2017년도 버전
(2017년. medium)​
작년 17년도 자료이긴 하지만 여전히 박수를 37K나 받은 유용한 자료라서 공유합니다. 테크트리를 보면서 한번 정리해보세요. 시작은 항상 html, css, javascript 부터!!

2. 차세대 자바스크립트  ECMAscript 2016, 2017, 그리고 2018!!
(4월 3일. freecodecamp)
매년 마다 업그레이드 되는 차세대 자바스크립트, 일명 에크마스크립트! 매년 어떻게 발전했고 업그레이드 했는지 차근차근 살펴보고 업데이트 하자. 

3. 트위터 대규모 해킹사건! 비밀번호 바꾸는 것 잊지 않으셨죠?
(5월 4일. ProductHunt)
 
4. IPFS가 어떻게 웹을 바꾸고 있는가!
(5월 3일. rubiksdigital)

5.페이스북이 AI를 훈련시키는 방법? 인스타그램 해쉬태그!
 (5월 3일. medium)


4월 28일자 뉴스

1. 리액트 개발자라면 알아야하는 10가지 팁
(4월 27일. creativebloq)​
Higher-order components, Container and presentational components, Error boundaries.. 그외 총 10가지. 리액트 개발자라면 이정도는 알아야한다 10가지 팁!

2. VS Code가 이것도 할 수 있어? VSC 사용팁 16가지
(4월 25일.vscodecandothat.com)
나도 몰랐던 VSC의 숨은 기능 살펴보기. 워매? 이것도 가능함??? 참. emmet, prettier은 다들 잘 사용하고 계시죠?? 아직도 모른다면 지금 바로 클릭!

3. 디지털 노마드와 코리빙의 상관관계
(4월 24일. BBC)
 
4. 매우 큰 자바스크립트 어플리케이션 디자인하기
(4월 15일. Medium. 좋아요 20K)

5.도쿄 그리고 홍콩 in 2018
 (4월 23일. haywirez)


4월 21일자 뉴스

1. 프로그레시브 웹 앱(PWA) + iOS  
(3월 30일. Medium. 좋아요 17K)​
 iOS 11.3에 애플이 조용히 PWA 지원기능을 올렸다는데..?!
앱스토어 승인 없이 iOS앱을 설치할 수 있다고?!

2. 내가 TypeScript를 쓰게된 이유 
(3월 10일. Medium. 좋아요 1.1K)
어쩌다 사용하게된 TypeScript에 홀딱 반하게된 사연
자바스크립트 ES6 기반이라는거!

3. 블록체인은 사실 실전에서는 활용되지않는 죽은 기술이다 
(4월 5일. Medium. 좋아요 30K)
 
4. 어떻게 GraphQL이 리덕스를 대체하나
(3월 10일. Medium. 좋아요 7.1K)

5. 백엔드 개발자 로드맵 2018. 어떻게 차근차근 기술을 연마하는가 
 (4월 3일. Medium. 좋아요 4K)


4월 5일자 뉴스

#1. 프로그레시브 웹 앱 (PWA)에 대한 6가지 오해
- PWA는 오프라인 앱만 가능하다 ?!?!
- PWA는 모바일 전용이라 데스크탑 환경은 구리다 ?!?!
- PWA는 아직 개발중이다 ?!?!
https://medium.com/samsung-internet-dev/6-myths-of-progressive-web-apps-81e28ca9d2b1

#2. 개발자라면, 크롬 말고 파이어폭스!
- 요소검사
- css grid
- box model
- font faily 등등 특히 프런트 쪽 살펴볼때 대박 편하다는 평가!
https://medium.com/swlh/calling-all-web-developers-heres-why-you-should-be-using-firefox-983f012d4aec

#3. 만우절 4월 1일. 개발자 드립 모음
- ATM 드론
- 람보르기니 크립토커런시 스토어
- 마시면 새로운 언어를 득도하게 되는 맥주 (오!!)
https://blog.producthunt.com/lets-play-a-game-b5fba27fd844

#4. Typescript 2.8로 완성한 최종 리액트 컴포넌트 패턴!
https://levelup.gitconnected.com/ultimate-react-component-patterns-with-typescript-2-8-82990c516935

#5. 이모티콘으로 한방에 (귀엽게) 설명하는 Hash(해쉬)!
https://medium.com/swlh/this-simple-yet-powerful-invention-is-changing-the-world-d04688c25f13


3월 28일자 뉴스

#1. 블록체인 개발자가 되어야하는 이유​
- 현재 1명 블록체인 개발자마다 14개의 일자리가 제공됨. 
- 즉. 일자리를 넘쳐나는데 정작 개발자가 없음
- Upwork에 따르면 일자리 성장속도는 매년 3만 5천 %임. (!!)
- TOP 3 스킬: 하이퍼레저, 리플, 솔리디티
https://hackernoon.com/become-a-blockchain-developer-and-get-rich-74712f1dd310

#2. 스택오버플로우 2018년 설문조사 결과
- 72% 자바스크립트 사용, 69% HTML, 66% CSS, 59% SQL, JAVA 45% 
- TOP 3 JS 라이브러리: Node JS(50%), Angular(38%), React (28%)
- 25% 개발자들은 해커톤에 참여함. 이유는? 재밌어서
- 45% 개발자들은 이미 개발자로 활동하고 있음에도 부트캠프에 참여함. 왜? 더 배우고 싶어서​
https://medium.freecodecamp.org/stack-overflow-2018-developer-survey-faac8d3eb357

#3. Web 3.0 시대의 등장
- 3천개의 크립토 코인 그리고 9백개의 DApps 
- 시장 규모 800 billion +
- 어떻게 web 2.0에서 블록체인의 3.0으로 바뀌고 있는지!
https://medium.com/@matteozago/why-the-net-giants-are-worried-about-the-web-3-0-44b2d3620da5

#4. 웹 개발자가 되고싶다고? php 배우지 말고 node js를 배우라구!​
https://hackernoon.com/want-to-be-a-web-developer-learn-node-js-not-php-dc298154fafd

#5. 멍청하고 잘못된 리액트, 자바스크립트 코드 분별법!​
https://medium.freecodecamp.org/learn-to-spot-red-flags-in-your-react-javascript-code-d52d5fac85f4


3월 15일자 뉴스

1. PostgresSQL vs MongoDB
https://hackernoon.com/https-medium-com-cn007b-postgresql-vs-mongodb-6d8bdb7c1697

#2. Progressive 웹앱? 미래의 모바일 웹앱 개발이라고?
https://hackernoon.com/progressive-web-apps-the-future-of-mobile-web-app-development-f29257b0dea2

#3. WebSocket 그리고 CSS3로 보여주는 겁내 쿨한 매직 (오! 신기!)
https://medium.com/outsystems-engineering/making-magic-with-websockets-and-css3-ec22c1dcc8a8

#4. 에스토니아, 디지털노마드 비자 2019년 시행 예정
http://emerging-europe.com/in-brief/estonia-launch-digital-nomad-visa/

#5. 존버시대에 당신이 해야 할 2가지
https://hackernoon.com/2-things-to-do-while-the-cryptocurrency-market-falls-2c6cdfbd6809


2월 21일자 뉴스

#1. 프로그래머에게 유용한 크롬 익스텐션, 코드 익스텐션 22개 모음​
https://medium.freecodecamp.org/tools-i-wish-i-had-known-about-when-i-started-coding-57849efd9248

#2. 당신이 블록체인 앱 빌드를 배워야하는 이유​
https://medium.com/loom-network/why-you-should-learn-to-build-blockchain-apps-be9a92e8d08e

#3. 코드 공유하는 5가지 방법 모음​
https://hackernoon.com/5-practical-ways-to-share-code-from-npm-to-lerna-and-bit-732f2a4db512

#4. 안녕? 난 블록체인 개발자야!
https://medium.com/wethinkideas/how-to-validate-if-your-ideas-need-a-blockchain-e1a4846d16fd

#5. 코딩은 적성이 아니야??? 때려치기전에 이걸 읽어봐​
https://medium.freecodecamp.org/why-so-many-developers-quit-before-ever-getting-a-job-please-dont-1c0fd6459e5e


2월 6일자 뉴스

#1. 엑스포(expo)로 게임 빌드하기
https://blog.expo.io/building-a-connected-game-with-expo-f09295c512a9

#2. 마케터라면 이제는 알아야하는 챗봇 chatbots
https://medium.com/swlh/the-ultimate-guide-to-chatbots-for-lead-generation-7dac67f8296b

#3. 구글을 떠나 그랩 (grab)에 입사한 이유
https://medium.com/@steve.yegge/why-i-left-google-to-join-grab-86dfffc0be84

#4. 원격 일자리/회사/웹 플래폼 최종 Ultimate 리스트
https://github.com/ajukco/remote-jobs-list

#5. 블록체인 + 페이스북 = ?? 2018년에 무슨일이!!
https://hackernoon.com/facebook-and-crypto-what-you-need-to-know-for-2018-6bcd71794853

'링크모음 > etc' 카테고리의 다른 글

CI / CD 설명 [펌]  (0) 2018.01.29
영어공부 팁 모음  (0) 2017.11.25
영어 저작권 없는 자료 링크  (0) 2017.11.24
카카오톡 개인정보 약관 저장  (0) 2017.11.21
소스 검색 방법 펌  (0) 2017.11.18

윈도우 상에서 도커를 이용해서 몽고 DB 세팅

윈도우상에서 몽고디비 설치시 가끔 오류 나는 부분이 있다. 그럼 설치도 안되고 개발도 안된다.

그럴때 도커를 이용해서 빠르게 테스팅을 할수 있다.

우선 도커를 켜서 다음 명령어를 하자.

docker pull mongo
docker run --name database -d -p 27017:27017 mongo --noauth --bind_ip=0.0.0.0

27017 포트에 0.0.0.0 으로 바인딩하는 문구이다.

-noauth 는 아이디랑 비번없이 들어갈 수 있다.

만약 설정시 아래와 같이 가능하다.

docker run --name some-mongo -d mongo --auth
docker exec -it some-mongo mongo admin

db.createUser({ user: 'jsmith', pwd: 'some-initial-password', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });

................................
Successfully added user: {
    "user" : "jsmith",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}

그러면 잘 설치가 되었는지 확인해보자.

docker ps

윈도우 유저의 경우 virtucal box 에 방화벽을 열어야 한다.

virutal box 열기

기본 머신 선택한 후에 셋팅 열기

설정에 네트워크 메뉴 열기

네트워크 옵션 하단에 포워딩 메뉴 열기

그리고 줄 하나 추가 한다.

mongo / TCP / host port ( 임의로 < 1111 > ) / guest port ( 27017 )

그리고 클라이언트를 다운받는다.

보통 주로 받는 건

https://robomongo.org/

https://www.mongodb.com/download-center?jmp=hero#compass

(무료 커뮤니티 버전 선택)


그리고 마지막으로 클라이언트 접속을 해본다.

IP 는 localhost 또는 127.0.0.1 로 하고

포트는 임의로 정한 1111 로 해본다.

그럼 admin 으로 접속된걸 볼수 있다.

참고 사이트

https://codehangar.io/mongodb-image-instance-with-docker-toolbox-tutorial/

https://hub.docker.com/_/mongo/

[PowerMockup]

개발을 할때에나 기획을 할때 늘 스토리보드를 보면서 서로 대화를 하면 잘 통한다. 
사람은 글보단 그림이 좀 더 직관적이기 때문이다. 
그래서 이번참에 목업툴 제대로 된걸 구해보자고 해서 찾아보았다. 

우선 1순위는 파워목업이었다. 안에 슬라이스도 많고 꽤 쓸만한것 같다. 
현재 버전 4점대로 나온것 같다. 

그럼 한번 사용을 해보자. 

우선 해당 홈페이지는 여기이다. 

파워목업은 파워포인트가 깔려있어야 사용가능하다. 

그럼 실제 스크린샷은 어떨까?


오른쪽 Shape 의 경우 아직 내가 정식유저가 아니다 보니 활성화가 다 안되어있다. 구입하는 경우 활성화 될거라 본다. 

그럼 대충 이렇다 치고 구매는 어떻게 해야 할까?

종류별로 다 있다. 

유의할 점은 버전링을 봐야 한다. 현재 4.3 인데 Major 버전( 4 )이 올라가기 전까지 무료로 업데이트가 가능하다고 한다. 



그럼 구매링크는?

https://www.powermockup.com/order

다운로드는 어디에서?

https://www.powermockup.com/download

다트 기본

온라인 다트 편집기에서 실행가능하다.

https://dartpad.dartlang.org/

함수편

기본 출력

void main() {
    var test = "test";
    print('test = $test');
}

기본값 설정

void printMsg(String msg, [String value = 'undefined']) {
  print('msg = $msg, value = $value');
}
void main() {
  printMsg('1234', '5678');
  printMsg('1234');
}

........................
msg = 1234, value = 5678
msg = 1234, value = undefined

name, value 쌍으로 map 형태로 인수 넣기

void printMsg({String msg, String value}) {
  print('msg = $msg, value = $value');
}
void main() {
  printMsg(
    msg: "1234",
    value: "5678"
  );
}
..............................
msg = 1234, value = 5678

함수를 인자로 넣을수도 있다.

double add(double a, double b) => a + b;

//Function 정의자를 유의해서 보자
Function makeAdder(double value) {
  return (x) => add(value, x);
}

void main() {
  var adder1 = makeAdder(10.0);
  var adder2 = makeAdder(20.0);

  print('adder1 = ${adder1(5)} , adder2 = ${adder2(10)}');
}
...................................
adder1 = 15 , adder2 = 30

리스트

일반 리스트에 추가

유의할 점은 같은 타입만 추가 가능하다.

void main() {
  List<int> list = [2, 1, 3];
  list.add(4);
  print(list);
  print(list[0]);
}
..............

[2, 1, 3, 4]
2

for문 사용해서 출력

void main() {
  List<int> list = [2, 1, 3];
  printList(list);
}

void printList(List<int> list) {
  for(var i=0; i< list.length; i++) {
    print(i);
  }
}

foreach 사용

void main() {
  List<int> list = [2, 1, 3];
  usingForEach(list);
}

void usingForEach(List<int> list) {
  list.forEach( (x) {
    print(x);
  });
}

//짧게 설정 가능
void usingForEachShort(List<int> list) {
  list.forEach( (x) => print(x));
}

void main() {
  Map<String, int> cats = {
    'ABC': 1,
    'DEF': 2
  };

  print(cats);
}

Class

toString은 이미 Object에서 정의되어 있어서 오버라이딩 방식으로 다시 정의할 수 있다.

class Cat {
  String name;
  int age;

  @override
  String toString() {
    return '$name , $age';
  }
}

void main() {
  final cat = new Cat();
  cat.name = 'steve';
  cat.age = 10;

  print(cat.toString());
}

생성자를 바로 입력도 가능하다.

class Cat {
  String name;
  int age;

  //이 부분 살펴보자. 
  Cat(this.name, this.age);   

 // 또는 타입 지정도 가능하다. 
  Cat(String this._name, int this._age); 

  @override
  String toString() {
    return '$name , $age';
  }
}

void main() {
  final cat = new Cat('steve', 10);  

  print(cat.toString());
}

Try / Catch

기본적으로 예외를 잡는 부분

void main() {

  try {
    String userInput = '3,14';

    double doubleNum = double.parse(userInput);

    print(doubleNum);  
  } catch (e) {
    print(e);
  }  
}

.................
FormatException: Invalid double
3,14

특정 예외를 잡고 싶다면

void main() {

  try {
    String userInput = '3,14';

    double doubleNum = double.parse(userInput);

    print(doubleNum);  
  } on FormatException catch (e) {
    print("FormatException inside => $e");   
  } catch (e) {
    print("Global Exception => $e");
  }  
}

..................
FormatException inside => FormatException: Invalid double
3,14

Async Request

비동기 요청에 대해서 알아보자.

import "dart:html";

void handleSuccess(String response) {
  print('Request was ok');
  print(response);
}

void handleError(String error) {
  print('The request was not ok');
  print(error);
}

void main() {

  var result = HttpRequest.getString('https://rebounce.online/api/time');
  result.then(handleSuccess);
  result.catchError(handleError);

  print('Main function finshed');
}

.............
Main function finshed //비동기로 실행된 부분 체크하자...
Request was ok
{"time":"2018-05-01T05:06:35+02:00"}

체인 형태로도 가능하다.

var result = HttpRequest
    .getString('https://rebounce.online/api/time')
    .then((String response) {
      print(response);
    })
    .catchError( (dynamic error) {
      print(error);
    });

동기적으로 바꿀수도 있다.

Future, Async, Await 를 유의해서 보자.

import "dart:async"; //이 부분 추가됨
import "dart:html";

//Future 확인
 Future main() async {

  try {
      final response = await HttpRequest.getString('https://rebounce.online/api/time');   
      print('Request was ok => $response');   
  } catch (e) {
    print('Request error => + $e');
  }

  print('Main function has ended');

}
..........................

Request was ok => {"time":"2018-05-01T05:13:52+02:00"}
Main function has ended


Java for Dart Codelab

다트는 타입이 있는 언어입니다.

온라인에서 에디터를 실행 후 바로 테스팅이 가능합니다.

https://dartpad.dartlang.org/

  • 다트를 특별하게 만드는 이유
  • 생성자를 만드는 방법
  • 매개 변수를 지정하는 다양한 방법
  • getter , setter 를 만드는 방법 및 시기
  • 다트가 privacy 를 처리하는 방법
  • 팩토리를 만드는 방법
  • 다트에서 함수형 언어가 동작되는 방법
  • 다른 다트 콘셉

그럼 시작해보자.

class Bicycle {
  int cadence;
  int speed;
  int gear;
}

void main() {

}

main 함수로 실행한다.

  • 만약 argument를 가지고 싶다면 main(List<String> args) 를 사용할 수 있다.
  • 기본적으로 접근 제어자는 가지고 있지 않다. 예를 들어 public, private, protected
  • 다트는 기본적으로 2칸을(보통 4칸) 띄우고 사용한다. 만약 툴을 이용해서 reformat을 하고 싶은 경우 dartfmt를 이용한다.

생성자

클래스 생성자 지정이 가능하다.

생성시 바로 this 로 지정해서 내부 변수로 접근이 가능하다.

class Bicycle {  
  int cadence;
  int speed;
  int gear;

  Bicycle(this.cadence, this.speed, this.gear);
}

void main() {
  var bike = new Bicycle(2, 0, 1); //초기화
  print(bike);
}

...........................
Instance of 'Bicycle' // 결과

초기화

일반 클래스 초기화를 하는 것처럼 New 를 붙여서 한다.

오버라이드 함수

내부적으로 함수를 넣을 수 있다.

class Bicycle {
  int cadence;
  int speed;
  int gear;

  Bicycle(this.cadence, this.speed, this.gear);

  @override
  String toString() => 'Bicycle: $speed mph'; // 자바에서 toString과 유사하다.
}

void main() {
  var bike = new Bicycle(2, 100, 1);
  print(bike);
}

Getter 와 Setter

다트에선 각각의 변수에 대해 Getter 와 Setter를 제공한다. 그러기 위해선

다트에선 자바와 조금 다르게 처리를 한다.

Getter / Setter 지정하길 원하면 제어자를 붙이면 된다.

Setter를 따로 지정하지 않아서 컴파일 시 오류가 발생을 한다.

Setter를 붙이는 경우

class Bicycle {
  int cadence;
  int _speed;
  int gear;

  Bicycle(this.cadence, this._speed, this.gear);

  int get speed => _speed;
  set speed(int speedNum) {
    _speed = speedNum;
  }

  void applyBrake(int decrement) {
    _speed -= decrement;
  }

  void speedUp(int increment) {
    _speed += increment;
  }

  @override
  String toString() => 'Bicycle: $_speed mph';
}

void main() {
  var bike = new Bicycle(2, 100, 1);
//   bike.applyBrake(10);
  print(bike._speed);
  bike.speed = 10;
  print(bike._speed);
}

------------------------------------------------
100
10

Optional 파라미터

파라미터 지정시 선택적으로 가능하다.

import 'dart:math';

class Rectangle {
  int width;
  int height;
  Point origin;

  Rectangle({this.origin = const Point(0,0), this.width = 0, this.height = 0});

  @override
  String toString() => 'Origin: (${origin.x}, ${origin.y}), width: $width, height: $height';
}

main() {
  print(new Rectangle(origin: const Point(10, 20), width: 100, height: 200));
  print(new Rectangle(origin: const Point(10, 10)));
  print(new Rectangle(width: 200));
  print(new Rectangle());
}

...................................
Origin: (10, 20), width: 100, height: 200
Origin: (10, 10), width: 0, height: 0
Origin: (0, 0), width: 200, height: 0
Origin: (0, 0), width: 0, height: 0

Factory를 이용해서 생성하는 방법

아래와 같이 Circle, Square 클래스가 있다고 가정하자.

그리고 생성시 각자 공통적으로 묶을수 있다고 한다.

import 'dart:math';

abstract class Shape {
  num get area;
}

class Circle implements Shape {
  final num radius;
  Circle(this.radius);
  num get area => PI * pow(radius, 2);
}

class Square implements Shape {
  final num side;
  Square(this.side);
  num get area => pow(side, 2);
}

main() {
  var circle = new Circle(2);
  var square = new Square(2);
  print(circle.area);
  print(square.area);
}

................................
12.566370614359172
4

우선 최상위 함수로 올려보자. 유의해서 볼껀 Shape 클래스를 제어자 쪽으로 뺀 것이다.

import 'dart:math';

abstract class Shape {
  num get area;
}

class Circle implements Shape {
  final num radius;
  Circle(this.radius);
  num get area => PI * pow(radius, 2);
}

class Square implements Shape {
  final num side;
  Square(this.side);
  num get area => pow(side, 2);
}

//Shape 제어자를 눈여겨 보자.
Shape shapeFactory(String type) {
  if (type == 'circle') return new Circle(2);
  if (type == 'square') return new Square(2);
  throw 'Can\'t create $type'; 
}

main() {
  var circle = shapeFactory('circle');
  var square = shapeFactory('square');

  print(circle.area);
  print(square.area);
}
..........................................
12.566370614359172
4

두번째 방법은 Shape클래스 안에 factory생성자를 만드는 것이다.

 import 'dart:math';

abstract class Shape {
  //팩토리 함수를 정의
  factory Shape(String type) {
      if (type == 'circle') return new Circle(2);
    if (type == 'square') return new Square(2);
    throw 'Can\'t create $type';   
  }

  num get area;
}

class Circle implements Shape {
  final num radius;
  Circle(this.radius);
  num get area => PI * pow(radius, 2);
}

class Square implements Shape {
  final num side;
  Square(this.side);
  num get area => pow(side, 2);
}

main() {
  var circle = new Shape('circle');
  var square = new Shape('square');  

  print(circle.area);
  print(square.area);
}

상속의 개념

다트에서는 모든 클래스를 인터페이스 형태로 상속이 가능하다.

class CircleMock implements Circle {

}

상속을 하고 비어있는 상태일 경우 Missing concrete implementations오류가 발생될 수 있다.

그래서 상속을 할 경우 getter 변수를 다 적어줘야 한다.

class CircleMock implements Circle {
  num get radius;
  num get area;
}

함수형 언어 지원

자바스크립트 처럼 함수형태로 활용이 가능하다.

String scream(int length) {
  return "A${'a' * length}h!";
}

main() {
  var values = [1, 2, 3, 5, 10, 50];
  for (var length in values) {
    print(scream(length));
  }

  //함수형으로 바꾸는 경우
  values.map(scream).forEach(print);
  values.skip(1).take(3).map(scream).forEach(print); //이런식으로 가능하다. 
}

더 배우기 위해선

In completing this codelab, you've gained knowledge on some differences between Java and Dart. Dart is easy to learn and, in addition, itscore librariesandrich set of available packagesincreases your productivity. Dart scales well to large applications. Hundreds of Google engineers use Dart to write mission critical apps that bring in much of Google's revenue.

Next steps

A 20-minute codelab isn't long enough to show you all of the differences between Java and Dart. For example, this codelab hasn't covered:

If you are interested in seeing Dart technologies in action, try these codelabs:

You can learn much more about Dart with the following articles, resources, and websites.

Articles

Resources

Websites


+ Recent posts