Post on 23-Jan-2018
Go gopher 길들이기
정성환
2016-08-26
들어가기�전에…
Gopher�by�Renée�French,�and�tenntenn
Go Gopher Gophervs.
“Go is a language designed by Google to help solve Google’s problems; and Google has big problems.”
— Rob Pike @SPLASH conference, 2012
Why Go?
프로그래밍�언어란?
좋은�프로그래밍�언어란?
현실의�문제
“ Go언어는 구글이 구글의 문제를 풀기 위해 고안한 프로그래밍 언어이다. 그리고 구글은 커다란 문제들이 있다.”
Go at Google, 2012
현실의�문제�(Cont’d)
• 구글의�문제�
• 느린�빌드�속도�
• 통제되지�않은�연관�요소들(dependencies)�
• 개발자들은�각각�다른�언어를�사용�
• 낮은�프로그램�이해도�(읽기�힘든�코드,�형편없는�문서�등)�
• 노력의�중복�
• 업데이트에�드는�비용�
• 소프트웨어�버전의�불균형(skew)�
• 자동화�도구를�작성하는데�어려움�
• 어떤�언어로�작성된�라이브러리가�다른�언어에서�사용됨
Go�언어
“Go�언어는�간단하고�견고하며�효율적인�소프트웨어를�만들기�
적합한�오픈�소스�프로그래밍�언어이다.”
Fast Fun Productive
Go�언어를�(개인적으로)�품평하자면…
• C가�필요한�많은�곳에서�활용할�수�있는�언어�
• 서버�역할도�해야�하는�시스템�프로그램�
• C로�구현할�만큼�성능이�절박하지도�않고,�자바로�구현할�만
큼�고도화된�프레임워크가�필요없을�때…�
• DevOps를�위한�언어�
• 클라우드를�위한�언어�
• 임베디드�시스템을�위한�언어�
• 무엇보다�작성하기�즐거운�언어
Go�언어로�작성된�프로젝트
Docker Kubernates ETCD
Revel InfluxDB Gogs
“Simplicity is the ultimate sophistication.”
— Leonardo da Vinci
Go 언어 소개
Go�언어�주요�개발자
• Rob�Pike�(UTF-8,�Plan�9�from�Bell�Labs)�
• Ken�Thompson�(UNIX,�B,�C++,��Plan�9)�
• Robert�Griesemer�(HotSpot,�V8)�
• Russ�Cox�(Plan�9,�RE2,�Google�code�search)�
• Ian�Taylor�(GCC,�Gold)�
• Gustavo�Niemeyer�(Geohash)
Rob Pike Ken ThompsonRobert Griesemer
Go�언어�역사
• 2007.9�
Robert�Griesemer,�Rob�Pike,�Ken�Thompson이�화이트�보드에�새로운�언어의�지향점에�대해�그리다.�
• 2008.�1�
Ken�Thompson은�구체적인�아이디어들을�실현할�compiler를�개발하기�시작하다.�이때만해도�go는�google의�part-time�project�였다.�
• 2008.�3�
Ian�Taylor는�go의�draft�specification을�가지고�go�team과�독립적으로�gcc�front-end를�개발하기�시작하다.
Go�언어�역사�(Cont’d)
• 2008�mid�
go는�google의�full-time�project가�되다.�
• 2008�late�
Russ�Cox가�언어와�라이브러리들을�프로토타입에서�실제�제품으로�만들기�위해�팀에�합류되다.�
• 2009.�11�
오픈소스�프로그래밍�언어로서�런칭되다.
Go�언어�역사�(Cont’d)
• 2010.�9�
온라인�미디어인�Infoworld로�부터�2010�Bossie�Award(The�best�open�source�application�development�software부문)을�수상하다.�
• 2011.�3�
Google�App�Engine을�위한�Go�runtime이�발표되다.��
• 2012.�3�
첫�major�버전인�Go�version�1이�릴리스�되다.
Go�언어�역사�(Cont’d)
• 2013.5�
Go�v1.1�릴리스,�performance�
• 2013.12�
Go�v1.2�릴리스,�pre-emptive�scheduler,�performance�
• 2014.6�
Go�v1.3�릴리스,�precise�garbage�collection,�NaCl�support�
• 2014.12�
Go�v1.4�릴리스,�Android/ARM�support
Go�언어�역사�(Cont’d)
• 2015.8�
Go�v1.5�릴리스,�compiler/runtime�are�written�in�Go,�Concurrent�GC�
• 2016.2�
Go�v1.6�릴리스,�HTTP/2�support�
• 2016.8�
Go�v1.7�릴리스,�context�package,�vendoring�support�
성장�곡선
Google Trends
Go�언어�특징
• 컴파일�언어�
• 강�타입�언어,�컴파일러가�타입�추론�지원�
• 가비지�컬렉션�
• 클로져�(closure)�
• 고루틴�(Goroutine:�경량화�스레드)�
• 채널�(channel:�고루틴간�데이터�교환�방법)�
• 빠른�컴파일�속도�
• Cgo�(C�코드�사용)�
• 현대화된�라이브러리�(battery-included�standard�libraries)�
• 크로스�컴파일�기본�지원�
• 다양한�도구�제공�(fmt,�vet,�fix,�get,�install�등)
“Less is exponentially more.”
— Rob Pike @Go SF, Jun 2012
Go�언어�훑어보기예제와�함께하는…
First�impression
�1�package�main��2���3�import�"fmt"��4���5�func�main()�{��6�����fmt.Println("Hello,�world!")��7�����fmt.Println("안녕,�세상아!")��8���9�����이름�:=�“네이버�D2�Campus�Seminar"�10��11�����fmt.Printf("안녕,�%s\n",�이름)�12�}
• 세미콜론(;)�생략�
• UTF-8�기본(natively)�지원�
• 타입�추론
타입�시스템
• 숫자형(numeric)�타입:�uint,�int,�float,�complex,�byte,�…�
• string�
• function�• struct�• interface�• array�&�slice�• pointer�
• map�• channel
변수
• 변수�선언
var a int = 10var b string = "hello, world"var c bool false로 초기화
• 짧은(short)�변수�선언
d := 10.0e := truef := "hello, world"
컴파일러가 float64형으로 추론
제어문�I:�if,�for-loop,�switch
• if�문 • for�문
a := 100b := "hello"
if a > 100 { fmt.Println("greater than 100")}
if b == "hello" { fmt.Println(a, "world")}
for i := 0; i < 10; i++ { fmt.Printf("i: %d\n", i)}
j := 0for j < 10 { fmt.Printf("j: %d\n", j) j++}
for { fmt.Println("Oops! infinite loop")}
a := 100b := "hello"
switch b {case "hello": fmt.Println(b, "world")case "world": fmt.Println("hello", b)case "안녕", "世界": fmt.Println("안녕, 世界")default: fmt.Println("hello world")}
switch {case a < 100: fmt.Println("less than 100")case a > 100: fmt.Println("greater than 100")case a == 100: fmt.Println("equal to 100")case b == "hello": fmt.Println("true, but never reached")default: fmt.Println("never reached")}
• switch�문
제어문�I:�if,�for-loop,�switch�(Cont’d)
function
1 package main 2 3 import "fmt" 4 5 func add(a int, b int) int { 6 return a + b 7 } 8 9 func sub(a, b int) (val int) {10 val = a - b11 return12 }13 14 func div(a, b int) (ok bool, val int) {15 if b == 0 {16 // divide by zero17 ok = false18 return19 } else {20 ok = true21 }22 23 val = a / b24 return25 }
27 func main() {28 fmt.Println(add(2, 1))29 fmt.Println(sub(2, 1))30 31 if ok, val := div(2, 1); ok {32 fmt.Println(val)33 }34 }
• 다중�리턴값�
• 이름이�있는�결과�매개변수
struct�타입
• Go언어의�객체(object)�
• 대문자로�시작하는�필드/함수명은�Public�을�의미�(소문자는�Private)
�1�package�main��2���3�import�"fmt"��4���5�type�Person�struct�{��6�����Name�string��7�����age�int��8�}��9��10�func�(p�Person)�PrintName()�{�11�����fmt.Println("name:",�p.Name)�12�}�13��14�func�(p�Person)�GetNameAge()�(name�string,�age�int)�{�15�����name�=�p.Name�16�����age�=�p.age�17��18�����return�19�}
21�func�main()�{�22�����p1�:=�Person{"Elsa",��21}�23�����p2�:=�Person{Name:"Anna",�age:18}�24��25�����p1.PrintName()�26�����name,�age�:=�p2.GetNameAge()�27��28�����fmt.Println(name,�age)�29�}
interface�타입
• Duck�typing:�인터페이스를�구현한다는�명시적인�선언�없음
type�fmt.Stringer�
type Stringer interface { String() string }
func�(p�Person)�String()�string�{�����return�fmt.Sprintf("%s,�age�%d",�p.Name,�p.Age)�}�
func�main()�{�����p�:=�Person("Elsa",�21}�����fmt.Println(p)�}
slice�타입
• Go언어의�배열�
• 동적으로�크기�확장func�printPersons(persons�[]Person)�{�����for�i,�person�:=�range�persons�{���������fmt.Printf("%d:�%v\n",�i,�person)�����}�}�
func�main()�{�����p1�:=�Person{“Elsa",�21}�����p2�:=�Person{"Anna",�18}�����p3�:=�Person{“White",�14}�
����persons�:=�[]Person{p1,�p2,�p3}�����printPersons(persons)�
����persons�=�append(persons,�Person{"Ariel",�16})�����printPersons(persons)�
����persons�=�persons[1:3]�����printPersons(persons)�}
slice�타입�(Cont’d)
• slice�내부�구조
bs�:=�[]byte{'a',�'b',�'c',�'d',�'e'}
bs
slice�타입�(Cont’d)
bs2�:=�bs[2:4]
bs
bs2
5
5
slice�타입�(Cont’d)
bs�:=�[]byte{'a',�'b',�'c',�'d',�'e'}
bs�=�append(bs,�'f')
6
10[10]byte
copy
bs
bs
map�타입
• Python의�dictionary와�유사
�1�package�main��2���3�import�"fmt"��4���5�func�main()�{��6�����m�:=�make(map[string]int)��7���8�����m["Answer"]�=�42��9�����fmt.Println("The�value:",�m["Answer"])�10��11�����m["Answer"]�=�48�12�����fmt.Println("The�value:",�m["Answer"])�13��14�����delete(m,�"Answer")�15�����fmt.Println("The�value:",�m["Answer"])�16��17�����v,�ok�:=�m["Answer"]�18�����fmt.Println("The�value:",�v,�"Present?",�ok)�19�}
제어문�II�(for-range�loop)
1 package main 2 3 import "fmt" 4 5 func main() { 6 arr := []string{"alpha", "bravo", "charlie", "delta", "echo"} 7 m := make(map[string]int) 8 9 for i, val := range arr {10 m[val] = i11 }12 13 for key, val := range m {14 fmt.Printf("%d: %s\n", val, key) // 출력 순서 보장 안됨15 }16 }
error�타입
• 일반적인�Go�함수�꼴
• error�타입�(predeclared)
type error interface { Error() string}
• 일반적인�Go�함수�호출�예
1 package main 2 3 import ( 4 "fmt" 5 "os" 6 ) 7 8 func main() { 9 _, err := os.Open("a_file.txt")10 if err != nil {11 fmt.Println("failed to open:", err)12 os.Exit(1)13 }14 }
closure,�defer�함수
�1�package�main��2���3�import�"fmt"��4���5�func�main()�{��6�����prefix�:=�"Hello,"��7���8�����printFunc�:=�func(s�string)�{��9���������fmt.Println(prefix,�s)�10�����}�11��12�����printFunc("golang")�13�}
�1�package�main��2���3�import�"fmt"��4���5�func�main()�{��6�����defer�func()�{��7��������fmt.Println(3)��8����}��9��10�����fmt.Println(1)�11�����fmt.Println(2)�12�}
closure defer function
고루틴�(Goroutines)
• 다수의�Goroutine은�(상대적으로�적은�수의)�OS�스레드에�
분배(multiplexed)�됨�
• Goroutine은�OS�스레드처럼�같은�메모리�주소�참조�
• 디자인�목표:�스레드�생성�및�관리의�복잡도를�크게�낮춤
func�main()�{�����go�func()�{���������time.Sleep(time.Second�*�1)���������fmt.Println("inner�goroutine")����}�
���time.Sleep(time.Second�*�2)�}
통신(communicating)하여�메모리�공유
• 채널을�통한�데이터�공유�
• Hoare의�CSP(Communicating�sequential�process)에�기반�
• 데이터�동기화에�필요한�프리미티브(mutex,�semaphore)�필요�없음
“ 메모리를 공유해서 통신하지 말고, 통신하여 메모리를 공유합시다.”
func�main()�{�����c�:=�make(chan�int)�����done�:=�make(chan�int)�
����go�func()�{���������//�producer���������for�i�:=�0;�i�<�5;�i++�{�������������c�<-�i���������}�
��������close(c)�����}�()�
����go�func()�{���������//�consumer���������for�i�:=�range�c�{�������������fmt.Println(i)���������}�
��������done�<-�1�����}�()�
����<-done�����fmt.Println("all�done")�}
제어문�III�(select)
24 func after(duration time.Duration) chan bool {25 ch := make(chan bool)26 27 go func() {28 time.Sleep(duration)29 ch <- true30 }()31 32 return ch33 }34 35 func main() {36 fmt.Println(37 "Calculating the answer to everything")38 39 select {40 case result := <-getAnswerToEverything():41 fmt.Println(42 "I just found the answer to everything:",43 result)44 case <-after(time.Second * 3):45 fmt.Println("ERROR: timeouted!")46 }47 }
1 package main 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 const answerToEverything = 42 9 10 func getAnswerToEverything() chan int {11 ch := make(chan int)12 13 go func() {14 // 0 ~ 9초간 슬립15 nowUnix := time.Now().Unix()16 time.Sleep(time.Second *17 time.Duration(nowUnix%10))18 ch <- answerToEverything19 }()20 21 return ch22 }
복구�모델
• recover()을�통한�복구
package�main�
import�"fmt"�
func�main()�{�����defer�func()�{���������if�e�:=�recover();�e�!=�nil�{�������������fmt.Printf("recover�from�\"%s\"\n",�e)���������}�����}�()�
����a�:=�0�����b�:=�1�
����fmt.Println(b�/�a)�}
cgo
• Go에서�C�함수�호출�
• C에서�Go�함수�호출�
• 다른�언어에서�Go�라이브러리�호출�(Go�1.5)
�1�package�main��2���3�/*��4�#include�<stdio.h>��5�#include�<stdlib.h>��6���7�typedef�struct�{��8�����int�age;��9�����char�*name;�10�}�person;�11��12�person*�create_person(int�age,�char�*name)�{�13�����person�*p�=�(person*)malloc(sizeof(person));�14�����p->age�=�age;�15�����p->name�=�name;�16��17�����return�p;�18�}�19��20�void�print_person(person�*p)�{�21�����printf("%s�(age:%d)\n",�p->name,�p->age);�22�}�23�*/�24�import�"C"
26�import�"unsafe"�27��28�func�main()�{�29�����cs�:=�C.CString("bokdol")�30�����defer�func()�{�31���������C.free(unsafe.Pointer(cs))�32�����}�()�33��34�����p�:=�C.create_person(11,�cs)�35�����C.print_person(p)�36�}
“Go is a language for programmers who want to get things done.”
— Dave Cheney @Gophercon India, Feb 2015
Go�언어�톺아보기실습과�함께하는…
Go�언어�톺아보기
• 실습�목표�
• 비교적�짧은�시간�안에�Go�언어를�음미해�봅니다.�
• 간단한�프로그램을�작성해�Gopher로�첫발을�내딛습니다.
• 실습�과정�
• 차근차근�투어�
• 공식�Go�투어:�https://go-tour-kr.appspot.com/#1
Gopher�by�Renée�French,�and�tenntenn