Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Let's Go (golang)

10,921 views

Published on

Go 언어의 기초.
이것만 알면, Go를 읽고 쓸수 있다.
온라인 Go 문서들을 집대성한 교육자료.

Published in: Technology
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... ...................................ALL FOR EBOOKS................................................. Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... ...................................ALL FOR EBOOKS................................................. Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THAT BOOKS/FILE INTO AVAILABLE FORMAT - (Unlimited) ......................................................................................................................... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes Christian, Classics, Comics, Contemporary, Cookbooks, Art, Biography, Business, Chick Lit, Children's, Manga, Memoir, Music, Science, Science Fiction, Self Help, History, Horror, Humor And Comedy, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • If you want to download or read this book, Copy link or url below in the New tab ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • If you want to download or read this book, Copy link or url below in the New tab ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Let's Go (golang)

  1. 1. Let’s Go 2015-3-14 송상욱 swsong at fastcatsearch.com ♥ ♥
  2. 2. Why Go? • 클라우드 시스템 관련 Core들이 Go로 작성되고 있음. • 특히 Docker는 Go의 성공사례 • 기존 PaaS를 분석하려고 하니 Go를 읽을 줄 알아야한다. • Github의 Go 프로젝트 59,145개 (2015.3.14기준)
  3. 3. Top Github Projects in Go • docker/docker Docker - the open-source application container engine • limetext/lime Open source API-compatible alternative to the text editor Sublime Text • syncthing/syncthing Open Source Continuous File Synchronization • golang/go The Go programming language • GoogleCloudPlatform/kubernetes Container Cluster Manager from Google • go-martini/martini Classy web framework for Go • joewalnes/websocketd Turn any program that uses STDIN/STDOUT into a WebSocket server. Like inetd, but for WebSockets. • github/hub hub helps you win at git. • coreos/etcd A highly-available key value store for shared configuration and service discovery • astaxie/build-web-application-with-golang A golang ebook intro how to build a web with golang 2015.3.14 기준으로 뽑아봤어요
  4. 4. 참고문서 • golang-korea – go 개발언어 관련 자료를 한국어로 번역하는 프로젝트 – https://code.google.com/p/golang-korea/ • 그외의 인터넷 문서들
  5. 5. 기초 형아들~♥ 이제 부터 나의 기초를 보여줄게 난 생긴것 처럼 단순한 아이야~ ♥ 자 그럼 Let’s Go~♥
  6. 6. Go 는 Object-Oriented 언어인가? • 맞기도 하고 아니기도 하다. – http://golang.org/doc/faq#Is_Go_an_object-oriented_language • 아닌 이유 – 상속관계가 없다. No subclass • 맞는 이유 – object-oriented 스타일의 프로그래밍을 허용한다. interface제공. • object-oriented 스타일의 프로그래밍? – 상속은 제공하지 않으며 interface만 제공. – implements"라는 선언 필요없음. – 단순히 해당 인터페이스의 메소드를 구현하기만 하면 인터페이스 사용가능
  7. 7. 준비사항 • 홈페이지 : http://golang.org/ • Go SDK 다운로드 : http://golang.org/dl/ • 편집도구 : LiteIDE – 다운로드 : http://sourceforge.net/projects/liteide/files/
  8. 8. 함수형태 • 리턴값 없음 func f1() { } • 리턴값 존재 func f1() string { return “OK” } • 리턴값 이름 func f2() (r string) { r = “OK” return } • struct 내부함수 type Counter struct { n int } func (ctr *Counter) add(int amount) { //리시버 Counter 선언. ctr.n += amount; } func f1() (string, int) { return “OK”, 1 } 리시버는 나중에 자세하게 나오니까 염려하지마요
  9. 9. Go 가시성 • 최상위 type, 함수, method, 상수, 변수 혹은 구조체의 필드나 method의 이름이 대문자로 시작하면 패키지의 사용자는 접근이 가능 • 반면에 소문자일 경우에는 패키지 내부에서만 접근이 가능
  10. 10. 진입점 • main 패키지의 main() 함수 package main func main() { //무언가를 수행한다. }
  11. 11. 실행과 빌드 • 실행 $ go run 파일명 • 빌드 $ go build 또는 $ go build 파일명 • 빌드결과삭제 $ go clean
  12. 12. 숫자타입 • 정수형 – uint8, uint16, uint32, uint64 – int8, int16, int32, int64 – uint, int, uintptr : 장비의존적 – uint8 == byte – uint32 == rune • 부동소숫점 – float32, float64 • 복소수 – complex64, complex128
  13. 13. 그외 모든 타입 bool  불린 true, false numeric  이전 장에서 설명한 숫자타입 string  문자열. Java와 달리 소문자이다. array  [] slice  [] array를 참조한다. ex) arr[2:5] struct  ex) type struct Human { } pointer  * function  func interface  interface map  map channel  chan
  14. 14. 키워드 break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var
  15. 15. Java와 다른점 몇가지 • 세미콜론은 생략한다. 하지만 같은줄에 여러명령에는 사용. a= 1 b= 2 c=1; d=2 • 변수선언에는 var를 사용하고 타입은 맨뒤에 선언 var a int cf) int a var b string cf) String b • main함수는 파라미터가 없다. 대신 flag사용 var port = flag.String("port", "8080", "Listening port") func main() { flag.Parse() } • if, for 에 괄호를 사용하지 않으며, 여는 중괄호({)는 반드시 같은줄에 사용한다. if x > 1 { .. } for i:=0; i< 100; i++ { //구현 } • 선언과 할당을 동시에 할때는 =가 아닌 := 를 사용한다. 이때 변수타입은 값의 타입으로 추정한다. price := 2000  var price int = 2000 과 동일.
  16. 16. Java와 다른점 몇가지 2 • switch-case 는 break가 필요없다. 기본이 break이며, 필요시 fallthrough 사용. • try-catch-finally, throw가 없다. defer  finally raise  throw recover  catch • 포인터존재 var a *Human a := new(Human) b := &i • 사용하지 않는 변수나 import는 컴파일시 에러발생. 제거하거나 주석처리해야한다. • import 에 alias 를 줄 수 있다. import “math” import math2 “my/custom/math” math2.Average(1,2) • private , public 이 없다. 대신 함수명이나 변수명이 대문자이면, public이고 소문자이면 private이다. var Name string  public var price int  private func CallMePublic()  public func callMeInside()  private
  17. 17. Java와 다른점 몇가지 3 • class라는 keyword가 없다. 대신 struct를 만들고 함수에 struct명을 주어(리시버) class와 동일하게 사용할 수 있다. • Thread가 없다. 대신 light-weight인 고루틴을 사용한다. go something()  비동기적 something()함수실행 • 여러값을 동시에 리턴가능하다. return a,b,c • 여러값을 동시에 할당가능하다. var a,b,c int = 1,2,3 • 여러변수를 동시에 선언가능하다. import도 동일. • 자동형변환이 안된다. 명시적 형변환필요. var c int = 2000 var d float64 = float64(c)  OK. 만약 var d float64 = c 은 에러. var d float64= float32(c))도 에러. • 배열선업시 괄호는 앞에 쓴다.  []int var ( a int b string ) import ( “fmt” “io” )
  18. 18. 변수선언/할당 • 사용법1 var x string = "Hello World" • 사용법2 var x string x = "Hello World" • 사용법3 x := "Hello World" > 일반적으로 많이 사용하는 방식. 타입추정.
  19. 19. 변수선언/할당2 • 같은줄에 컴마구분으로 여러변수를 동일 타입으로 정의가능 a int, b int , c int , d int  a, b, c, d int a int, b int, c float64, d float64  a, b int, c, d float64 func f(a, b int, c, d float64) { // do something.. } func main() { f(1, 2, 3., 4.) }
  20. 20. 다중값 할당 func f() (int, int) { return 5, 6 } func main() { x, y := f() } • 오류와 함께 반환하는 기능은 자주 사용됨. f, err := os.Open(name, os.O_RDONLY, 0) if err != nil { return err } //파일 f 사용.
  21. 21. 다중값 할당2 • 두값의 SWAP이 편하다 • OLD한 방식 a = 10 b = 30 tmp := b b = a a = tmp • Go 방식 a = 10 b= 30 a, b = b, a • 여러개도 된다. a, b, c = b, c, a
  22. 22. 다중값 할당3 • 동일한 내용 다른 표현 var ( a int = 1 b int = 2 c int = 3 ) var a int, b int, c int = 1, 2, 3  syntax error: unexpected comma, expecting semicolon or newline or } var a, b, c int = 1, 2, 3 a, b, c := 1, 2, 3
  23. 23. 사용하지 않는 변수 • Go 컴파일러는 사용하지 않는 변수존재시 에러발생. func main() { i := 0 } $ go run test.go # command-line-arguments .test.go:16: i declared and not used
  24. 24. 문자열 비교 • 자바와 다른점 var x string = "hello" var y string = "hello" fmt.Println(x == y) > true
  25. 25. 상수 • 변수 var x string = "Hello World” • 상수 const x string = "Hello World"
  26. 26. 상수 • 상수의 Type을 정하지 않으면, 사용될때context에 의해 정해짐. const huge = 1 << 100 fmt.Println(huge)  constant 1267650600228229401496703205376 overflows int fmt.Println(huge >> 40)  4611686018427387904 • iota(Java의 Enum효과) const ( red = iota // red == 0 blue // blue == 1 green // green == 2 )
  27. 27. 다중 정의 • 변수 var ( a = 5 b = 10 ) • 상수 const ( Space = " ” Newline = "n" )
  28. 28. 다중 정의 • Import import ( "os" "fmt" ) • Type type( book struct { title string price int } coffee struct { size int origin string } )
  29. 29. 루프 • For가 유일한 루프. • 괄호가 없다. – 사용법1 for { } – 사용법2 for i < 10 { } – 사용법3 for i:=0 ; i < 10; i++ { }
  30. 30. 특별 루프 • Range func main() { x := [5]int{1,2,3,4} for i, value := range x { fmt.Println(value) } } – i : 현재위치(0부터시작) – value : 현재값. x[i] • 컴파일시 에러 : i declared and not used func main() { x := [5]int{1,2,3,4} for _, value := range x { fmt.Println(value) } } – _(언더스코어)는 컴파일러에게 이것이 필요하지 않다고 알려주는 데 사용
  31. 31. Switch-Case • 괄호가 없다. • 상수이거나 Integer이 필요가 없다. 문자열도 가능. • Break가 필요없다. 기본적으로 break이며, 통과를 원하면 fallthrough. • switch 값이 생략된 경우에는 기본값은 true가 된다. func main() { str := "3" switch str { case "1": fmt.Println("@1") case "2": fmt.Println("@2") default : fmt.Println("default") } } ---- switch { case i < 0 || i > 0: fmt.Println(”Non-Zero") fallthrough case i == 0 : fmt.Println(”Zero") }
  32. 32. Switch-Case • 컴마로 여러 조건가능. switch c { case ' ', '?', '&', '=', '#', '+', '%': … }
  33. 33. 배열 • 사용법1 var x [5]int x[0] = 1; x[1] = 2; ;x[2] = 3; x[3] = 4; x[4] = 5 • 사용법2 x := [5]int{1,2,3,4,5} • 사용법3 x := [5]int{ 1,2,3,4, 5, } – 한줄씩 사용할 경우 컴마가 반드시 값뒤에 붙어야하고, 마지막 원소도 반드시 컴마존재. • 사용법4 x := []int{1,2,3,4,5,7,8,9,10} // [1,2,3,4,5,7,8,9,10] 또는 x := []int{} // [] – 배열의 길이를 정하지 않아도 됨.
  34. 34. 슬라이스 • 배열을 참조하는 일부를 가리킴.데이터공유 arr := []int{1,2,3,4,5} x := arr[0:3] // 0<=i<3  [1,2,3] x := arr[:3] // i<3  [0:3]과 동일 x := arr[3:] // i >= 3  [4,5] • 선언 var x []float64 • 생성 x := make([]float64, 5) x := make([]float64, 5, 10)
  35. 35. 슬라이스 • 배열을 참조하는 일부를 가리킴.데이터공유 arr := []int{1,2,3,4,5} x := arr[0:3] // 0<=i<3  [1,2,3] x := arr[:3] // i<3  [0:3]과 동일 x := arr[3:] // i >= 3  [4,5] • 선언 var x []float64 • 생성 x := make([]float64, 5) x := make([]float64, 5, 10)
  36. 36. 슬라이스 관련함수 • append slice1 := []int{1,2,3} slice2 := append(slice1, 4, 5) // 4,5 를 추가. // slice1  [1,2,3] // slice2  [1,2,3,4,5] • copy slice1 := []int{1,2,3} slice2 := make([]int, 2) // 길이가 2인 슬라이스 copy(slice2, slice1) // slice1  [1,2,3] // slice2  [1,2]
  37. 37. 맵 • Key는 동등연산자(==)이 가능한 integer, float, 복소수, string, 포인터, 그리고 인터페이스와 같이 어떤 타입이든 가능 • struct와 배열,slice는 동등연산을 할 수 없기 때문에 불가. • 사용법1 var x map[string]int x = make(map[string]int) x["a"]=1; x["b"]=2; x["c"]=3 • 사용법2 x := make(map[string]int) x["a"]=1; x["b"]=2; x["c"]=3 • 사용법3 x := map[string]int{"a":1, "b":2, "c":3}
  38. 38. 맵 • 참조 name := x[”aaaa"] 또는 name, ok := x[”aaaa"] fmt.Println(name, ok) • 삭제 delete(x, "b") • 갯수확인 len(x)
  39. 39. 다중맵 elements := map[string]map[string]string{ "H": map[string]string{ "name":"Hydrogen", "state":"gas", }, "He": map[string]string{ "name":"Helium", "state":"gas", }, }
  40. 40. 가변함수 func add(args ...int) int { total := 0 for _, v := range args { total += v } return total } • add(1,2,3)  OK • xs := []int{1,2,3} add(xs)  Error. 가변인자는 슬라이스와 호환되지 않는다. • add(xs...)  OK. 가변인자 변수자체를 전달할때는 ...을 붙여야 인식됨. 가변인자는 add(foo...)와 같이 ...를 반드시 붙어야해요
  41. 41. 클로저 func main() { add := func(x, y int) int { return x + y } fmt.Println(add(1,1)) } --------------------------------------------------------------------------------------------- func makeEvenGenerator() func() uint { i := uint(0) return func() (ret uint) { ret = i i += 2 return } } func main() { nextEven := makeEvenGenerator() fmt.Println(nextEven()) // 0 fmt.Println(nextEven()) // 2 fmt.Println(nextEven()) // 4 }
  42. 42. Defer (지연된 호출) • 해당함수 종료시 실행됨. • Java의 try-finally 대체 func main() { defer second() first() } ------------------------------------------------ f, _ := os.Open(filename) defer f.Close() • 장점 1. Close 호출을 Open 호출 가까이에 둬서 이해하기가 쉽다. 2. 함수에 return이 여러 개 있더라도 Close가 어떠한 return 시라도 호출 3. 지연된 함수는 런타임 패닉이 일어나더라도 실행
  43. 43. Panic & Recover • Java의 throw-catch 를 대체 • panic : 런타임오류 강제발생 • recover : 런타임패닉 처리 • 잘못된 사용예. recover가 호출기도 전에 종료. panic("PANIC") str := recover() • 올바른 사용예. defer와 짝을 맞춤. 익명함수 사용. defer func() { str := recover() fmt.Println(str) }() panic("PANIC”) • 사용목적 – 범위를 벗어난 배열 인덱스에 접근시 에러처리 – 맵을 초기화하는 것을 잊어버릴 경우 에러처리
  44. 44. 구조체 / 인터페이스
  45. 45. 포인터 • Address 연산자로 포인터 사용 func one(xPtr *int) { *xPtr = 0 } func main() { x := 5 one(&x) fmt.Println(x) // x는 1 } ---------------------------- • new 로 포인터 사용 func main() { xPtr := new(int) one(xPtr) fmt.Println(*xPtr) // x는 1 }
  46. 46. 포인터 접근 type Rectangle struct { length, width int } func main() { var r *Rectangle r = new(Rectangle) // Rectangle에 대한 포인터 반환. r.length = 5 (*r).length = 5 //r.length=5와 동일하다. fmt.Println(r.length) //  5 fmt.Println((*r).length) //  5 } • c++과 달리 -> 가 없다. 포인터, 인스턴스 모두에 대해 dot(.) 노테이션 사용
  47. 47. Struct • Go는 클래스가 없다. • 하지만 클래스와 동일한걸 만들수 있다. • Java에서 Rectangle 클래스는 area()메소드를 가지고 있음 //JAVA public class Rectangle { private float x1, y2, x2, y2; public float area() { float l = distance(x1, y1, x1, y2); float w = distance(x1, y1, x2, y1); return l * w; } private float distance(float x1, float y1, float x2, float y2) { float a = x2 - x1; float b = y2 - xy; return Math.sqrt(a*a + b*b); } }
  48. 48. Struct //C++ class rectangle { private: float x1, y2, x2, y2; public: float area(void); } inline float rectangle::area() { float l = distance(x1, y1, x1, y2); float w = distance(x1, y1, x2, y1); return l * w; } float distance(float x1, float y1, float x2, float y2) { float a = x2 - x1; float b = y2 - xy; return sqrt(a*a + b*b); }
  49. 49. Struct • Receiver를 사용하여 특정 type에 종속적 함수를 생성한다. //Go type Rectangle struct { x1, y1, x2, y2 float64 } func (r *Rectangle) area() float64 { l := distance(r.x1, r.y1, r.x1, r.y2) w := distance(r.x1, r.y1, r.x2, r.y1) return l * w } func distance(x1, y1, x2, y2 float64) float64 { a := x2 – x1 b := y2 – y1 return math.Sqrt(a*a + b*b) } func main() { r := Rectangle{1, 5, 3, 7} fmt.Println(r) //  {1 5 3 7} }
  50. 50. Struct • 리시버는 포인터 or 객체중 어느걸 써야할까? type Rectangle struct { length, width int } func (r Rectangle) set(i, j int) { r.length = i r.width = j } ----- • Receiver는 아래 두가지 모두 사용가능. func (r Rectangle) set(i, j int) { .. } // OK func (r *Rectangle) set(i, j int) { .. } // OK
  51. 51. Struct 1. 객체 사용시 func (r Rectangle) set(i, j int) { r.length = i r.width = j } func main() { r := Rectangle{1, 5} r.set(10, 50) fmt.Println(r) //  [1 5] 안바뀐다. r이 set함수에 복사되어 전달됨. shallow copy. } 2. 포인터 사용시 func (r *Rectangle) set(i, j int) { ..} 결과 [10 50] 변경됨. call by reference.
  52. 52. Struct • 생성방식 type Rectangle struct { length, width int } var r Rectangle // Rectangle타입. 내용은 length=0, width=0 var r *Rectangle // *Rectangle타입. 내용은 nil. r := new(Rectangle) // *Rectangle타입. 내용은 length=0, width=0 r := Rectangle{width:10, length: 50} // Rectangle타입. 이름명시 r := Rectangle{10, 50} // Rectangle타입. 순서대로 할당
  53. 53. Struct – embedded type type Person struct { Name string } • HAS-A 관계 type Android struct { Person person Model string } a.person.Name=5 //Person을 통해서 접근 • IS-A 관계 type Android struct { Person //Android is a person Model string } a := new(Android) a.Name=5 // Android가 Person인것 처럼 접근가능.
  54. 54. Struct –기본 타입 확장 • 기존 int 타입을 기반으로 string() 함수를 붙인다. #src/fmt/stringer_test.go 참조 type TI int func (v TI) String() string { return fmt.Sprintf("I: %d", int(v)) } • Java라면 public class IntegerType extends Integer { public String string() { .. } } $ javac IntegerType.java IntegerType.java:1: error: cannot inherit from final Integer public class IntegerType extends Integer { ^ 1 error  Integer는 Final class 이므로 확장 불가.
  55. 55. Interface • Rectangle type Rectangle struct { x1, y1, x2, y2 float64 } func (r *Rectangle) area() float64 { .. } • Circle type Circle struct { x, y, r float64 } func (c *Circle) area() float64 { .. } • Shape type Shape interface { area() float64 } • 사용시 func totalArea(shapes ...Shape) float64 { .. } 어떠한 선언적 종속관계도 없다!!
  56. 56. 동시성
  57. 57. 고루틴(go) package main import ( "fmt" "math/rand" "time" ) func f(n int) { amt := time.Duration(rand.Intn(250)) time.Sleep(time.Millisecond * amt) fmt.Println(n) } func main() { for i := 0; i < 1000000; i++ { go f(i) } var input string fmt.Scanln(&input) }
  58. 58. 채널(chan) • 채널(channel)은 두 고루틴이 서로 통신하고 실행흐름을 동기화하는 수단을 제공 func main() { c := make(chan string) c <- "oce” msg := <-c fmt.Println(msg) } 결과 $ go run main.go fatal error: all goroutines are asleep - deadlock! • main함수는 첫번째 고루틴이다.
  59. 59. 채널(chan) func main() { c := make(chan string) go func() { // 익명 함수의 고루틴 c <- "oce” }() msg := <-c fmt.Println(msg) } 결과 $ go run main.go oce • 비동기 채널설정 기본적으로 채널은 동기적. 버퍼를 주면 비동기적으로 동작가능. c := make(chan int, 1) //길이가 1인 버퍼설정.
  60. 60. 채널(chan) - 방향 • 양방향 func f(c chan string) • 입력전용 func f(c chan<- string) • 출력전용 func f(c <-chan string)
  61. 61. Select c1 := make(chan string) c2 := make(chan string) select { case msg1 := <- c1: fmt.Println("Message 1", msg1) case msg2 := <- c2: fmt.Println("Message 2", msg2) case <- time.After(time.Second): fmt.Println("timeout") default: fmt.Println("nothing ready") }
  62. 62. 기타
  63. 63. 초기화 • func init() 이 존재하면 main()보다도 먼저실행 • init()은 해당패키지 import시 실행 – import “abc” 가 실행시 abc.go내 init()이 실행된다. • init() 여러번 중복해서 선언될수 있으며, 코드 순서대로 순차적 실행 package main import "fmt” var i = foo() func foo() int { fmt.Println("Call foo()") return 1 } func init() { fmt.Println("Call init() 1") } func init() { fmt.Println("Call init() 2") } func main() { fmt.Println("Call main()") } func init() { fmt.Println("Call init() 3") } 실행결과 Call foo() Call init() 1 Call init() 2 Call init() 3 Call main()
  64. 64. make()와 new()의 차이 • make() – 오로지 slice, map, channel을 만드는 용도로만 사용. – 포인터를 반환하지 않음. 즉 *T가 아닌 T타입을 리턴. var p *[]int = new([]int) // slice구조를 할당함; *p == nil; 그다지 유용하지 않음 var v []int = make([]int, 100) // slice v는 이제 100개의 int를 가지는 새로운 배열을 참조함 // new : 불필요하게 복잡함: var p *[]int = new([]int) *p = make([]int, 100, 100) // make: 자연스러움: v := make([]int, 100)
  65. 65. Conversion var f1 float64 = 6.0 f2 := 12 / f1 // 상수 12는 float64로 자동변환  2 var i int = 12 var f1 float64 = 6.0 f2 := i / f1 // 변수타입은 자동변환되지 않는다.  invalid operation: i / f1 (mismatched types int and float64) var i = 12. //12. 은 float64 형이다. var f1 float32 = 6.0 f2 := i / f1 //심지어 같은 float형이라도 float32와 float64는 자동형변환 불가.  invalid operation: i / f1 (mismatched types float64 and float32)
  66. 66. Conversion var i = 12. var f1 float32 = 6.0 f2 := i / f1  ERROR var i = 12. var f1 float32 = 6.0 f2 := float32(i) / f1  2 i := 12 fmt.Println(”Result = ” + i)  cannot convert "Result=" to type int invalid operation: "Result=" + i (mismatched types string and int) import ”strconv” i := 12 fmt.Println("Result = " + strconv.Itoa(i))  Result = 3
  67. 67. GOROOT • GOROOT는 Go SDK의 설치위치를 나타내며, 이 위치하위에서 기본 라이브러리와 문서등을 찾아서 사용한다. • Go 기본설치위치 – *nix : /usr/local/go – Windows : C:Go • 만약 다른 곳에 설치했다면 GOROOT 환경변수를 설정해주어야함. – ex) /application/go에 설치했다면, export GOROOT=/application/go export PATH=$PATH:$GOROOT/bin – *nix계열은 .bash_profile과 같은 설정파일에 추가한다. • 기본위치에 설치되어 있다면 GOROOT를 설정할 필요없음
  68. 68. GOPATH • Java에는 classpath, Go에는 GOPATH • import 시 GOPATH의 경로를 찾음 • *Nix계열은 콜론, Windows는 세미콜론으로 연결된 경로 리스트 GOPATH=/home/user/gocode /home/user/gocode/ src/ foo/ bar/ (go code in package bar) x.go grep2/ (go code in package main) y.go bin/ grep2 (installed command) pkg/ linux_amd64/ oce/ bar.a (installed package object) Tip: GOPATH가 여러개일때 특정 src하위에서 install 된 패키지파일은 해당 고패스하위로 들어간다.
  69. 69. 패키지 GOPATH=<User Home Directory>/go $ cd go $ mkdir -p src/math2 $ cd src/math2 $ vi foo.go # 파일명과 패키지 명이 동일할 필요없음. package math2 // 패키지명은 폴더와 이름이 일치해야함. func Average(i, j int) float64 { // average가 아닌 대문자 Average로 선언. import후 호출가능함 return float64(i + j) / 2 } $ go install  <User Home Directory>/go/pkg/darwin_amd64/math2.a 생성됨. ------------------- package main import “fmt” import “math2” func main() { i := math2.Average(10,30) // 20 fmt.Println(“i=“, i) } > 패키지명을 math로 하면 이미 존재하는 go의 기본패키지명과 겹치므로 go install시 에러발생.
  70. 70. 패키지 • 최상위가 아닌 중간경로를 주면 math라는 이름으로 패키지 생성가능. $ mkdir -p src/oce.org/math $ cd src/oce.org/math $ vi foo.go package math func Average(i, j int) float64 { return float64(i + j) / 2 } $ go install  <User Home Directory>/go/pkg/darwin_amd64/oce.org/math.a 생성됨. ------------------- package main import “fmt” import “oce.org/math” func main() { i := math.Average(10,30) // 20 fmt.Println(“i=“, i) }
  71. 71. 패키지 • 패키지 이름의 중복을 방지하기 위하여 import시 Alias가능 package main import “fmt” import “math” import math2 “oce.org/math” func main() { i := math.Average(10,30) j := math2.Average(10,30) fmt.Println(“i=“, i, “j=“, j) }
  72. 72. 패키지 • Alias를 Dot(.) 으로 하면 해당패키지를 이름없이 바로 접근가능. package main import . “fmt” func main() { Println(“Called without package name!”) }
  73. 73. 패키지 - remote • go get
  74. 74. 문서화 • Java에는 javadoc, Go에는 godoc • usage: godoc package [name ...] godoc -http=:6060 $ godoc oce.org/math PACKAGE DOCUMENTATION package math import "oce.org/math” FUNCTIONS func Average(i, j int) float64 $ godoc oce.org/math average  대소문자구분 No match found. $ godoc oce.org/math Average func Average(i, j int) float64 $godoc –http=:6060  로컬 웹서버시작  http://localhost:6060/pkg/
  75. 75. 문서화 //Copyright 2015 // oce.org에서 제공하는 수학패키지. //  빈줄삽입. // 2015-3-14 업데이트. package math // 평균을 구한다. // 입력값은 i,j 정수를 받아들인다. // 리턴값은 float64이다. // // 입력값: // i 첫번째정수  Tab을 넣었다. // j 두번째정수  Tab을 넣었다. func Average(i, j int) float64 { return float64(i + j) / 2 } 주석에 Tab이 들어있으면, 회색Box안으로 표시되요
  76. 76. 문서화 $ go install; godoc oce.org/math PACKAGE DOCUMENTATION package math import "oce.org/math" oce.org에서 제공하는 수학패키지.  빈줄이 나타났다. 2015-3-14 업데이트. FUNCTIONS func Average(i, j int) float64 평균을 구한다. 입력값은 i,j 정수를 받아들인다. 리턴값은 float64이다.  주석내 개행은 무시된다. 입력값: i 첫번째정수 j 두번째정수
  77. 77. 문서화 http://localhost:6060/pkg $ godoc -http=:6060
  78. 78. 문서화 http://localhost:6060/pkg/oce.org/math/$ godoc -http=:6060 가장 좋은 문서화예제는 Go sdk의 소스에 있어요. <GOROOT>/src/fmt/print.go <GOROOT>/src/fmt/doc.go 를 참조하세요.
  79. 79. 문서화 • Example 도 넣을수 있다. 패키지 os/exec/
  80. 80. 문서화 • 함수정의 (src/os/exec/exec.go, src/os/exec/lp_unix.go) func LookPath(file string) (string, error) { .. } func (c *Cmd) Start() error { .. } • 예제정의(src/os/exec/example_test.go) func ExampleLookPath() { path, err := exec.LookPath("fortune") if err != nil { log.Fatal("installing fortune is in your future")  이 소스가 예제항목으로 삽입된다. } fmt.Printf("fortune is available at %sn", path) } func ExampleCmd_Start() { cmd := exec.Command("sleep", "5") err := cmd.Start() if err != nil { log.Fatal(err)  이 소스가 예제항목으로 삽입된다. } log.Printf("Waiting for command to finish...") err = cmd.Wait() log.Printf("Command finished with error: %v", err) }
  81. 81. 테스트 • 테스트 함수만드는 법 – 파일이름은 _test.go로 끝난다. – 함수이름이 Test로 시작 – *testing.T를 인자로 받을것 (import “testing”) • 예제 # foo_test.go package math import "testing" func TestAverage(t *testing.T) { var v float64 v = Average([]float64{1,2}) if v != 1.5 { t.Error("Expected 1.5, got ", v) } }
  82. 82. 테스트 $ go test PASS ok oce.org/math 0.003s • 만약 파일명이 _test.go, test.go, foo_testing.go 등 파일명규칙을 따르지 않을때는 아래와 같이 테스트파일을 못찾는다. $ go test ? oce.org/math [no test files] • fmt 패키지내 파일 리스트 참고 (경로 <GOROOT>/src/fmt) doc.go export_test.go fmt_test.go format.go print.go scan.go scan_test.go stringer_test.go
  83. 83. 테스트 import "testing" type testpair struct { values []float64 average float64 } var tests = []testpair{ { []float64{1,2}, 1.5 }, { []float64{1,1,1,1,1,1}, 1 }, { []float64{-1,1}, 0 }, } func TestAverage(t *testing.T) { for _, pair := range tests { v := Average(pair.values) if v != pair.average { t.Error( "For", pair.values, "expected", pair.average, "got", v, ) } } } struct를 이용하면 여러 테스트값을 편하게 테스트해볼 수 있어요.
  84. 84. 핵심패키지
  85. 85. strings strings.Contains("test", "es") // true strings.Count("test", "t") // 2 strings.HasPrefix("test", "te") // true strings.HasSuffix("test", "st") // true strings.Index("test", "e") // 1 strings.Join([]string{"a","b"}, "-") // "a-b" strings.Repeat("a", 5) // "aaaaa" strings.Replace("aaaa", "a", "b", 2) // "bbaa" strings.Split("a-b-c-d-e", "-") // []string{"a","b","c","d","e"} strings.ToLower("TEST") // "test" strings.ToUpper("test") // "TEST” ---- arr := []byte("test") str := string([]byte{'t','e','s','t'}) 더 많은 정보는 여기있어요 https://golang.org/pkg/strings
  86. 86. io • 함수정의 보다는 대부분이 interface로 구성 • 주요 인터페이스는 Reader와 Writer • Reader는 Read(), Writer는 Write() 지원 • Reader  Writer 데이터 복사 – func Copy(dst Writer, src Reader) (written int64, err error) 더 많은 정보는 여기있어요 https://golang.org/pkg/io
  87. 87. bytes package main import ( "bytes" "fmt" "os" ) func main() { var b bytes.Buffer // 버퍼는 초기화가 필요없다. 선언후 그대로 사용. b.Write([]byte("Hello ")) fmt.Fprintf(&b, "world!") b.WriteTo(os.Stdout) } ----- func main() { // string 이나 []byte 를 io.Reader 로 바꿔준다. buf := bytes.NewBufferString("R29waGVycyBydWxlIQ==") dec := base64.NewDecoder(base64.StdEncoding, buf) io.Copy(os.Stdout, dec) } 더 많은 정보는 여기있어요 https://golang.org/pkg/bytes
  88. 88. os • 파일열기 : os.Open() • 파일닫기 : file.Close() package main import ( "fmt" "os" ) func main() { file, err := os.Open("test.txt") if err != nil { // 오류를 처리 return } defer file.Close() // 파일의 크기를 구함 stat, err := file.Stat() if err != nil { return } // 파일을 읽음 bs := make([]byte, stat.Size()) _, err = file.Read(bs) if err != nil { return } str := string(bs) fmt.Println(str) }
  89. 89. error • 오류에 대한 내장타입 • error.New() 사용시 자체오류 생성가능 package main import ( "errors" "fmt" ) func main() { err := errors.New("emit macho dwarf: elf header corrupted") if err != nil { fmt.Print(err) } } ----- func main() { const name, id = "bimmler", 17 err := fmt.Errorf("user %q (id %d) not found", name, id) if err != nil { fmt.Print(err) } }
  90. 90. container heap Package heap provides heap operations for any type that implements heap.Interface. list Package list implements a doubly linked list. ring Package ring implements operations on circular lists. package main import ( "container/list" "fmt" ) func main() { // Create a new list and put some numbers in it. l := list.New() e4 := l.PushBack(4) e1 := l.PushFront(1) l.InsertBefore(3, e4) l.InsertAfter(2, e1) // Iterate through list and print its contents. for e := l.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) } }
  91. 91. container - heap // This example demonstrates an integer heap built using the heap interface. package main import ( "container/heap" "fmt" ) // An IntHeap is a min-heap of ints. type IntHeap []int func (h IntHeap) Len() int { return len(h) } func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *IntHeap) Push(x interface{}) { // Push and Pop use pointer receivers because they modify the slice's length, // not just its contents. *h = append(*h, x.(int)) } func (h *IntHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } // This example inserts several ints into an IntHeap, checks the minimum, // and removes them in order of priority. func main() { h := &IntHeap{2, 1, 5} heap.Init(h) heap.Push(h, 3) fmt.Printf("minimum: %dn", (*h)[0]) for h.Len() > 0 { fmt.Printf("%d ", heap.Pop(h)) } }
  92. 92. sort • Sort 함수는 sort.Interface가 구현된 것만 정렬가능 • sort.Interface는 Len, Less, Swap의 3개 메서드 필요. type Interface interface { // Len is the number of elements in the collection. Len() int // Less reports whether the element with // index i should sort before the element with index j. Less(i, j int) bool // Swap swaps the elements with indexes i and j. Swap(i, j int) }
  93. 93. sort type Person struct { Name string Age int } type ByName []Person func (this ByName) Len() int { return len(this) } func (this ByName) Less(i, j int) bool { return this[i].Name < this[j].Name } func (this ByName) Swap(i, j int) { this[i], this[j] = this[j], this[i] } func main() { kids := []Person{ {"Jill",9}, {"Jack",10}, } sort.Sort(ByName(kids)) fmt.Println(kids) }
  94. 94. hash type Hash interface { // Write (via the embedded io.Writer interface) adds more data to the running hash. // It never returns an error. io.Writer // Sum appends the current hash to b and returns the resulting slice. // It does not change the underlying hash state. Sum(b []byte) []byte // Reset resets the Hash to its initial state. Reset() // Size returns the number of bytes Sum will return. Size() int // BlockSize returns the hash's underlying block size. // The Write method must be able to accept any amount // of data, but it may operate more efficiently if all writes // are a multiple of the block size. BlockSize() int } type Hash32 interface { Hash Sum32() uint32 } type Hash64 interface { Hash Sum64() uint64 }
  95. 95. hash - 비암호화 • 종류 : adler32, crc32, crc64, fnv package main import ( "fmt" "hash/crc32" ) func main() { h := crc32.NewIEEE() h.Write([]byte("test")) v := h.Sum32() fmt.Println(v) }  3632233996
  96. 96. crypto – 암호화해시 • 종류 : aes, cipher, des, dsa, ecdsa, elliptic, hmac, md5, rand, rc4, rsa, sha1, sha256, sha512, subtle, tls, 509 package main import ( "crypto/sha1" "fmt" "io" ) func main() { h := sha1.New() io.WriteString(h, "His money is twice tainted:") io.WriteString(h, " 'taint yours and 'taint mine.") fmt.Printf("% x", h.Sum(nil)) }
  97. 97. net • Go는 아래에 대해 Portable 인터페이스를 제공 – Network I/O – TCP/IP – UDP – Domain name resolution – Unix domain socket type Listener interface { // Accept waits for and returns the next connection to the listener. Accept() (c Conn, err error) // Close closes the listener. // Any blocked Accept operations will be unblocked and return errors. Close() error // Addr returns the listener's network address. Addr() Addr }
  98. 98. net //////////////////// Client 간단버전 ////////////////// conn, err := net.Dial("tcp", "google.com:80") if err != nil { // handle error } fmt.Fprintf(conn, "GET / HTTP/1.0rnrn") status, err := bufio.NewReader(conn).ReadString('n') // ... ////////////////// Server 간단버전 ////////////////// ln, err := net.Listen("tcp", ":8080") if err != nil { // handle error } for { conn, err := ln.Accept() if err != nil { // handle error } go handleConnection(conn) }
  99. 99. net ////////////// Echo 서버 //////////// package main import ( "io”; "log”; "net" ) func main() { // Listen on TCP port 2000 on all interfaces. l, err := net.Listen("tcp", ":2000") if err != nil { log.Fatal(err) } defer l.Close() for { // Wait for a connection. conn, err := l.Accept() if err != nil { log.Fatal(err) } // Handle the connection in a new goroutine. // The loop then returns to accepting, s o that // multiple connections may be served concurrently. go func(c net.Conn) { // Echo all incoming data. io.Copy(c, c) // Shut down the connection. c.Close() }(conn) } } $ telnet localhost 2000 I love Go  입력 I love Go  출력
  100. 100. net/http package main import ("net/http" ; "io") func hello(res http.ResponseWriter, req *http.Request) { res.Header().Set( "Content-Type", "text/html", ) io.WriteString( res, `<doctype html> <html> <head><title>Hello World</title></head> <body>Hello World!</body> </html>`, ) } func main() { http.HandleFunc("/hello", hello) http.ListenAndServe(":9000", nil) } http://localhost:9000/hello HandleFunc는 URL 라우팅(/hello) 처리를 담당해요
  101. 101. net/rpc package main import ( "fmt” ; "net”; "net/rpc" ) type Server struct {} func (this *Server) Negate(i int64, reply *int64) error { *reply = -i return nil } func server() { rpc.Register(new(Server)) ln, err := net.Listen("tcp", ":9999") if err != nil { fmt.Println(err) return } for { c, err := ln.Accept() if err != nil { continue } go rpc.ServeConn(c) } } func client() { c, err := rpc.Dial("tcp", "127.0.0.1:9999") if err != nil { fmt.Println(err) return } var result int64 err = c.Call("Server.Negate", int64(999), &result) if err != nil { fmt.Println(err) } else { fmt.Println("Server.Negate(999) =", result) } } func main() { go server() go client() var input string fmt.Scanln(&input) }
  102. 102. flag (명령줄 파싱) • 명령줄 플래그(-로 시작)를 flag.String(), Bool(), Int() 등을 사용하여 파싱 – flag.Int(플래그명, 기본값, 설명메시지) – flag.IntVar(입력변수주소, 플래그명, 기본값, 설명메시지) – 방법1 import "flag" var ip = flag.Int("flagname", 1234, "help message for flagname”) – 방법2 var flagvar int func init() { flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") } • 플래그가 아닌 일반파라미터는 flag.Args()를 통해 받을 수 있으며 []string 형으로 리턴된다. var args []string = flag.Args()
  103. 103. flag (명령줄 파싱) package main import ( "flag" "fmt" ) var species = flag.String("species", "gopher", "the species we are studying") var gopherType string func init() { const ( defaultGopher = "pocket" usage = "the variety of gopher" ) flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage) flag.StringVar(&gopherType, "g", defaultGopher, usage+" (shorthand)") } func main() { flag.Parse() fmt.Println("species=", *species, "ngopherType=", gopherType) var args []string = flag.Args() fmt.Println("Args=", args) }
  104. 104. flag (명령줄 파싱) $ ./hello species= gopher gopherType= pocket Args= [] $ ./hello -h Usage of ./hello: -g="pocket": the variety of gopher (shorthand) -gopher_type="pocket": the variety of gopher -species="gopher": the species we are studying $ ./hello -species=oce -g=fastcat species= oce gopherType= fastcat Args= [] $ ./hello -species=oce -gopher_type=fastcat  위 결과와 동일 species= oce gopherType= fastcat Args= [] $ ./hello -species=”oce fastcat” world war 2 species= oce fastcat gopherType= pocket Args= [world war 2]
  105. 105. sync type Cond func NewCond(l Locker) *Cond func (c *Cond) Broadcast() func (c *Cond) Signal() func (c *Cond) Wait() type Locker type Mutex func (m *Mutex) Lock() func (m *Mutex) Unlock() type Once func (o *Once) Do(f func()) type Pool func (p *Pool) Get() interface{} func (p *Pool) Put(x interface{}) type RWMutex func (rw *RWMutex) Lock() func (rw *RWMutex) RLock() func (rw *RWMutex) RLocker() Locker func (rw *RWMutex) RUnlock() func (rw *RWMutex) Unlock() type WaitGroup func (wg *WaitGroup) Add(delta int) func (wg *WaitGroup) Done() func (wg *WaitGroup) Wait() 더 많은 정보는 여기있어요 https://golang.org/pkg/sync/
  106. 106. sync/Mutex package main import ( "fmt”; "sync”; "time" ) func main() { m := new(sync.Mutex) for i := 0; i < 10; i++ { go func(i int) { m.Lock() fmt.Println(i, "start") time.Sleep(time.Second) fmt.Println(i, "end") m.Unlock() }(i) } var input string fmt.Scanln(&input) } 실행결과 0 start 0 end 1 start 1 end 2 start 2 end 3 start 3 end 4 start 4 end 5 start 5 end 6 start 6 end 7 start 7 end 8 start 8 end 9 start 9 end
  107. 107. sync/Once package main import ( "fmt”; "sync" ) func main() { var once sync.Once onceBody := func() { fmt.Println("Only once") } done := make(chan bool) for i := 0; i < 10; i++ { go func() { once.Do(onceBody) done <- true }() } for i := 0; i < 10; i++ { <-done } }  결과 : Only once
  108. 108. sync/WaitGroup var wg sync.WaitGroup var urls = []string{ "http://www.golang.org/", "http://www.google.com/", "http://www.somestupidname.com/", } for _, url := range urls { // Increment the WaitGroup counter. wg.Add(1) // Launch a goroutine to fetch the URL. go func(url string) { // Decrement the counter when the goroutine completes. defer wg.Done() // Fetch the URL. http.Get(url) }(url) } // Wait for all HTTP fetches to complete. wg.Wait()
  109. 109. Go 의 동기화 스타일 type Work struct { x, y, z int assigned, done bool } type WorkSet struct { mu sync.Mutex work []*Work } type Work struct { x, y, z int } func worker(in <-chan *Work, out chan<- *Work) { for w := range in { w.z = w.x * w.y // do some work... out <- w } } func main() { in, out := make(chan *Work), make(chan *Work) for i := 0; i < 10; i++ { go worker(in, out) } go sendLotsOfWork(in) receiveLotsOfResults(out) } 메모리공유를 통한 통신이나 공유데이터를 보호하기 위한 Lock이 필요없다. 전통적인 접근 Go 스타일
  110. 110. time 정의 : func Sleep(d Duration) 샘플 : time.Sleep(100 * time.Millisecond) 정의 : func (t Time) Sub(u Time) Duration 샘플 : t0 := time.Now() expensiveCall() t1 := time.Now() mt.Printf("The call took %v to run.n", t1.Sub(t0))  3m56s 정의 : func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time 샘플 : t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) 정의 : func (t Time) Format(layout string) string 샘플 : const layout = "Jan 2, 2006 at 3:04pm (MST)" t := time.Date(2009, time.November, 10, 15, 0, 0, 0, time.Local) fmt.Println(t.Format(layout)) 정의 : func Parse(layout, value string) (Time, error) 샘플 : const longForm = "Jan 2, 2006 at 3:04pm (MST)" t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)") Go 에는 Java의 yyyyMMdd 같은 형식이 없어요.
  111. 111. regexp 정의 : func MatchString(pattern string, s string) (matched bool, err error) 샘플 : matched, err := regexp.MatchString("foo.*", "seafood") 정의 : func MustCompile(str string) *Regexp 샘플 : var re = regexp.MustCompile(`^[a-z]+[[0-9]+]$`) 정의 : func (re *Regexp) MatchString(s string) bool 샘플 : fmt.Println(re.MatchString("adam[23]")) 정의 : func (re *Regexp) FindAllString(s string, n int) []string 샘플 : fmt.Println(re.FindAllString("paranormal", -1)) 정의 : func (re *Regexp) ReplaceAllString(src, repl string) string 샘플 : fmt.Println(re.ReplaceAllString("-ab-axxb-", "T"))
  112. 112. database age := 27 rows, err := db.Query("SELECT name FROM users WHERE age=?", age) if err != nil { log.Fatal(err) } defer rows.Close() for rows.Next() { var name string if err := rows.Scan(&name); err != nil { log.Fatal(err) } fmt.Printf("%s is %dn", name, age) } if err := rows.Err(); err != nil { log.Fatal(err) } https://github.com/golang/go/wiki/SQLDrivers
  113. 113. database - drivers • MySQL: https://github.com/ziutek/mymysql [*] • MySQL: https://github.com/go-sql-driver/mysql/ [*] • Postgres (pure Go): https://github.com/lib/pq [*] • Oracle: https://github.com/mattn/go-oci8 • MS SQL Server (pure go): https://github.com/denisenkom/go-mssqldb 그 외의 드라이버는 여기를 참조하세요. https://github.com/golang/go/wiki/SQLDrivers
  114. 114. database - mysql package main import ( "os" "github.com/ziutek/mymysql/mysql" _ "github.com/ziutek/mymysql/native" // Native engine // _ "github.com/ziutek/mymysql/thrsafe" // Thread safe engine ) func main() { db := mysql.New("tcp", "", "127.0.0.1:3306", user, pass, dbname) err := db.Connect() if err != nil { panic(err) } rows, res, err := db.Query("select * from X where id > %d", 20) if err != nil { panic(err) } https://github.com/ziutek/mymysql for _, row := range rows { for _, col := range row { if col == nil { // col has NULL value } else { // Do something with text in col (type []byte) } } // You can get specific value from a row val1 := row[1].([]byte) // You can use it directly if conversion isn't needed os.Stdout.Write(val1) // You can get converted value number := row.Int(0) // Zero value str := row.Str(1) // First value bignum := row.MustUint(2) // Second value // You may get values by column name first := res.Map("FirstColumn") second := res.Map("SecondColumn") val1, val2 := row.Int(first), row.Str(second) } }
  115. 115. log package main import ( "bytes" "fmt" "log" ) func main() { var buf bytes.Buffer logger := log.New(&buf, "logger: ", log.Lshortfile) logger.Print("Hello, log file!") fmt.Print(&buf) }  logger: main.go:12: Hello, log file!
  116. 116. log - level • 로그레벨에 따라 로깅하는 패키지는 기본 SDK에 없다. • https://github.com/jcelliott/lumber • 콘솔로거 log := lumber.NewConsoleLogger(lumber.WARN) • 파일로거 log := lumber.NewFileLogger("filename.log", lumber.INFO, lumber.ROTATE, 5000, 9, 100) • 파일로거 (rotate) log := lumber.NewRotateLogger("filename.log", 5000, 9) • 사용법 log.Trace("the %s log level", "lowest") log.Debug("") log.Info("the default log level") log.Warn("") log.Error("") log.Fatal("the %s log level", "highest") • 로그앞에 prefix 붙이기 log.Prefix("MYAPP")
  117. 117. 끝 수고하셨어요~♥

×