├── packages
├── os
│ ├── sample.txt
│ ├── exec
│ │ ├── 00_오버뷰.go
│ │ └── 01_Command예제.go
│ ├── 01_텍스트파일읽기.go
│ └── 00_오버뷰.go
├── fmt
│ ├── 01_문자열값받기_Scan.go
│ └── 00_오버뷰.go
├── time
│ ├── 00_오버뷰.go
│ └── 01_Example.go
├── net
│ ├── http
│ │ ├── 01_파일서버.go
│ │ ├── 03_Get.go
│ │ ├── 02_하이재커.go
│ │ ├── GetJava.java
│ │ └── 00_오버뷰.go
│ ├── 02_godoc예제.go
│ ├── 01_TCP서버.go
│ └── 00_오버뷰.go
├── strconv
│ └── 00_오버뷰.go
└── reflect
│ └── 01_겟셋값해보기.go
├── effectivego
├── 02_주석.go
├── 03_명칭
│ ├── 03_interface이름들.go
│ ├── 02_Getters.go
│ └── 01_패키지네임.go
├── 07_데이터
│ ├── 04_배열.go
│ ├── 08_덧붙임append.go
│ ├── 01_new를사용한데이터할당.go
│ ├── 03_make를사용한메모리할당.go
│ ├── 02_생성자와복합문장.go
│ ├── 05_슬라이스.go
│ ├── 06_맵스.go
│ └── 07_출력.go
├── 06_함수
│ ├── 02_명명된파라미터값.go
│ ├── 01_다중리턴값.go
│ └── 03_Defer.go
├── 01_형식화하기.go
├── 04_세미콜론.go
├── 09_메소드.go
├── 08_초기화.go
└── 05_제어구조.go
├── gotour
├── 01_헬로월드.go
├── 11_변수.go
├── 05_임포트.go
├── 26_구조체필드.go
├── 04_패키지.go
├── 06_익스포트.go
├── 25_구조체.go
├── 16_반복문.go
├── 17_반복문For2.go
├── 12_변수의초기화.go
├── 34_레인지.go
├── 09_여러개의결과.go
├── 13_변수의짧은선언.go
├── 08_함수2.go
├── 30_슬라이스.go
├── 27_포인터.go
├── 07_함수.go
├── 29_new함수.go
├── 42_함수값.go
├── 10_이름이정해진결과.go
├── 14_상수.go
├── 20_조건문if.go
├── 33_빈슬라이스.go
├── 38_맵리터럴.go
├── 44_연습_피보나치.go
├── 22_IF와ELSE.go
├── 37_맵.go
├── 65_버퍼링되는채널.go
├── 48_심화연습_복소수세제곱근.go
├── 21_IF와짧은명령문.go
├── 41_연습_맵.go
├── 50_메소드.go
├── 51_메소드2.go
├── 47_조건을생략한스위치.go
├── 40_맵리터럴2.go
├── 31_슬라이스자르기.go
├── 43_함수클로저.go
├── 15_숫자형상수.go
├── 28_구조체리터럴.go
├── 35_레인지2.go
├── 45_스위치.go
├── 36_연습_슬라이스.go
├── 58_연습_HTTP핸들러.go
├── 60_연습_이미지.go
├── 46_스위치동작순서.go
├── 59_이미지.go
├── 68_셀렉트의디폴트케이스.go
├── 57_웹서버.go
├── 24_기본자료형.go
├── 67_셀렉트.go
├── 63_고루틴.go
├── 32_슬라이스만들기.go
├── 61_연습Rot13Reader.go
├── 23_연습_루프와함수.go
├── 55_에러.go
├── 39_맵다루기.go
├── 64_채널.go
├── 54_인터페이스의암시적충족.go
├── 53_인터페이스.go
├── 56_연습_에러.go
├── 66_Range와Close.go
├── 52_포인터리시버를가지는메소드.go
├── 70_연습_동등한이진트리.go
└── 71_웹크롤러.go
├── gobyexample
├── 01_헬로월드.go
├── 16_재귀.go
├── 02_값.go
├── 12_함수.go
├── 65_Exit.go
├── 05_For문.go
├── 03_변수들.go
├── 04_상수.go
├── 23_채널.go
├── 31_레인지채널.go
├── 13_다중리턴값.go
├── 24_채널버퍼링.go
├── 06_If_Else문.go
├── 59_커맨드라인아규먼트.go
├── 25_채널동기화.go
├── 26_채널방향.go
├── 14_가변인자함수.go
├── 33_티커.go
├── 39_정렬.go
├── 08_배열들.go
├── 61_환경변수.go
├── 27_셀렉트.go
├── 07_스위치.go
├── 19_메소드.go
├── 22_Go루틴.go
├── 54_Sha1해쉬.go
├── 17_포인터.go
├── 32_타이머.go
├── 41_패닉.go
├── 52_숫자파싱.go
├── 18_구조체.go
├── 10_맵.go
├── 15_클로저.go
├── 11_레인지.go
├── 49_Epoch.go
├── 42_디퍼.go
├── 36_아토믹카운터.go
├── 55_Base64인코딩.go
├── 34_워커풀.go
├── 29_논블록킹채널운영.go
├── 28_타임아웃.go
├── 57_파일쓰기.go
├── 30_채널닫기.go
├── 53_Url파싱.go
├── 44_문자열함수.go
├── 40_Function정렬.go
├── 48_시간.go
├── 51_랜덤숫자.go
├── 20_인터페이스.go
├── 58_라인필터.go
├── 50_시간형식화.go
├── 60_커맨드라인플래그.go
├── 64_시그널.go
├── 09_슬라이스.go
├── 35_RateLimiting.go
├── 56_파일읽기.go
├── 63_프로세스실행.go
├── 37_뮤텍스.go
├── 46_정규식표현.go
├── 21_에러.go
├── 45_문자열포맷팅.go
├── 43_콜렉션펑션.go
├── 62_프로세스생성.go
├── 38_Stateful고루틴들.Go.go
└── 47_JSON.go
└── README.md
/packages/os/sample.txt:
--------------------------------------------------------------------------------
1 | Hello Go os package
2 | 한글도 잘 되나요?^^
--------------------------------------------------------------------------------
/packages/fmt/01_문자열값받기_Scan.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("문자열을 입력하시오")
7 | var input string
8 | fmt.Scanln(&input)
9 | fmt.Println(input)
10 | }
11 |
--------------------------------------------------------------------------------
/effectivego/02_주석.go:
--------------------------------------------------------------------------------
1 | // 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo#주석(Commentary)
2 | // 원글을 봐도... 무슨 내용인지 잘 모르겠군요 ㅠㅠ.;
3 |
4 | package main
5 |
6 | import (
7 | "fmt"
8 | )
9 |
10 | func main() {
11 | fmt.Println("Hello World!")
12 | }
13 |
--------------------------------------------------------------------------------
/packages/time/00_오버뷰.go:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | 타임 패키지는 시간을 측정하고 보여주기 위한 기능을 제공한다.
4 |
5 | 달력에 관한 계산은 언제나 그레고리안 달력을 가정한다.
6 |
7 | Package time provides functionality for measuring and displaying time.
8 |
9 | The calendrical calculations always assume a Gregorian calendar.
10 |
11 | */
--------------------------------------------------------------------------------
/gotour/01_헬로월드.go:
--------------------------------------------------------------------------------
1 | //헬로월드를 간단히 띄움.
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 |
8 | fmt.Println("Hello, 안녕")
9 | }
10 |
11 | /*
12 | 정리내용 : 헬로월드에 관한 것. fmt.Println
13 |
14 | Written by arahansa
15 | https://www.facebook.com/groups/golangko/
16 | 모든 내용은 http://go-tour-kr.appspot.com/
17 | */
18 |
--------------------------------------------------------------------------------
/packages/os/exec/00_오버뷰.go:
--------------------------------------------------------------------------------
1 | // exec 패키지는 외부 커맨트를 실행시킨다.
2 | // 이것은 os.StartProcess를 포장해서 stdin 과 stdour를 remap하기, pipe로 I/O에 접속하기 그리고 다른 수정등을 하기 쉽게 해준다.
3 | //
4 |
5 | //Package exec runs external commands. It wraps os.StartProcess to make it easier to remap stdin and stdout,
6 | //connect I/O with pipes, and do other adjustments.
--------------------------------------------------------------------------------
/packages/os/exec/01_Command예제.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "os/exec"
7 | )
8 |
9 | func main() {
10 | //out, err := exec.Command("cmd", "/C", "dir").Output()
11 | out, err := exec.Command("date").Output()
12 | if err != nil {
13 | log.Fatal(err)
14 | }
15 | fmt.Printf("The date is %s\n", out)
16 | }
17 |
--------------------------------------------------------------------------------
/gobyexample/01_헬로월드.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/hello-world
4 |
5 | Go by Example: Hello World
6 | */
7 |
8 | package main
9 |
10 | import "fmt"
11 |
12 | func main() {
13 | fmt.Println("hello world")
14 | }
15 |
16 | /*
17 |
18 | 실행시키기위해서는 go run 파일명.go 를 한다.
19 | 빌드를 할때는 go build를 하면 된다.
20 |
21 | 자세한 설명은 이제 생략 ^^
22 |
23 | */
24 |
--------------------------------------------------------------------------------
/gotour/11_변수.go:
--------------------------------------------------------------------------------
1 | // 변수선언해보기
2 | package main
3 |
4 | import "fmt"
5 |
6 | var x, y, z int
7 | var c, python, java bool
8 |
9 | func main() {
10 | fmt.Println(x, y, z, c, python, java)
11 | }
12 |
13 | /*
14 | 내용 : 변수 선언은 var를 통한다. 타입을 뒤에 적는다.
15 |
16 | Written by arahansa
17 | https://www.facebook.com/groups/golangko/
18 | 모든 내용은 http://go-tour-kr.appspot.com/
19 | */
20 |
--------------------------------------------------------------------------------
/packages/net/http/01_파일서버.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 | )
7 |
8 | func main() {
9 | // Simple static webserver:
10 | //log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))))
11 | //윈도우환경에서 하고 싶다면 다음으로 실행하면 된다:역주
12 | log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("c:/go"))))
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/gotour/05_임포트.go:
--------------------------------------------------------------------------------
1 | // 임포트 하는 방법
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | func main() {
10 | fmt.Printf("Now you have %g problems.",
11 | math.Nextafter(2, 3))
12 | }
13 |
14 | /*
15 | 내용 : 여러 개의 package를 소괄호로 감싸서 임포트로 표현함을 보자.
16 | Written by arahansa
17 | https://www.facebook.com/groups/golangko/
18 | 모든 내용은 http://go-tour-kr.appspot.com/
19 | */
20 |
--------------------------------------------------------------------------------
/gotour/26_구조체필드.go:
--------------------------------------------------------------------------------
1 | // 26_구조체필드
2 | package main
3 |
4 | import "fmt"
5 |
6 | type Vertex struct {
7 | X int
8 | Y int
9 | }
10 |
11 | func main() {
12 | v := Vertex{1, 2}
13 | v.X = 4
14 | fmt.Println(v.X)
15 | }
16 |
17 | /*
18 | 구조체 필드는 . 으로 접근한다.
19 |
20 | Written by arahansa
21 | https://www.facebook.com/groups/golangko/
22 | 모든 내용은 http://go-tour-kr.appspot.com/
23 | */
24 |
--------------------------------------------------------------------------------
/gotour/04_패키지.go:
--------------------------------------------------------------------------------
1 | //패키지 정보를 보는 법
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | func main() {
10 | fmt.Println("Happy", math.Pi, "Day")
11 | }
12 |
13 | /*
14 | 내용 : 패키지 이름은 디렉토리의 마지막 이름을 사용
15 | path/filepath 를 사용하면 path가 패키지 명이다.
16 |
17 | Written by arahansa
18 | https://www.facebook.com/groups/golangko/
19 | 모든 내용은 http://go-tour-kr.appspot.com/
20 | */
21 |
--------------------------------------------------------------------------------
/gotour/06_익스포트.go:
--------------------------------------------------------------------------------
1 | // 대문자를 써야 외부참조 가능!! 주의
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | func main() {
10 | fmt.Println(math.pi)
11 | //fmt.Println(math.Pi)
12 | }
13 |
14 | /*
15 | 내용 : pi를 Pi 로 변경해야 한다. 외부참조시에 대문자로 쓰여져 exported 된 것들만 접근 가능하다.
16 | Written by arahansa
17 | https://www.facebook.com/groups/golangko/
18 | 모든 내용은 http://go-tour-kr.appspot.com/
19 | */
20 |
--------------------------------------------------------------------------------
/gotour/25_구조체.go:
--------------------------------------------------------------------------------
1 | // 25_구조체
2 | package main
3 |
4 | import "fmt"
5 |
6 | type Vertex struct {
7 | X int
8 | Y int
9 | }
10 |
11 | func main() {
12 | fmt.Println(Vertex{1, 2})
13 | }
14 |
15 | /*
16 | 구조체는 필드와 데이터들의 조합이다.
17 | type 선언으로 struct 의 이름을 정할수 있다.
18 |
19 | Written by arahansa
20 | https://www.facebook.com/groups/golangko/
21 | 모든 내용은 http://go-tour-kr.appspot.com/
22 | */
23 |
--------------------------------------------------------------------------------
/gotour/16_반복문.go:
--------------------------------------------------------------------------------
1 | // 16_반복문
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | sum := 0
8 | for i := 0; i < 10; i++ {
9 | sum += i
10 | }
11 | fmt.Println(sum)
12 | }
13 |
14 | /*
15 | 내용 : Go 에서는 반복문이 For 밖에 없다.
16 | 하지만 소괄호() 가 필요없고 중괄호는 무조건 필요 {}
17 |
18 | Written by arahansa
19 | https://www.facebook.com/groups/golangko/
20 | 모든 내용은 http://go-tour-kr.appspot.com/
21 | */
22 |
--------------------------------------------------------------------------------
/gotour/17_반복문For2.go:
--------------------------------------------------------------------------------
1 | // 17_For2
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | sum := 1
8 | for sum < 1000 {
9 | sum += sum
10 | }
11 | fmt.Println(sum)
12 |
13 | }
14 |
15 | /*
16 |
17 | 전후처리를 제외하고 조건문만 표현할 수도 있다.
18 | 무한루프는 그냥 for {} 로 표시.
19 |
20 | Written by arahansa
21 | https://www.facebook.com/groups/golangko/
22 | 모든 내용은 http://go-tour-kr.appspot.com/
23 | */
24 |
--------------------------------------------------------------------------------
/gotour/12_변수의초기화.go:
--------------------------------------------------------------------------------
1 | // 12_변수의초기화
2 | package main
3 |
4 | import "fmt"
5 |
6 | var x, y, z int = 1, 2, 3
7 | var c, python, java = true, false, "no!"
8 |
9 | func main() {
10 | fmt.Println(x, y, z, c, python, java)
11 | }
12 |
13 | /*
14 | 내용 : 초기화 선언을 하면서 타입을 생략할 수 있으며, 초기화값에 따라타입 결정됩니다.
15 |
16 | Written by arahansa
17 | https://www.facebook.com/groups/golangko/
18 | 모든 내용은 http://go-tour-kr.appspot.com/
19 | */
20 |
--------------------------------------------------------------------------------
/gotour/34_레인지.go:
--------------------------------------------------------------------------------
1 | // 34_레인지
2 | package main
3 |
4 | import "fmt"
5 |
6 | var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
7 |
8 | func main() {
9 | for i, v := range pow {
10 | fmt.Printf("2**%d = %d\n", i, v)
11 | }
12 | }
13 |
14 | /*
15 | for 반복문에서 range 를 사용하면 슬라이스나 맵을 순회(iterates)할 수 있다.
16 |
17 | Written by arahansa
18 | https://www.facebook.com/groups/golangko/
19 | 모든 내용은 http://go-tour-kr.appspot.com/
20 | */
21 |
--------------------------------------------------------------------------------
/gotour/09_여러개의결과.go:
--------------------------------------------------------------------------------
1 | // 09_여러개의결과.go
2 | package main
3 |
4 | import "fmt"
5 |
6 | func swap(x, y string) (string, string) {
7 | return y, x
8 | }
9 |
10 | func main() {
11 | a, b := swap("hello", "world")
12 | fmt.Println(a, b)
13 | }
14 |
15 | /*
16 | 내용 : 하나의 함수가 다중리턴이 가능한데, 여기선 두개의 문자열 순서를 바꿔서 리턴함.
17 |
18 | Written by arahansa
19 | https://www.facebook.com/groups/golangko/
20 | 모든 내용은 http://go-tour-kr.appspot.com/
21 | */
22 |
--------------------------------------------------------------------------------
/gotour/13_변수의짧은선언.go:
--------------------------------------------------------------------------------
1 | // 13_변수의짧은선언 := 로 바로 선언함.
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | var x, y, z int = 1, 2, 3
8 | c, python, java := true, false, "no!"
9 |
10 | fmt.Println(x, y, z, c, python, java)
11 | }
12 |
13 | /*
14 | := 를 선언하면 var와 타입생략가능하다 ! 로컬변수 정도에 쓰기좋다.
15 | 함수밖에서는 := 불가.
16 |
17 | Written by arahansa
18 | https://www.facebook.com/groups/golangko/
19 | 모든 내용은 http://go-tour-kr.appspot.com/
20 | */
21 |
--------------------------------------------------------------------------------
/gobyexample/16_재귀.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/recursion
4 |
5 | Go by Example: Recursion
6 |
7 | Go는 재귀함수를 지원하며 여기 잘 알려진 팩토리얼 예제를 보여주겠다~
8 | */
9 | package main
10 |
11 | import "fmt"
12 |
13 | // 이 fact function은 func(0)d이 될때까지 자기 자신을 호출한다.
14 | func fact(n int) int {
15 | if n == 0 {
16 | return 1
17 | }
18 | return n * fact(n-1)
19 | }
20 |
21 | func main() {
22 | fmt.Println(fact(7))
23 | }
24 |
--------------------------------------------------------------------------------
/gotour/08_함수2.go:
--------------------------------------------------------------------------------
1 | // 메서드 타입정하는 것
2 | package main
3 |
4 | import "fmt"
5 |
6 | func add(x, y int) int {
7 | return x + y
8 | }
9 |
10 | func main() {
11 | fmt.Println(add(42, 13))
12 | }
13 |
14 | /*
15 | 내용 : 두개 이상의 매개변수가 같은 타입일 때(type) 같은 타입을 취하는 마지막 매개변수만 타입 명시하고 생략 가능하다.
16 | 예를 들어서 x int, y int 를 x, y int 로 생략가능하다.
17 |
18 | Written by arahansa
19 | https://www.facebook.com/groups/golangko/
20 | 모든 내용은 http://go-tour-kr.appspot.com/
21 | */
22 |
--------------------------------------------------------------------------------
/gotour/30_슬라이스.go:
--------------------------------------------------------------------------------
1 | // 30_슬라이스
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | p := []int{2, 3, 5, 7, 11, 13}
8 | fmt.Println("p ==", p)
9 |
10 | for i := 0; i < len(p); i++ {
11 | fmt.Printf("p[%d] == %d\n",
12 | i, p[i])
13 | }
14 | }
15 |
16 | /*
17 | 슬라이스는 배열의 값을 가리킴. 배열의 길이를 가짐.
18 | []T 는 T를 가지는 요소의 슬라이스이다.
19 |
20 | Written by arahansa
21 | https://www.facebook.com/groups/golangko/
22 | 모든 내용은 http://go-tour-kr.appspot.com/
23 | */
24 |
--------------------------------------------------------------------------------
/gotour/27_포인터.go:
--------------------------------------------------------------------------------
1 | // 27_포인터
2 | package main
3 |
4 | import "fmt"
5 |
6 | type Vertex struct {
7 | X int
8 | Y int
9 | }
10 |
11 | func main() {
12 | p := Vertex{1, 2}
13 | q := &p
14 | q.X = 1e9
15 | fmt.Println(p)
16 | }
17 |
18 | /*
19 | Go에는 포인터가 있지만 포인터 연산은 불가
20 | 구조체 변수는 구조체 포인터를 이용해 접근 가능.
21 | 포인터를 이용하는 간접적 접근은 실제 구조체에도 영향을 미침
22 |
23 | Written by arahansa
24 | https://www.facebook.com/groups/golangko/
25 | 모든 내용은 http://go-tour-kr.appspot.com/
26 | */
27 |
--------------------------------------------------------------------------------
/gotour/07_함수.go:
--------------------------------------------------------------------------------
1 | // 메서드 만들기
2 | package main
3 |
4 | import "fmt"
5 |
6 | func add(x int, y int) int {
7 | return x + y
8 | }
9 |
10 | func main() {
11 | fmt.Println(add(42, 13))
12 | }
13 |
14 | /*
15 | 내용 : 함수를 설명하는데 매개변수가 뒤에 감을 의식하자.
16 | 바로 이곳 : add(x int, y int) int
17 | 왜 그런지 궁금하면 http://blog.golang.org/gos-declaration-syntax 이곳을 참조하자.
18 |
19 | Written by arahansa
20 | https://www.facebook.com/groups/golangko/
21 | 모든 내용은 http://go-tour-kr.appspot.com/
22 | */
23 |
--------------------------------------------------------------------------------
/gotour/29_new함수.go:
--------------------------------------------------------------------------------
1 | // 29_new함수 : 모든필드가 0이 할당된 T의 반환
2 | package main
3 |
4 | import "fmt"
5 |
6 | type Vertex struct {
7 | X, Y int
8 | }
9 |
10 | func main() {
11 | v := new(Vertex)
12 | fmt.Println(v)
13 | v.X, v.Y = 11, 9
14 | fmt.Println(v)
15 | }
16 |
17 | /*
18 | new 는 모든 필드가 0이 할당된 T타입의 포인터를 반환함.
19 | var t *T = new(T) 또는 t := new(T)
20 |
21 | Written by arahansa
22 | https://www.facebook.com/groups/golangko/
23 | 모든 내용은 http://go-tour-kr.appspot.com/
24 | */
25 |
--------------------------------------------------------------------------------
/gotour/42_함수값.go:
--------------------------------------------------------------------------------
1 | // 42_함수값
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | func main() {
10 | hypot := func(x, y float64) float64 {
11 | return math.Sqrt(x*x + y*y)
12 | }
13 |
14 | fmt.Println(hypot(3, 4))
15 | }
16 |
17 | /*
18 | 함수도 값 입니다.
19 | (번역자 : 맨 아래 hypot(3,4) 의 hypot 함수를 Println함수의 인자값 처럼 사용 하고 있습니다.)
20 |
21 |
22 | Written by arahansa
23 | https://www.facebook.com/groups/golangko/
24 | 모든 내용은 http://go-tour-kr.appspot.com/
25 | */
26 |
--------------------------------------------------------------------------------
/gobyexample/02_값.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/values
4 |
5 | Go by Example: Values
6 | */
7 | package main
8 |
9 | import "fmt"
10 |
11 | func main() {
12 |
13 | // 문자열은 + 로 연결될 수 있다. 이건 자바와 비슷하군?!
14 | fmt.Println("go" + "lang")
15 |
16 | // 숫자와 소수들
17 | fmt.Println("1+1 =", 1+1)
18 | fmt.Println("7.0/3.0 =", 7.0/3.0)
19 |
20 | // 참거짓 연산자들.
21 | fmt.Println(true && false)
22 | fmt.Println(true || false)
23 | fmt.Println(!true)
24 | }
25 |
--------------------------------------------------------------------------------
/gotour/10_이름이정해진결과.go:
--------------------------------------------------------------------------------
1 | // RETURN 시 반환 안 정해주게도함.
2 | package main
3 |
4 | import "fmt"
5 |
6 | func split(sum int) (x, y int) {
7 | x = sum * 4 / 9
8 | y = sum - x
9 | return
10 | }
11 |
12 | func main() {
13 | fmt.Println(split(17))
14 | }
15 |
16 | /*
17 | 내용 : 함수는 매개변수를 취하는데, 리턴할 이름을 정해주면 알아서 반환한다..이 말임.
18 | 잘 볼 곳 : return 만 적었는데 반환값이 x, y int 이므로 x,y 를 알아서 리턴함.
19 |
20 | Written by arahansa
21 | https://www.facebook.com/groups/golangko/
22 | 모든 내용은 http://go-tour-kr.appspot.com/
23 | */
24 |
--------------------------------------------------------------------------------
/gotour/14_상수.go:
--------------------------------------------------------------------------------
1 | // 14_상수 선언
2 | package main
3 |
4 | import "fmt"
5 |
6 | const Pi = 3.14
7 |
8 | func main() {
9 | const World = "안녕"
10 | fmt.Println("Hello", World)
11 | fmt.Println("Happy", Pi, "Day")
12 |
13 | const Truth = true
14 | fmt.Println("Go rules?", Truth)
15 | }
16 |
17 | /*
18 | 상수는 const 키워드와 함께 변수처럼 선언가능하다.
19 | 상수는 character, string, boolean, 숫자타입중의 하나 가능하다
20 | Written by arahansa
21 | https://www.facebook.com/groups/golangko/
22 | 모든 내용은 http://go-tour-kr.appspot.com/
23 | */
24 |
--------------------------------------------------------------------------------
/gotour/20_조건문if.go:
--------------------------------------------------------------------------------
1 | // 20_조건문if
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | func sqrt(x float64) string {
10 | if x < 0 {
11 | return sqrt(-x) + "i"
12 | }
13 | return fmt.Sprint(math.Sqrt(x))
14 | }
15 |
16 | func main() {
17 | fmt.Println(sqrt(2), sqrt(-4))
18 | }
19 |
20 | /*
21 | 내용 : if문은 C와 java와 비슷하지만 조건표현을 위한 ( ) 생략.
22 | 실행문을 위한 {} 는 작성.
23 |
24 | Written by arahansa
25 | https://www.facebook.com/groups/golangko/
26 | 모든 내용은 http://go-tour-kr.appspot.com/
27 | */
28 |
--------------------------------------------------------------------------------
/gotour/33_빈슬라이스.go:
--------------------------------------------------------------------------------
1 | // 33_빈슬라이스
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | var z []int
8 | fmt.Println(z, len(z), cap(z))
9 | if z == nil {
10 | fmt.Println("nil!")
11 | }
12 | }
13 |
14 | /*
15 | 슬라이스의 zero value는 nil 입니다.
16 |
17 | nil 슬라이스는 길이와 최대 크기가 0입니다.
18 |
19 | (슬라이스에 대해 더 알고 싶다면 다음 글을 읽어보세요.)
20 | http://golang.org/doc/articles/slices_usage_and_internals.html
21 |
22 |
23 | Written by arahansa
24 | https://www.facebook.com/groups/golangko/
25 | 모든 내용은 http://go-tour-kr.appspot.com/
26 | */
27 |
--------------------------------------------------------------------------------
/gotour/38_맵리터럴.go:
--------------------------------------------------------------------------------
1 | // 37_맵리터럴
2 | package main
3 |
4 | import "fmt"
5 |
6 | type Vertex struct {
7 | Lat, Long float64
8 | }
9 |
10 | var m = map[string]Vertex{
11 | "Bell Labs": Vertex{
12 | 40.68433, -74.39967,
13 | },
14 | "Google": Vertex{
15 | 37.42202, -122.08408,
16 | },
17 | }
18 |
19 | func main() {
20 | fmt.Println(m)
21 | }
22 |
23 | /*
24 | 맵 리터럴은 구조체 리터럴과 비슷하지만 key 를 반드시 지정해야 합니다.
25 |
26 |
27 | Written by arahansa
28 | https://www.facebook.com/groups/golangko/
29 | 모든 내용은 http://go-tour-kr.appspot.com/
30 | */
31 |
--------------------------------------------------------------------------------
/gobyexample/12_함수.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/functions
4 |
5 | Go by Example: Functions
6 | _Functions_ 은 Go의 중심이다. . 몇가지 예제와 함께 function을 알아보자.
7 | */
8 | package main
9 |
10 | import "fmt"
11 |
12 | // 여기 두개의 int를 받아서 합계를 int로 돌려주는 예제가 있다.
13 | func plus(a int, b int) int {
14 |
15 | // Go 분명한 리턴을 필요로 한다.
16 | //다시말하자면 자동으로 표현식의 마지막값을 리턴하지 않는다.
17 | return a + b
18 | }
19 |
20 | func main() {
21 | res := plus(1, 2)
22 | fmt.Println("1+2 =", res)
23 | }
24 |
25 | // todo: coalesced parameter types
26 |
--------------------------------------------------------------------------------
/gotour/44_연습_피보나치.go:
--------------------------------------------------------------------------------
1 | // 44_연습_피보나치
2 | package main
3 |
4 | import "fmt"
5 |
6 | // fibonacci is a function that returns
7 | // a function that returns an int.
8 | func fibonacci() func() int {
9 | }
10 |
11 | func main() {
12 | f := fibonacci()
13 | for i := 0; i < 10; i++ {
14 | fmt.Println(f())
15 | }
16 | }
17 |
18 | /*
19 | 함수를 가지고 놀아봅시다.
20 |
21 | fibonacci 함수를 구현합니다. 이 함수는 이어지는 피보나치 수를 반환하는 함수 (클로져)를 반환해야 합니다.
22 |
23 |
24 | Written by arahansa
25 | https://www.facebook.com/groups/golangko/
26 | 모든 내용은 http://go-tour-kr.appspot.com/
27 | */
28 |
--------------------------------------------------------------------------------
/gobyexample/65_Exit.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/exit
4 | Go by Example: exit
5 |
6 | os.Exit는 주어진 상황(status)과 함께 즉시 종료된다
7 | */
8 |
9 | package main
10 |
11 | import "fmt"
12 | import "os"
13 |
14 | func main() {
15 |
16 | // 'defer'는 os.Exit를 사용할 때 실행되지 않을 것이다.
17 | //그러므로 이 'fmt.Println'은 절대 호출되지 않을 것이다.
18 | defer fmt.Println("!")
19 |
20 | // status3과 함께 종료된다.
21 | os.Exit(3)
22 | }
23 |
24 | // C와는 달리 Go는 main에서 exit status를 가리키기 위해 정수리턴값을 사용하지 않는다.
25 | // 만약 제로값이 아닌 status를 사용하면서 종료 하고 싶다면 os.Exit를 사용해야 한다.
26 |
--------------------------------------------------------------------------------
/gotour/22_IF와ELSE.go:
--------------------------------------------------------------------------------
1 | // 22_IF와ELSE
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | func pow(x, n, lim float64) float64 {
10 | if v := math.Pow(x, n); v < lim {
11 | return v
12 | } else {
13 | fmt.Printf("%g >= %g\n", v, lim)
14 | }
15 | // can't use v here, though
16 | return lim
17 | }
18 |
19 | func main() {
20 | fmt.Println(
21 | pow(3, 2, 10),
22 | pow(3, 3, 20),
23 | )
24 | }
25 |
26 | /*
27 |
28 |
29 | Written by arahansa
30 | https://www.facebook.com/groups/golangko/
31 | 모든 내용은 http://go-tour-kr.appspot.com/
32 | */
33 |
--------------------------------------------------------------------------------
/gotour/37_맵.go:
--------------------------------------------------------------------------------
1 | // 37_맵
2 | package main
3 |
4 | import "fmt"
5 |
6 | type Vertex struct {
7 | Lat, Long float64
8 | }
9 |
10 | var m map[string]Vertex
11 |
12 | func main() {
13 | m = make(map[string]Vertex)
14 | m["Bell Labs"] = Vertex{
15 | 40.68433, -74.39967,
16 | }
17 | fmt.Println(m["Bell Labs"])
18 | }
19 |
20 | /*
21 | 맵은 값에 키를 지정합니다.
22 | 맵은 반드시 사용하기 전에 make 를 명시해야합니다. (주의: new 가 아닙니다)
23 | make 를 수행하지 않은 nil 에는 값을 할당할 수 없습니다.
24 |
25 | Written by arahansa
26 | https://www.facebook.com/groups/golangko/
27 | 모든 내용은 http://go-tour-kr.appspot.com/
28 | */
29 |
--------------------------------------------------------------------------------
/gotour/65_버퍼링되는채널.go:
--------------------------------------------------------------------------------
1 | // 65_버퍼링되는채널
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | c := make(chan int, 2)
8 | c <- 1
9 | c <- 2
10 | fmt.Println(<-c)
11 | fmt.Println(<-c)
12 | }
13 |
14 | /*
15 | 채널은 _버퍼링_될 수 있습니다. make 에 두번째 인자로 버퍼 용량을 넣음으로써
16 | 해당 용량만큼 버퍼링되는 채널을 생성할 수 있습니다:
17 |
18 | ch := make(chan int, 100)
19 | 버퍼링되는 채널로의 송신은 버퍼가 꽉 찰 때까지 블록됩니다. 수신측은 버퍼가 빌 때 블록됩니다.
20 |
21 | 예제를 수정해서 버퍼를 넘치게 해보고 어떻게 동작하는지 확인해 보세요.
22 |
23 |
24 | Written by arahansa
25 | https://www.facebook.com/groups/golangko/
26 | 모든 내용은 http://go-tour-kr.appspot.com/
27 | */
28 |
--------------------------------------------------------------------------------
/gotour/48_심화연습_복소수세제곱근.go:
--------------------------------------------------------------------------------
1 | // 48_심화연습_복소수세제곱근
2 | package main
3 |
4 | import "fmt"
5 |
6 | func Cbrt(x complex128) complex128 {
7 | }
8 |
9 | func main() {
10 | fmt.Println(Cbrt(2))
11 | }
12 |
13 | /*
14 | complex64 타입과 complex128 타입을 통해서 Go 언어의 복소수 지원 기능을 알아봅니다. 세제곱근을 얻기 위해서는, 뉴턴의 방법 (Newton's method)을 적용하여 다음을 반복 수행합니다:
15 |
16 | z = z - (z * z * z - x) / (3 * z * z)
17 |
18 | 알고리즘이 잘 동작하는지 확인하기 위해 2의 세제곱근을 구해봅시다. math/cmplx 패키지에는 Pow 함수가 있습니다.
19 |
20 | Written by arahansa
21 | https://www.facebook.com/groups/golangko/
22 | 모든 내용은 http://go-tour-kr.appspot.com/
23 | */
24 |
--------------------------------------------------------------------------------
/gotour/21_IF와짧은명령문.go:
--------------------------------------------------------------------------------
1 | // 21_IF와짧은명령문
2 | //IF실행전 간단한 변수선언가능하다.
3 | package main
4 |
5 | import (
6 | "fmt"
7 | "math"
8 | )
9 |
10 | func pow(x, n, lim float64) float64 {
11 | if v := math.Pow(x, n); v < lim {
12 | return v
13 | }
14 | return lim
15 | }
16 |
17 | func main() {
18 | fmt.Println(
19 | pow(3, 2, 10),
20 | pow(3, 3, 20),
21 | )
22 | }
23 |
24 | /*
25 | if문 앞에 짧은 문장을 넣을 수 있다. 이부분 => v := math.Pow(x, n);
26 | if 블록 안에서만 사용가능하다.
27 |
28 | Written by arahansa
29 | https://www.facebook.com/groups/golangko/
30 | 모든 내용은 http://go-tour-kr.appspot.com/
31 | */
32 |
--------------------------------------------------------------------------------
/gotour/41_연습_맵.go:
--------------------------------------------------------------------------------
1 | // 41_연습_맵
2 | package main
3 |
4 | import (
5 | "code.google.com/p/go-tour/wc"
6 | )
7 |
8 | func WordCount(s string) map[string]int {
9 | return map[string]int{"x": 1}
10 | }
11 |
12 | func main() {
13 | wc.Test(WordCount)
14 | }
15 |
16 | /*
17 | WordCount 함수를 구현합니다. 이 함수는 s라는 문자열 내에서 각각의 "단어"의 등장 횟수를 나타내는 맵을 반환해야 합니다.
18 | wc.Test 함수는 주어진 함수를 이용하여 테스트를 실행한 뒤에 그 성공 여부를 출력해 줍니다.
19 |
20 | 아마도 다음 링크 (strings.Fields)의 내용이 도움이 될 것입니다.
21 |
22 | Written by arahansa
23 | https://www.facebook.com/groups/golangko/
24 | 모든 내용은 http://go-tour-kr.appspot.com/
25 | */
26 |
--------------------------------------------------------------------------------
/gotour/50_메소드.go:
--------------------------------------------------------------------------------
1 | // 50_메소드
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | type Vertex struct {
10 | X, Y float64
11 | }
12 |
13 | func (v *Vertex) Abs() float64 {
14 | return math.Sqrt(v.X*v.X + v.Y*v.Y)
15 | }
16 |
17 | func main() {
18 | v := &Vertex{3, 4}
19 | fmt.Println(v.Abs())
20 | }
21 |
22 | /*
23 | 고에는 클래스가 없습니다. 하지만 메소드를 구조체(struct)에 붙일 수 있습니다.
24 |
25 | 메소드 리시버(method receiver) 는 func 키워드와 메소드의 이름 사이에 인자로 들어갑니다.
26 |
27 | Written by arahansa
28 | https://www.facebook.com/groups/golangko/
29 | 모든 내용은 http://go-tour-kr.appspot.com/
30 | */
31 |
--------------------------------------------------------------------------------
/gotour/51_메소드2.go:
--------------------------------------------------------------------------------
1 | // 51_메소드2
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | type MyFloat float64
10 |
11 | func (f MyFloat) Abs() float64 {
12 | if f < 0 {
13 | return float64(-f)
14 | }
15 | return float64(f)
16 | }
17 |
18 | func main() {
19 | f := MyFloat(-math.Sqrt2)
20 | fmt.Println(f.Abs())
21 | }
22 |
23 | /*
24 | 사실 메소드는 구조체(struct) 뿐 아니라 아무 타입(type)에나 붙일 수 있습니다.
25 |
26 | 다른 패키지에 있는 타입이나 기본 타입들에 메소드를 붙이는 것은 불가능합니다.
27 |
28 |
29 | Written by arahansa
30 | https://www.facebook.com/groups/golangko/
31 | 모든 내용은 http://go-tour-kr.appspot.com/
32 | */
33 |
--------------------------------------------------------------------------------
/packages/strconv/00_오버뷰.go:
--------------------------------------------------------------------------------
1 | // strconv 패키지는 전환을 구현한다. 문자열로의 아니면, 문자열로부터 기본데이터타입의 표현으로~
2 | //Package strconv implements conversions to and from string representations of basic data types.
3 |
4 | package main
5 |
6 | import (
7 | "fmt"
8 | "strconv"
9 | )
10 |
11 | func main() {
12 | fmt.Println("Hello world")
13 | //Atoi 는 문자열=> 숫자로 파싱해준다. 두번째 값은 에러리턴.
14 | fmt.Println(strconv.Atoi("27"))
15 | //Itoa 는 숫자를 문자열로 파싱
16 | fmt.Println("숫자=>문자는 Itoa :", strconv.Itoa(27))
17 | // 파라미터는 (i int64, base int) 형으로, base는 2(포함)와 36(포함)사이의 값
18 | fmt.Println(strconv.FormatInt(11, 36))
19 | }
20 |
--------------------------------------------------------------------------------
/gotour/47_조건을생략한스위치.go:
--------------------------------------------------------------------------------
1 | // 47_조건을생략한스위치
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "time"
7 | )
8 |
9 | func main() {
10 | t := time.Now()
11 | switch {
12 | case t.Hour() < 12:
13 | fmt.Println("Good morning!")
14 | case t.Hour() < 17:
15 | fmt.Println("Good afternoon.")
16 | default:
17 | fmt.Println("Good evening.")
18 | }
19 | }
20 |
21 | /*
22 | 스위치에서 조건을 생략하면 " switch true " 와 같습니다.
23 | 만약 긴 if-then-else 를 작성해야 할 때, 이 구조를 사용하면 코드를 깔끔하게 작성할 수 있습니다.
24 |
25 | Written by arahansa
26 | https://www.facebook.com/groups/golangko/
27 | 모든 내용은 http://go-tour-kr.appspot.com/
28 | */
29 |
--------------------------------------------------------------------------------
/gotour/40_맵리터럴2.go:
--------------------------------------------------------------------------------
1 | // 38_맵리터럴2
2 | package main
3 |
4 | import "fmt"
5 |
6 | type Vertex struct {
7 | Lat, Long float64
8 | }
9 |
10 | var m = map[string]Vertex{
11 | "Bell Labs": {40.68433, -74.39967},
12 | "Google": {37.42202, -122.08408},
13 | }
14 |
15 | func main() {
16 | fmt.Println(m)
17 | }
18 |
19 | /*
20 | 만약 가장 상위의 타입이 타입명이라면 리터럴에서 타입명을 생략해도 됩니다.
21 | "Bell Labs": {40.68433, -74.39967} 또는
22 | "Bell Labs": Vertex{40.68433, -74.39967}
23 | 는 같은 표현입니다.
24 |
25 |
26 | Written by arahansa
27 | https://www.facebook.com/groups/golangko/
28 | 모든 내용은 http://go-tour-kr.appspot.com/
29 | */
30 |
--------------------------------------------------------------------------------
/gotour/31_슬라이스자르기.go:
--------------------------------------------------------------------------------
1 | // 31_슬라이스자르기
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | p := []int{2, 3, 5, 7, 11, 13}
8 | fmt.Println("p ==", p)
9 | fmt.Println("p[2:3] ==", p[2:3])
10 |
11 | // missing low index implies 0
12 | fmt.Println("p[:3] ==", p[:3])
13 |
14 | // missing high index implies len(s)
15 | fmt.Println("p[4:] ==", p[4:])
16 | }
17 |
18 | /*
19 | 슬라이스에서 슬라이스이름[시작:끝-1] 으로 재분할가능하다.
20 | 예) 저기 위에서 슬라이스이름[2:3] 은 0, 1, 2에서 2번째것 즉 5만 나타냄.
21 |
22 |
23 | Written by arahansa
24 | https://www.facebook.com/groups/golangko/
25 | 모든 내용은 http://go-tour-kr.appspot.com/
26 | */
27 |
--------------------------------------------------------------------------------
/packages/net/02_godoc예제.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "io"
5 | "log"
6 | "net"
7 | )
8 |
9 | func main() {
10 | // 모든 인터페이스들 위에서 2000포트로 TCP 접속을 대기함.
11 | l, err := net.Listen("tcp", ":2000")
12 | if err != nil {
13 | log.Fatal(err)
14 | }
15 | defer l.Close()
16 | for {
17 | //접속대기
18 | conn, err := l.Accept()
19 | if err != nil {
20 | log.Fatal(err)
21 | }
22 | // 새로운 Go루틴에서 접속을 다룸.
23 | // loop 는 접속으로 돌아간다, 그래서 여러개의 접속이 동시적으로 처리된다.
24 | go func(c net.Conn) {
25 | // 들어오는 모든 데이터를 출력함.
26 | io.Copy(c, c)
27 | //접속 종료
28 | c.Close()
29 | }(conn)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GolangKorea Facebook
2 | Golang Korea facebook group 멤버들과 나누는 깃헙
3 | 일단 이런 테마를 가지고 정리를 하고 있습니다.
4 |
5 | 1. Gotour
6 | 2. GoByExample
7 | 3. Effective Go
8 | 4. packages 샘플 소스들 정리
9 |
10 |
11 | # 그룹 내의 발표자료들.
12 | (그룹 홈피를 잘 정리해서 저장할 예정입니다.)
13 |
14 | 1. [Go, 90% Perfect 100% of the time](http://100coding.com/go/slide#1)
15 | 2. [Advanced Go Concurrency Patterns](http://bit.ly/arahanGo)
16 | 3. [Go + Revel +Gorp 로 만드는 페이징 게시판](http://100coding.com/go/tutorial/1)
17 | 4. [Go + Revel+ GORM 으로 만드는 블로그](https://github.com/jaehue/goblog/wiki)
18 | 5. [Go 웹 프레임워크 Revel 번역] (http://100coding.com/go/revel)
19 |
--------------------------------------------------------------------------------
/gotour/43_함수클로저.go:
--------------------------------------------------------------------------------
1 | // 43_함수클로저
2 | package main
3 |
4 | import "fmt"
5 |
6 | func adder() func(int) int {
7 | sum := 0
8 | return func(x int) int {
9 | sum += x
10 | return sum
11 | }
12 | }
13 |
14 | func main() {
15 | pos, neg := adder(), adder()
16 | for i := 0; i < 10; i++ {
17 | fmt.Println(
18 | pos(i),
19 | neg(-2*i),
20 | )
21 | }
22 | }
23 |
24 | /*
25 | 그리고 함수는 클로져(full closures) 입니다.
26 | 코드에서 adder 함수는 클로져(closure)를 반환합니다.
27 | 각각의 클로져는 자신만의 sum 변수를 가집니다.
28 |
29 | Written by arahansa
30 | https://www.facebook.com/groups/golangko/
31 | 모든 내용은 http://go-tour-kr.appspot.com/
32 | */
33 |
--------------------------------------------------------------------------------
/gotour/15_숫자형상수.go:
--------------------------------------------------------------------------------
1 | // 15_숫자형상수
2 | package main
3 |
4 | import "fmt"
5 |
6 | const (
7 | Big = 1 << 100
8 | Small = Big >> 99
9 | )
10 |
11 | func needInt(x int) int { return x*10 + 1 }
12 | func needFloat(x float64) float64 {
13 | return x * 0.1
14 | }
15 |
16 | func main() {
17 | fmt.Println(needInt(Small))
18 | fmt.Println(needFloat(Small))
19 | fmt.Println(needFloat(Big))
20 | }
21 |
22 | /*
23 | 숫자형 상수는 정밀한 값을 표현하는데 적합하다
24 | 타입을 지정하지 않은 상수는 문맥에 따라 타입을 가지게 된다.
25 | 어떤 결과를 출력할지 시험!?
26 |
27 | Written by arahansa
28 | https://www.facebook.com/groups/golangko/
29 | 모든 내용은 http://go-tour-kr.appspot.com/
30 | */
31 |
--------------------------------------------------------------------------------
/gobyexample/05_For문.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/for
4 |
5 | Go by Example: For
6 |
7 | `for` 는 Go의 유일한 반복문이고, 여기 for문의 세가지 유형이 있다.
8 | */
9 | package main
10 |
11 | import "fmt"
12 |
13 | func main() {
14 |
15 | // 가장 기본적 타입인 단일조건문
16 | i := 1
17 | for i <= 3 {
18 | fmt.Println(i)
19 | i = i + 1
20 | }
21 |
22 | // 많이 본 for문이죠..? ㅎㅎ 초기식/조건식/후처리 for문
23 | for j := 7; j <= 9; j++ {
24 | fmt.Println(j)
25 | }
26 |
27 | // 조건식이 없는 for문은 break를 만나거나
28 | //enclosing(?동봉된?둘러쌓여진?) 함수에서 return될때까지 계속 반복합니다.
29 | for {
30 | fmt.Println("loop")
31 | return
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/gotour/28_구조체리터럴.go:
--------------------------------------------------------------------------------
1 | // 28_구조체리터럴
2 | package main
3 |
4 | import "fmt"
5 |
6 | type Vertex struct {
7 | X, Y int
8 | }
9 |
10 | var (
11 | p = Vertex{1, 2} // has type Vertex
12 | q = &Vertex{1, 2} // has type *Vertex
13 | r = Vertex{X: 1} // Y:0 is implicit
14 | s = Vertex{} // X:0 and Y:0
15 | )
16 |
17 | func main() {
18 | fmt.Println(p, q, r, s)
19 | }
20 |
21 | /*
22 | 구조체 리터럴은 필드와 값을 나열해 구조체를 새로 할당하는 방법이다.
23 | 원하는 필드를 {Name:value} 구문을 통해 할당 가능하다.
24 | 특별한 접두어 &를 사용하면 구조체 리터럴에 대한 포인터 생성 가능하다.
25 |
26 | Written by arahansa
27 | https://www.facebook.com/groups/golangko/
28 | 모든 내용은 http://go-tour-kr.appspot.com/
29 | */
30 |
--------------------------------------------------------------------------------
/gotour/35_레인지2.go:
--------------------------------------------------------------------------------
1 | // 35_레인지2
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | pow := make([]int, 10)
8 | for i := range pow {
9 | pow[i] = 1 << uint(i)
10 | }
11 | for _, value := range pow {
12 | fmt.Printf("%d\n", value)
13 | }
14 | }
15 |
16 | /*
17 | _ 를 이용해서 인덱스(index)나 값(value)를 무시할 수 있습니다.
18 | 만약 인덱스만 필요하다면 “ `, value` ” 부분을 다 제거하면 됩니다.
19 |
20 | for i, value := range pow {
21 | pow[i] = 1 << uint(i)
22 | }
23 | 를
24 | for i := range pow {
25 | pow[i] = 1 << uint(i)
26 | }
27 | 로바꾸기 가능
28 |
29 | Written by arahansa
30 | https://www.facebook.com/groups/golangko/
31 | 모든 내용은 http://go-tour-kr.appspot.com/
32 | */
33 |
--------------------------------------------------------------------------------
/effectivego/03_명칭/03_interface이름들.go:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Interface 이름들
4 | 규정에 의하면 하나의 method interface들은 method name에 추가로 -er 접미사를 붙여서
5 | 이름을 만듭니다.(예: Reader, Writer, Formatter 등등)
6 |
7 | 그런류에 많은 이름들이 있고 이런 방법은 그것들을 관리하는데 효율적입니다.
8 | Read, Write, Close, Flush, String 등등은 일반적인 용법과 의미를 가지고 있습니다.
9 | 혼란을 막기 위해, 같은 용법과 의미를 가지고 있는게 아니라면 당신이 만든 method의 이름을
10 | 그 이름들 중에서 사용하지 마십시요. 반대로 만약 당신이 구현한 method가 잘 알려진 type과 같은
11 | 의미를 가지고 있다면, 같은 이름과 용법을 사용하십시요.
12 | (예: 당신이 만든 string-converter method는 ToString?이 아니라 String이라고 이름지으십시요)
13 |
14 |
15 |
16 | Mixed Caps
17 | 마지막으로, Go 언어에서의 규약은 여러 단어를 사용한 이름을 쓰기 위해서는
18 | (_)보다는 대소문자 혼합(MixedCaps?)을 사용한다는 것 입니다.
19 |
20 |
21 | */
--------------------------------------------------------------------------------
/packages/net/http/03_Get.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "io/ioutil"
6 | "log"
7 | "net/http"
8 | "time"
9 | )
10 |
11 | func main() {
12 | //res, err := http.Get("http://www.google.com/robots.txt")
13 | //현재 시간 계산 시작
14 | start := time.Now().Nanosecond()
15 |
16 | res, err := http.Get("http://localhost:9000") //Go로 게시판 서버 열었다.
17 | if err != nil {
18 | log.Fatal(err)
19 | }
20 | robots, err := ioutil.ReadAll(res.Body)
21 | res.Body.Close()
22 | if err != nil {
23 | log.Fatal(err)
24 | }
25 | fmt.Printf("%s", robots)
26 |
27 | //작업후 시간 계산 시작
28 | end := time.Now().Nanosecond()
29 | fmt.Println("실행시간 :", (end-start)/1000)
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/gobyexample/03_변수들.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/variables
4 |
5 | Go by Example: Variables
6 | */
7 | package main
8 |
9 | import "fmt"
10 |
11 | func main() {
12 |
13 | // `var` 는 한개나 여러 개의 변수를 선언한다.
14 | var a string = "initial"
15 | fmt.Println(a)
16 |
17 | // 동시에 여러개의 변수선언이 가능하다.
18 | var b, c int = 1, 2
19 | fmt.Println(b, c)
20 |
21 | // Go 는 변수가 초기화될때 타입을 추론한다.
22 | var d = true
23 | fmt.Println(d)
24 |
25 | // 초기화값이 없는 변수는 zero-value. 숫자의 경우는0
26 | var e int
27 | fmt.Println(e)
28 |
29 | // `:=` 는 초기화와 선언의 요약이다. 로컬에 쓰임.
30 | // f:="short"는 var f string = "short"임.
31 | f := "short"
32 | fmt.Println(f)
33 | }
34 |
--------------------------------------------------------------------------------
/packages/reflect/01_겟셋값해보기.go:
--------------------------------------------------------------------------------
1 | //출처 : http://golang-examples.tumblr.com/post/44089080167/get-set-a-field-value-of-a-struct-using-reflection
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "reflect"
7 | )
8 |
9 | type MyStruct struct {
10 | N int
11 | }
12 |
13 | //리플렉션을 이용한 게터세터를 이용할 때,
14 | //겟할 때는 reflect.ValueOf(n)
15 | //셋할 때는 Value(&변수명).Elem()
16 | func main() {
17 |
18 | n := MyStruct{1}
19 |
20 | // 겟해보기
21 | immutable := reflect.ValueOf(n)
22 | val := immutable.FieldByName("N").Int()
23 | fmt.Printf("N=%d\n", val) // prints 1
24 |
25 | // set
26 | mutable := reflect.ValueOf(&n).Elem()
27 | mutable.FieldByName("N").SetInt(7)
28 | fmt.Printf("N=%d\n", n.N) // prints 7
29 | }
30 |
--------------------------------------------------------------------------------
/gotour/45_스위치.go:
--------------------------------------------------------------------------------
1 | // 45_스위치
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "runtime"
7 | )
8 |
9 | func main() {
10 | fmt.Print("Go runs on ")
11 | switch os := runtime.GOOS; os {
12 | case "darwin":
13 | fmt.Println("OS X.")
14 | case "linux":
15 | fmt.Println("Linux.")
16 | default:
17 | // freebsd, openbsd,
18 | // plan9, windows...
19 | fmt.Printf("%s.", os)
20 | }
21 | }
22 |
23 | /*
24 | 다른 일반적인 언어를 아는 분이라면 switch 에 대해서 잘 알 것입니다.
25 |
26 | 다른 언어와 다른점은 case의 코드 실행을 마치면 알아서 break를 한다는 점입니다.
27 |
28 | ( fallthrough 로 끝나는 case는 스스로 break를 하지 않습니다 )
29 |
30 |
31 | Written by arahansa
32 | https://www.facebook.com/groups/golangko/
33 | 모든 내용은 http://go-tour-kr.appspot.com/
34 | */
35 |
--------------------------------------------------------------------------------
/gobyexample/04_상수.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/constants
4 |
5 | Go by Example: Constants
6 | */
7 | package main
8 |
9 | import "fmt"
10 | import "math"
11 |
12 | // `const` 는 상수를 선언한다.
13 | const s string = "constant"
14 |
15 | func main() {
16 | fmt.Println(s)
17 |
18 | // `const` 는 var가 나타날 수 있는 어디든지 등장할 수 있다.
19 | const n = 500000000
20 |
21 | // 상수표현식은 임의적인 정확도의 연산을 수행한다.
22 | const d = 3e20 / n
23 | fmt.Println(d)
24 |
25 | // 숫자상수는 명시적형변환같은 타입이 주어질때까지 어떤 타입도 갖지 않는다.
26 | fmt.Println(int64(d))
27 |
28 | //숫자는 그것을 필요로 하는 맥락속에서 변수할당이나 함수호출로써 사용되므로써 타입이 주어질 수 있다
29 | //예를 들자면 여기서 `math.Sin` 은 `float64` 를 필요로 한다.
30 | fmt.Println(math.Sin(n))
31 | }
32 |
--------------------------------------------------------------------------------
/gotour/36_연습_슬라이스.go:
--------------------------------------------------------------------------------
1 | // 36_연습_슬라이스
2 | package main
3 |
4 | import "code.google.com/p/go-tour/pic"
5 |
6 | func Pic(dx, dy int) [][]uint8 {
7 | }
8 |
9 | func main() {
10 | pic.Show(Pic)
11 | }
12 |
13 | /*
14 | Pic이라는 함수를 구현합니다. 이 함수는 dy개 만큼의 길이를 가지는 슬라이스를 리턴해야 하는데, 각각의 요소들은 또한 dx 개의 8비트 부호없는 8비트 정수 타입을 가지는 슬라이스입니다. 프로그램을 실행하면 이 정수값들을 흑백 (사실은 파란색)을 나타내는 값으로 해석하여 그림을 보여줄 것입니다.
15 |
16 | 그림은 여러분이 원하는 것으로 선택할 수 있습니다. (이용할 수 있는) 흥미로운 함수로는 x^y, (x+y)/2, x*y 등이 있습니다.
17 |
18 | (여러분은 [][]uint8 슬라이스 내에서 사용할 각각의 []uint8 슬라이스를 할당하기 위해 루프를 활용해야 할 것입니다.)
19 |
20 | (타입 간의 변환을 위해서는 uint8(intValue)을 사용합니다.)
21 |
22 | Written by arahansa
23 | https://www.facebook.com/groups/golangko/
24 | 모든 내용은 http://go-tour-kr.appspot.com/
25 | */
26 |
--------------------------------------------------------------------------------
/gobyexample/23_채널.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/channels
4 | Go by Example: channels
5 |
6 | 채널은 동시에 공존하는 Go루틴들을 연결하는 파이프다.
7 | 하나의 go루틴에서 채널로 값을 전송할 수 있으며 그러한 값들을 다른 Go루틴을 통해 받을 수 있다.
8 | */
9 |
10 | package main
11 |
12 | import "fmt"
13 |
14 | func main() {
15 |
16 | // `make(chan 값-타입)` 로 새로운 채널을 만든다.
17 | // 채널은 자신이 운반하는 값에 의해 타입이 정해진다.
18 | messages := make(chan string)
19 |
20 | // `channel <- 문법을 이용해서 채널에 값을 전송할 수 있다.
21 | // 여기 우리가 'message'라는 위에서 만든 채널에 "ping"을 보내는 작업을 Go루틴으로부터 하고 있다.
22 | go func() { messages <- "ping" }()
23 |
24 | // <-channel 문법은 채널로부터 값을 받는다.
25 | // 여기 우리는 위에서 보낸 ping 메시지를 받아서 그것을 출력한다.
26 | msg := <-messages
27 | fmt.Println(msg)
28 | }
29 |
--------------------------------------------------------------------------------
/gobyexample/31_레인지채널.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/range-over-channels
4 | Go by Example: range-over-channels
5 |
6 | 지난번의 range예제에서 우리는 for와 range가 기초적인 자료구조에서 어떻게 반복하는지 보았다.
7 | 우리는 또한 이 문법을 채널을 통해 들어오는 값에서 반복할 수 있다.
8 | */
9 |
10 | package main
11 |
12 | import "fmt"
13 |
14 | func main() {
15 |
16 | // 우리는 queue 채널에서 2개의 값 이상을 반복할 것이다.
17 | queue := make(chan string, 2)
18 | queue <- "one"
19 | queue <- "two"
20 | close(queue)
21 |
22 | //이 range는 각각의 요소들 위에서 반복한다. 요소들이 queue채널에서 받아지기 때문이다.
23 | //우리가 위에서 채널을 닫았기 때문에 반복은 2개의 요소를 받고 난 뒤 끝난다.
24 | // 만약 우리가 채널을 닫지 않으면, 우리는 loop 에서 3번째로 받을 때 블락될 것이다.
25 |
26 | for elem := range queue {
27 | fmt.Println(elem)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/gotour/58_연습_HTTP핸들러.go:
--------------------------------------------------------------------------------
1 | // 58_연습_HTTP핸들러
2 | package main
3 |
4 | import (
5 | "net/http"
6 | )
7 |
8 | func main() {
9 | // your http.Handle calls here
10 | http.ListenAndServe("localhost:4000", nil)
11 | }
12 |
13 | /*
14 | 아래 나오는 타입을 구현하고 그 타입의 ServeHTTP 메소드를 정의하십시오.
15 | 그 메소드를 당신의 웹 서버에서 특정 경로를 처리할 수 있도록 등록하십시오.
16 |
17 | type String string
18 |
19 | type Struct struct {
20 | Greeting string
21 | Punct string
22 | Who string
23 | }
24 | 예컨대, 당신은 아래와 같이 핸들러를 등록할 수 있어야 합니다.
25 |
26 | http.Handle("/string", String("I'm a frayed knot."))
27 | http.Handle("/struct", &Struct{"Hello", ":", "Gophers!"})
28 |
29 | Written by arahansa
30 | https://www.facebook.com/groups/golangko/
31 | 모든 내용은 http://go-tour-kr.appspot.com/
32 | */
33 |
--------------------------------------------------------------------------------
/gobyexample/13_다중리턴값.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/functions
4 |
5 | Go by Example: Multiple Return Values
6 |
7 | Go는 다중리턴값을 지원합니다.
8 | 이러한 특징은 Go 에서 자연스럽게 사용되며, 예를 들자면
9 | 함수로부터 결과값과 에러 둘다 받을 때 사용됩니다.
10 | */
11 | package main
12 |
13 | import "fmt"
14 |
15 | // 이 함수에서 (int, int) 는 두개의 int형을 리턴한다는 것을 의미합니다.
16 | func vals() (int, int) {
17 | return 3, 7
18 | }
19 |
20 | func main() {
21 |
22 | //여기, 다중리턴호출로부터 두개의 다른 값을 받아봅니다.
23 | a, b := vals()
24 | fmt.Println(a)
25 | fmt.Println(b)
26 |
27 |
28 | //만약 다중리턴 에서 필요하지 않은게 있으면 그것은 _ 로 처리하면 된다.
29 | _, c := vals()
30 | fmt.Println(c)
31 | }
32 |
33 | // todo: named return parameters
34 | // todo: naked returns
35 |
--------------------------------------------------------------------------------
/gotour/60_연습_이미지.go:
--------------------------------------------------------------------------------
1 | // 60_연습_이미지
2 | package main
3 |
4 | import (
5 | "code.google.com/p/go-tour/pic"
6 | "image"
7 | )
8 |
9 | type Image struct{}
10 |
11 | func main() {
12 | m := Image{}
13 | pic.ShowImage(m)
14 | }
15 |
16 | /*
17 | 이전의 연습에서 당신이 작성한 그림 생성기를 기억하십니까? 다른 생성기를 만들어봅시다.
18 | 하지만 이번에는 데이터의 슬라이스 대신에 image.Image 의 구현체를 반환할 것입니다.
19 | 당신 자신의 Image 타입을 정의하시고, 필수 함수들 을 구현하신 다음,
20 | pic.ShowImage 를 호출하십시오.
21 | Bounds 는 image.Rect(0, 0, w, h) 와 같은 image.Rectangle 을 반환해야 합니다.
22 | ColorModel 은 color.RGBAModel 을 반환해야 합니다.
23 |
24 | At 은 하나의 컬러를 반환해야 합니다;
25 | 지난 그림 생성기에서 값 v 는 color.RGBA{v, v, 255, 255} 와 같습니다.
26 |
27 | Written by arahansa
28 | https://www.facebook.com/groups/golangko/
29 | 모든 내용은 http://go-tour-kr.appspot.com/
30 | */
31 |
--------------------------------------------------------------------------------
/gotour/46_스위치동작순서.go:
--------------------------------------------------------------------------------
1 | // 46_스위치동작순서
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "time"
7 | )
8 |
9 | func main() {
10 | fmt.Println("When's Saturday?")
11 | today := time.Now().Weekday()
12 | switch time.Saturday {
13 | case today + 0:
14 | fmt.Println("Today.")
15 | case today + 1:
16 | fmt.Println("Tomorrow.")
17 | case today + 2:
18 | fmt.Println("In two days.")
19 | default:
20 | fmt.Println("Too far away.")
21 | }
22 | }
23 |
24 | /*
25 | 스위치의 각 조건은 위에서 아래로 평가합니다. 만약 조건이 참인 case를 찾으면 평가를 마칩니다.
26 |
27 | (예를 들어
28 | switch i {
29 | case 0:
30 | case f():
31 | }
32 | 에서 i==0 이라면 f() 는 실행하지 않습니다)
33 |
34 |
35 | Written by arahansa
36 | https://www.facebook.com/groups/golangko/
37 | 모든 내용은 http://go-tour-kr.appspot.com/
38 | */
39 |
--------------------------------------------------------------------------------
/gobyexample/24_채널버퍼링.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/channels
4 | Go by Example: channels
5 |
6 | 기본적 채널은 버퍼되지(unbuffered)않았다. 이것은 그들이 오직 채널들이
7 | 그에 상응하는 받는 (`<- chan`) 이 보내는 값을 받을 준비가 되어야만, 전송(`chan <-`)하는 것을 수락한다는 것이다.
8 | Buffered channels 은 그에 상응하는 값들을 위한 리시버없이 제한된 개수의 값을 수락한다.
9 | */
10 |
11 | package main
12 |
13 | import "fmt"
14 |
15 | func main() {
16 |
17 | // 여기서 make로 문자열채널을 만들고, 2개의 값까지 버퍼링 up 한다.
18 | messages := make(chan string, 2)
19 |
20 | //이 채널은 버퍼되었기 때문에, 우리는 이러한 값들을 채널에 보낼 수 있으며
21 | //이때는, 이에 상응하는 리시버가 없어도 된다.
22 | messages <- "buffered"
23 | messages <- "channel"
24 |
25 | //후에 우리는 평소대로 이러한 두가지 값을 받을 수 있다.
26 | fmt.Println(<-messages)
27 | fmt.Println(<-messages)
28 | }
29 |
--------------------------------------------------------------------------------
/gobyexample/06_If_Else문.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/if-else
4 |
5 | Go by Example: IfElse
6 |
7 | Go에서의 If else 분기문은 간단하다
8 | */
9 | package main
10 |
11 | import "fmt"
12 |
13 | func main() {
14 |
15 | // 이것은 기본적인 예제다.
16 | if 7%2 == 0 {
17 | fmt.Println("7 is even")
18 | } else {
19 | fmt.Println("7 is odd")
20 | }
21 |
22 | // else 없이 사용 가능하며
23 | if 8%4 == 0 {
24 | fmt.Println("8 is divisible by 4")
25 | }
26 |
27 | // 문장 하나가 조건식 앞에 나올 수 있다.; 이 문장에 쓰여진 변수들은 이
28 | // if else 문 어디서도 사용 가능하다..
29 | if num := 9; num < 0 {
30 | fmt.Println(num, "is negative")
31 | } else if num < 10 {
32 | fmt.Println(num, "has 1 digit")
33 | } else {
34 | fmt.Println(num, "has multiple digits")
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/gotour/59_이미지.go:
--------------------------------------------------------------------------------
1 | // 59_이미지
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "image"
7 | )
8 |
9 | func main() {
10 | m := image.NewRGBA(image.Rect(0, 0, 100, 100))
11 | fmt.Println(m.Bounds())
12 | fmt.Println(m.At(0, 0).RGBA())
13 | }
14 |
15 | /*
16 | Package image 는 Image 인터페이스를 정의합니다.
17 |
18 | package image
19 |
20 | type Image interface {
21 | ColorModel() color.Model
22 | Bounds() Rectangle
23 | At(x, y int) color.Color
24 | }
25 | (모든 세부사항에 대한 것은 이 문서 를 참고하십시오.)
26 | http://golang.org/pkg/image/#Image
27 | 또한, color.Color 와 color.Model 는 인터페이스이지만,
28 | 미리 정의된 구현체인 color.RGBA 와 color.RGBAModel 을
29 | 사용함으로써 그 인터페이스를 무시할 수 있습니다.
30 |
31 | Written by arahansa
32 | https://www.facebook.com/groups/golangko/
33 | 모든 내용은 http://go-tour-kr.appspot.com/
34 | */
35 |
--------------------------------------------------------------------------------
/gotour/68_셀렉트의디폴트케이스.go:
--------------------------------------------------------------------------------
1 | // 68_셀렉트의디폴트케이스
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "time"
7 | )
8 |
9 | func main() {
10 | tick := time.Tick(1e8)
11 | boom := time.After(5e8)
12 | for {
13 | select {
14 | case <-tick:
15 | fmt.Println("tick.")
16 | case <-boom:
17 | fmt.Println("BOOM!")
18 | return
19 | default:
20 | fmt.Println(" .")
21 | time.Sleep(5e7)
22 | }
23 | }
24 | }
25 |
26 | /*
27 | select 의 default 케이스는 현재 수행 준비가 완료된 케이스가 없을 때 수행됩니다.
28 |
29 | 블로킹 없이(비동기적인) 송/수신을 하고자 할 때 default 케이스를 사용하세요.
30 |
31 | select {
32 | case i := <-c:
33 | // i를 사용
34 | default:
35 | // c로부터의 수신은 블록된 상태
36 | }
37 |
38 | Written by arahansa
39 | https://www.facebook.com/groups/golangko/
40 | 모든 내용은 http://go-tour-kr.appspot.com/
41 | */
42 |
--------------------------------------------------------------------------------
/effectivego/03_명칭/02_Getters.go:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | https://code.google.com/p/golang-korea/wiki/EffectiveGo#명칭(Names)
4 |
5 | Go 언어는 getter와 setter를 자동으로 제공하지 않습니다.
6 | 당신 스스로 getter와 setter를 만드는 것은 잘못된 것이 아니며,
7 | 그렇게 하는 것은 흔한 일입니다.
8 |
9 | 당신이 만든 getter와 setter에는 문법적인 오류가 없어야 하며
10 | getter의 이름에 Get을 넣을 필요가 없습니다.
11 |
12 | 예로, 만약 당신이 owner(소문자, export되지 않았음)라고 불리는 field를 하나 가지고 있다면
13 | getter method는 GetOwner?가 아니라 Owner(대문자, export됨)로 호출되어야만 합니다.
14 |
15 | export하기 위해 대문자 이름을 사용하는 것은 method로 부터 그 field를 구분하기 위한 방법을
16 | 제공합니다. 만약 필요하다면, setter 함수는 SetOwner?로 불릴 것입니다.
17 |
18 | 두 이름 모두 읽기에 좋습니다.(getter는 Get이라는 단어를 사용하지 않지만,
19 | setter는 Set이라는 단어를 사용함)
20 |
21 | */
22 | func main() {
23 | owner := obj.Owner()
24 | if owner != user {
25 | obj.SetOwner(user)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/gotour/57_웹서버.go:
--------------------------------------------------------------------------------
1 | // 57_웹서버
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "net/http"
7 | )
8 |
9 | type Hello struct{}
10 |
11 | func (h Hello) ServeHTTP(
12 | w http.ResponseWriter,
13 | r *http.Request) {
14 | fmt.Fprint(w, "Hello!")
15 | }
16 |
17 | func main() {
18 | var h Hello
19 | http.ListenAndServe("localhost:4000", h)
20 | }
21 |
22 | /*
23 | Package http 는 http.Handler 를 구현한 어떠 값을 사용하여 HTTP 요청(requests)을 제공합니다.
24 |
25 | package http
26 |
27 | type Handler interface {
28 | ServeHTTP(w ResponseWriter, r *Request)
29 | }
30 | 이 예제에서, Hello 라는 타입은 http.Handler 를 구현합니다.
31 |
32 | 이 코드를 로컬에서 실행하고, http://localhost:4000/ 에 접속해보세요.
33 |
34 | Written by arahansa
35 | https://www.facebook.com/groups/golangko/
36 | 모든 내용은 http://go-tour-kr.appspot.com/
37 | */
38 |
--------------------------------------------------------------------------------
/gotour/24_기본자료형.go:
--------------------------------------------------------------------------------
1 | // 24_기본자료형
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math/cmplx"
7 | )
8 |
9 | var (
10 | ToBe bool = false
11 | MaxInt uint64 = 1<<64 - 1
12 | z complex128 = cmplx.Sqrt(-5 + 12i)
13 | )
14 |
15 | func main() {
16 | const f = "%T(%v)\n"
17 | fmt.Printf(f, ToBe, ToBe)
18 | fmt.Printf(f, MaxInt, MaxInt)
19 | fmt.Printf(f, z, z)
20 | }
21 |
22 | /*
23 | 기본 자료형은 다음과 같다.
24 | bool
25 | string
26 | int int8 int16 int32 int64
27 | uint uint8 uint16 uint32 uint64 uintptr
28 |
29 | byte uint8의 다른 이름(alias)
30 |
31 | rune int32의 다른 이름(alias)
32 | 유니코드 코드 포인트 값을 표현합니다.
33 | float32 float64
34 |
35 | complex64 complex128
36 | Written by arahansa
37 | https://www.facebook.com/groups/golangko/
38 | 모든 내용은 http://go-tour-kr.appspot.com/
39 | */
40 |
--------------------------------------------------------------------------------
/gobyexample/59_커맨드라인아규먼트.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/command-line-arguments
4 | Go by Example: command-line-arguments
5 |
6 | 커맨드라인 아규먼트는 프로그램 실행에서 파라미터를 쓰는 흔한 방법이다.
7 | 예를 들어서 go run hello.go 에서 run과 hello.go 는 Go프로그램의 아규먼트들이다.
8 | */
9 |
10 | package main
11 |
12 | import "os"
13 | import "fmt"
14 |
15 | func main() {
16 |
17 | // os.Args는 커맨드라인 아규먼트에 접근을 제공한다.
18 | // 이 슬라이스의 첫번째 값은 프로그램에 path란 것을 기억하자.
19 | // os.Args[1:]은 프로그램의 아규먼트들을 가지고 있다.
20 | argsWithProg := os.Args
21 | argsWithoutProg := os.Args[1:]
22 |
23 | // 당신은 평범한 인덱싱으로 독립적인 아규먼트를 얻을 수 있다.
24 | arg := os.Args[3]
25 |
26 | fmt.Println(argsWithProg)
27 | fmt.Println(argsWithoutProg)
28 | fmt.Println(arg)
29 |
30 | // 커맨드 라인 아규먼트를 실험하기 위해서, 먼저 go build로 바이너리파일을 만들 것이 좋다.
31 | }
32 |
--------------------------------------------------------------------------------
/gotour/67_셀렉트.go:
--------------------------------------------------------------------------------
1 | // 67_셀렉트
2 | package main
3 |
4 | import "fmt"
5 |
6 | func fibonacci(c, quit chan int) {
7 | x, y := 0, 1
8 | for {
9 | select {
10 | case c <- x:
11 | x, y = y, x+y
12 | case <-quit:
13 | fmt.Println("quit")
14 | return
15 | }
16 | }
17 | }
18 |
19 | func main() {
20 | c := make(chan int)
21 | quit := make(chan int)
22 | go func() {
23 | for i := 0; i < 10; i++ {
24 | fmt.Println(<-c)
25 | }
26 | quit <- 0
27 | }()
28 | fibonacci(c, quit)
29 | }
30 |
31 | /*
32 | select 구문은 고루틴이 다수의 통신 동작으로부터 수행 준비를 기다릴 수 있게 합니다.
33 |
34 | select 는 case 구문으로 받는 통신 동작들 중 하나가 수행될 수 있을 때까지 수행을 블록합니다.
35 | 다수의 채널이 동시에 준비되면 그 중 하나를 무작위로 선택합니다.
36 |
37 | Written by arahansa
38 | https://www.facebook.com/groups/golangko/
39 | 모든 내용은 http://go-tour-kr.appspot.com/
40 | */
41 |
--------------------------------------------------------------------------------
/packages/os/01_텍스트파일읽기.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "log"
7 | "os"
8 | )
9 |
10 | func main() {
11 | lines, err := readLines("sample.txt")
12 | if err != nil {
13 | log.Fatalf("readLines: %s", err)
14 | }
15 | for i, line := range lines {
16 | fmt.Println(i, line)
17 | }
18 | }
19 |
20 | // readLines 은 파일을 메모리로 읽어들여,
21 | // 파일들 라인의 슬라이스를 리턴한다. 참고 http://bit.ly/golangreadwrite
22 | func readLines(path string) ([]string, error) {
23 | file, err := os.Open(path)
24 | if err != nil {
25 | return nil, err
26 | }
27 | defer file.Close() //defer 는 다른 언어문법에서 finally 같은 것을 의미함.
28 |
29 | var lines []string
30 | scanner := bufio.NewScanner(file)
31 | for scanner.Scan() {
32 | lines = append(lines, scanner.Text())
33 | }
34 | return lines, scanner.Err()
35 | }
36 |
--------------------------------------------------------------------------------
/packages/fmt/00_오버뷰.go:
--------------------------------------------------------------------------------
1 | //http://golang.org/pkg/fmt/
2 | /*
3 | fmt 패키지는 형식화된 입출력을 c의 printf, scanf와 비슷한 함수들로 구현한다.
4 | 형식 verb들은 C에서 따왔지만, 좀 다 간결하다.
5 |
6 | */
7 | %v 구조체를 출력할 때 기본형식값, +표시(%+v)는 필드명을 더한다.
8 | %v the value in a default format when printing structs, the plus flag (%+v) adds field names
9 | %#v 값을 재표시하는 Go문법
10 | %T 값의 타입을 재표시(representation)
11 | %% a literal percent sign; consumes no value
12 |
13 | Boolean:
14 |
15 | %t 참, 거짓
16 |
17 | Integer:
18 |
19 | %b 2진수
20 | %c 문자, 유니코드에 해당하는,
21 | %d 10진수
22 | %o 8진수
23 | %q 단일인용문자 리터럴? a single-quoted character literal safely escaped with Go syntax.
24 | %x 16진수 영어는 소문자 표현 //base 16, with lower-case letters for a-f
25 | %X 16진수 대문자로 표현 //base 16, with upper-case letters for A-F
26 | %U 유니코드 포맷 //Unicode format: U+1234; same as "U+%04X"
27 |
28 | //TODO
29 |
30 |
--------------------------------------------------------------------------------
/gobyexample/25_채널동기화.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/channel-synchronization
4 | Go by Example: channel-synchronization
5 |
6 | 우리는 채널을 Go루틴들사이에서 동기화실행을 위해 사용할 수 있다.
7 | 여기에 Go루틴이 마쳐질때까지 기다리기위해 리시브를 블락킹하는 예제가 있다.
8 | */
9 |
10 | package main
11 |
12 | import "fmt"
13 | import "time"
14 |
15 | // 여기 이 함수는 Go루틴에서 실행될 함수인데,
16 | // 다른 고루틴에게 이 함수의 작업이 완료되었단 것을 알리기 위해 done 채널이 사용될 것이다.
17 | func worker(done chan bool) {
18 | fmt.Println("working...(역주:여기서 1초 쉴겁니다)")
19 | time.Sleep(time.Second)
20 | fmt.Println("done")
21 |
22 | // 우리가 다 됬단 것을 알려주기 위한 값을 전송한다.
23 | done <- true
24 | }
25 |
26 | func main() {
27 |
28 | // worker Go루틴을 실행하고 알림을 주기위해 채널을 전달한다.
29 | done := make(chan bool, 1)
30 | go worker(done)
31 |
32 | //우리가 채널이 있는 worker로부터 알림을 받을 때까지 블락된다.
33 | <-done
34 | }
35 |
--------------------------------------------------------------------------------
/gotour/63_고루틴.go:
--------------------------------------------------------------------------------
1 | // 63_고루틴
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "time"
7 | )
8 |
9 | func say(s string) {
10 | for i := 0; i < 5; i++ {
11 | time.Sleep(100 * time.Millisecond)
12 | fmt.Println(s)
13 | }
14 | }
15 |
16 | func main() {
17 | go say("world")
18 | say("hello")
19 | }
20 |
21 | /*
22 | _고루틴_은 Go 런타임에 의해 관리되는 경량 쓰레드입니다.
23 |
24 | go f(x, y, z)
25 | 위의 코드는 새로운 고루틴을 시작시킵니다.
26 |
27 | f(x, y, z)
28 | 현재의 고루틴에서 f , x , y , z 가 평가(evaluation)되고,
29 | 새로운 고루틴에서 f 가 수행(execution)됩니다.
30 |
31 | 고루틴은 동일한 주소 공간에서 실행되므로, 공유되는 자원으로의 접근은 반드시 동기화 되어야 합니다.
32 | [[http://golang.org/pkg/sync/][sync]] 패키지가 이를 위해 유용한 기본 기능을 제공합니다.
33 | Go 에서는 그외에도 다양한 기본 기능을 제공하니 크게 필요치 않을 테지만요. (다음 슬라이드를 보세요.)
34 |
35 | Written by arahansa
36 | https://www.facebook.com/groups/golangko/
37 | 모든 내용은 http://go-tour-kr.appspot.com/
38 | */
39 |
--------------------------------------------------------------------------------
/gobyexample/26_채널방향.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/channel-directions
4 | Go by Example: channel-directions
5 |
6 | 만약 채널을 함수의 파라미터로 이용할때, 당신은 채널이 오직 값을 받거나, 수신할지 명시할 수 있다.
7 | 이러한 명시는 프로그램의 타입안전(type-safety)를 증가시킨다.
8 |
9 | */
10 |
11 | package main
12 |
13 | import "fmt"
14 |
15 | //이 핑 함수는 오직 값을 보내는 것만 받는다,
16 | //이 채널로 받기를 시도하려고 한다면 이것은 compile 에러를 낼 것이다.
17 | func ping(pings chan<- string, msg string) {
18 | pings <- msg
19 | }
20 |
21 | // 이 퐁 함수는 오직 (pings)수신을 위한 채널과 ('pongs')전송을 위한 채널만을 받아들인다.
22 | func pong(pings <-chan string, pongs chan<- string) {
23 | msg := <-pings
24 | pongs <- msg
25 | }
26 |
27 | func main() {
28 | pings := make(chan string, 1)
29 | pongs := make(chan string, 1)
30 | ping(pings, "passed message")
31 | pong(pings, pongs)
32 | fmt.Println(<-pongs)
33 | }
34 |
--------------------------------------------------------------------------------
/gotour/32_슬라이스만들기.go:
--------------------------------------------------------------------------------
1 | // 32_슬라이스만들기
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | a := make([]int, 5)
8 | printSlice("a", a)
9 | b := make([]int, 0, 5)
10 | printSlice("b", b)
11 | c := b[:2]
12 | printSlice("c", c)
13 | d := c[2:5]
14 | printSlice("d", d)
15 | }
16 |
17 | func printSlice(s string, x []int) {
18 | fmt.Printf("%s len=%d cap=%d %v\n",
19 | s, len(x), cap(x), x)
20 | }
21 |
22 | /*
23 | 슬라이스는 make 함수로 만들기 가능. a := make([]int, 5) // len(a)=5
24 | 이렇게 생성된 슬라이스는 0을할당한 배열을 만들어 그것을 참조한다.
25 |
26 | //make 함수의 세번째 매개변수로 용량을 제한 가능하다.
27 |
28 | b := make([]int, 0, 5) // len(b)=0, cap(b)=5
29 |
30 | b = b[:cap(b)] // len(b)=5, cap(b)=5
31 | b = b[1:] // len(b)=4, cap(b)=4
32 |
33 | Written by arahansa
34 | https://www.facebook.com/groups/golangko/
35 | 모든 내용은 http://go-tour-kr.appspot.com/
36 | */
37 |
--------------------------------------------------------------------------------
/gotour/61_연습Rot13Reader.go:
--------------------------------------------------------------------------------
1 | // 61_연습Rot13Reader
2 | package main
3 |
4 | import (
5 | "io"
6 | "os"
7 | "strings"
8 | )
9 |
10 | type rot13Reader struct {
11 | r io.Reader
12 | }
13 |
14 | func main() {
15 | s := strings.NewReader(
16 | "Lbh penpxrq gur pbqr!")
17 | r := rot13Reader{s}
18 | io.Copy(os.Stdout, &r)
19 | }
20 |
21 | /*
22 | 어떤 식으로든 스트림을 수정하여 다른 io.Reader 를 감싸는 io.Reader 는 흔한 패턴입니다.
23 |
24 | 예컨대, gzip.NewReader 함수는 io.Reader (gzip으로 압축된 데이터의 스트림) 를 가지고,
25 | io.Reader (압축 해제된 데이터의 스트림) 를 구현한 `*gzip.Reader`를 반환합니다.
26 |
27 | ROT13 치환 암호화를 모든 알파벳 문자에 적용함으로써 스트림을 수정하며
28 | io.Reader 를 구현하고 io.Reader 로 부터 읽는 rot13Reader 를 구현하십시오.
29 | rot13Reader 타입은 당신을 위해 제공됩니다. 이 타입의 Read 함수를 구현함으로써 io.Reader 을 만들어 보십시오.
30 |
31 | Written by arahansa
32 | https://www.facebook.com/groups/golangko/
33 | 모든 내용은 http://go-tour-kr.appspot.com/
34 | */
35 |
--------------------------------------------------------------------------------
/gobyexample/14_가변인자함수.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/variadic-functions
4 |
5 | Go by Example: Variadic Functions
6 |
7 | [_Variadic functions_](http://en.wikipedia.org/wiki/Variadic_function)
8 | 가변인자 함수는 여러개의 파라미터를 받을 수 있는 함수다.
9 | 예를 들자면 fmt.Println이 가변인자함수
10 | */
11 | package main
12 |
13 | import "fmt"
14 |
15 | // 임의의 숫자 nums 들을 int 로 받는 함수
16 | func sum(nums ...int) {
17 | fmt.Print(nums, " ")
18 | total := 0
19 | for _, num := range nums {
20 | total += num
21 | }
22 | fmt.Println(total)
23 | }
24 |
25 | func main() {
26 |
27 | // 가변인자함수는 독립적인 파라미터들과 함께 호출될수 있다.
28 | sum(1, 2)
29 | sum(1, 2, 3)
30 |
31 | //
32 | //슬라이스안에 이미 여러개의 파라미터를 가진 경우 그것들을 다음과 같이
33 | //메서드(슬라이스)같이 하여 가변인자함수에 적용할 수 있다.
34 | nums := []int{1, 2, 3, 4}
35 | sum(nums...)
36 | }
37 |
--------------------------------------------------------------------------------
/gobyexample/33_티커.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/tickers
4 | Go by Example: tickers
5 |
6 | timer는 당신이 미래에 어떤 일을 하고 싶을 때 쓰고 ticker는 당신이 정기적으로
7 | 어떤 일을 반복적으로 하기 원할 때 쓴다. 여기 우리가 멈출 때까지 정기적으로 tick하는
8 | ticker 예제가 있다. (틱장애가 떠오른다...역주)
9 |
10 | */
11 |
12 | package main
13 |
14 | import "time"
15 | import "fmt"
16 |
17 | func main() {
18 |
19 | // Ticker는 타이머(값을 전송하는 채널)와 비슷한 메커니즘이다.
20 | // 여기 채널에서 반복하는 range문을 이용하여서, 매초 500ms 마다 들어오는 값을 반복하자.
21 | ticker := time.NewTicker(time.Millisecond * 500)
22 | go func() {
23 | for t := range ticker.C {
24 | fmt.Println("Tick at", t)
25 | }
26 | }()
27 |
28 | //Tickers는 타이머같이 멈춰질수 있는데 ticker가 멈춰지면, 그것은 채널로부터 어떠한 더 이상의 값도 받지 못한다.
29 | // 1500ms초후에 우리는 이것을 멈춰보자.
30 | time.Sleep(time.Millisecond * 1500)
31 | ticker.Stop()
32 | fmt.Println("Ticker stopped")
33 | }
34 |
--------------------------------------------------------------------------------
/gotour/23_연습_루프와함수.go:
--------------------------------------------------------------------------------
1 | // 23_연습_루프와함수
2 | package main
3 |
4 | import (
5 | "fmt"
6 | )
7 |
8 | func Sqrt(x float64) float64 {
9 | }
10 |
11 | func main() {
12 | fmt.Println(Sqrt(2))
13 | }
14 |
15 | /*
16 | 함수와 루프의 사용법을 익히는 간단한 연습으로, 제곱근 함수를 뉴턴의 방법(Newton's method)을 이용하여 구현합니다.
17 | 여기서 뉴턴의 방법이란 초기값 z를 선택한 후에 다음의 공식을 이용하여 반복적으로 Sqrt(x) 함수의 근사값을 찾아가는 방법을 말합니다:
18 | z = z - (z * z - x) / (2 * z)
19 | 처음에는 계산을 10번만 반복하여 여러분이 작성한 함수가 다양한 값들 (1, 2, 3, ...)에 대하여 얼마나 정확한 값을 찾아내는지 확인합니다.
20 | 그 다음에는, 루프의 조건을 수정하여 값이 더이상 바뀌지 않을 때 (혹은 아주 작은 차이가 발생할 때) 루프를 종료하도록 합니다. 이렇게 하면 반복문의 실행 횟수가 어떻게 달라지는지 확인합니다. 결과값이 math.Sqrt 함수의 값과 얼마나 비슷한가요?
21 | 힌트: 실수(floating point)값을 선언하고 초기화 하려면, 실수값을 표현하는 문법을 사용하거나 변환 함수를 사용합니다:
22 | z := float64(1)
23 | z := 1.0
24 |
25 | Written by arahansa
26 | https://www.facebook.com/groups/golangko/
27 | 모든 내용은 http://go-tour-kr.appspot.com/
28 | */
29 |
--------------------------------------------------------------------------------
/gotour/55_에러.go:
--------------------------------------------------------------------------------
1 | // 55_에러
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "time"
7 | )
8 |
9 | type MyError struct {
10 | When time.Time
11 | What string
12 | }
13 |
14 | func (e *MyError) Error() string {
15 | return fmt.Sprintf("at %v, %s", e.When, e.What)
16 | }
17 |
18 | func run() error {
19 | return &MyError{
20 | time.Now(),
21 | "it didn't work",
22 | }
23 | }
24 |
25 | func main() {
26 | if err := run(); err != nil {
27 | fmt.Println(err)
28 | }
29 | }
30 |
31 | /*
32 | 에러 문장(string)으로 자신을 표현할 수 있는 것은 모두 에러입니다.
33 | 이 아이디어는 문자열(string)을 반환하는 하나의 메소드 Error 로 구성된 내장 인터페이스 타입 error 에서 나왔습니다.
34 |
35 | type error interface {
36 | Error() string
37 | }
38 | fmt 패키지의 다양한 출력 루틴들은 error 의 출력을 요청받았을 때 자동으로 이 메소드를 호출합니다.
39 |
40 | Written by arahansa
41 | https://www.facebook.com/groups/golangko/
42 | 모든 내용은 http://go-tour-kr.appspot.com/
43 | */
44 |
--------------------------------------------------------------------------------
/gobyexample/39_정렬.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/sorting
4 |
5 | Go by Example: sorting
6 |
7 | Go의 sort패키지는 내장형이거나 사용자가정의한 타입에 관하여 정렬을 구현한다.
8 | 내장형에 관한 정렬을 먼저 알아보겠다
9 | */
10 |
11 | package main
12 |
13 | import "fmt"
14 | import "sort"
15 |
16 | func main() {
17 |
18 | // Sort메소드는 내장타입에 대하여 구체적이다.
19 | // 여기 문자열에 관한 예제가 있다. 정렬은 제자리에서 한다는 것을 기억하자(sort. 이렇게~)
20 | // 그래서 주어진 슬라이스를 변경하지, 새로운 것을 리턴하지 않는다.
21 | strs := []string{"c", "a", "b"}
22 | sort.Strings(strs)
23 | fmt.Println("Strings:", strs)
24 |
25 | // int형을 정렬하는 예제다.
26 | ints := []int{7, 2, 4}
27 | sort.Ints(ints)
28 | fmt.Println("Ints: ", ints)
29 |
30 | // 우리는 또한 슬라이스가 이미 정렬되었는지 체크할 수 있다.
31 | s := sort.IntsAreSorted(ints)
32 | fmt.Println("Sorted: ", s)
33 |
34 | //우리의 프로그램을 실행하면 정렬된 문자열과 숫자 슬라이스, 그리고 참값을
35 | // AreSorted테스트의 결과로 나타낼 것이다.
36 | }
37 |
--------------------------------------------------------------------------------
/effectivego/07_데이터/04_배열.go:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
4 |
5 |
6 | 배열(Arrays)
7 | 배열은 메모리의 자세한 레이아웃을 설계할 때 유용하며, 때로는, 메모리 할당하는 것을 피할 수 있습니다.
8 | 하지만 주로 배열은 다음 섹션의 주제인 slice를 위한 하나의 덩어리 입니다.
9 | 주제에 대한 기초를 쌓기 위해, 여기서 배열에 관해 몇마디 하자면,
10 | Go 언어와 C언어 사이에는 큰 차이 점이 있습니다. Go 언어에서는 배열은 값들입니다.
11 |
12 | 모든 요소들의 또다른 복사본을 위해 하나의 배열을 지정하는 것,
13 | 특히, 만약 함수에 배열을 넘긴다면, 함수는 실제 배열에 대한 포인터가 아니라 배열의 복사본을 넘겨 받게 될 것입니다.
14 | 배열의 크기는 배열의 타입의 한 부분입니다. 10?int 와 20?int는 구별되어지며, 값 속성은 유용하지만 사용이 힘듭니다.;
15 | 만약 C언어에서와 같은 형태의 사용이나 효율성을 원한다면 다음 예제와 같이 배열에 포인터를 넘겨줄 수도 있습니다.
16 |
17 | */
18 |
19 | func Sum(a *[3]float64) (sum float64) {
20 | for _, v := range *a {
21 | sum += v
22 | }
23 | return
24 | }
25 |
26 | array := [...]float64{7.0, 8.5, 9.1}
27 | x := Sum(&array) // Note the explicit address-of operator
28 |
29 | //하지만 이런 형태는 자연스러운 Go언어의 형태가 아닙니다.
--------------------------------------------------------------------------------
/gotour/39_맵다루기.go:
--------------------------------------------------------------------------------
1 | // 39_맵다루기
2 | package main
3 |
4 | import "fmt"
5 |
6 | func main() {
7 | m := make(map[string]int)
8 |
9 | m["Answer"] = 42
10 | fmt.Println("The value:", m["Answer"])
11 |
12 | m["Answer"] = 48
13 | fmt.Println("The value:", m["Answer"])
14 |
15 | delete(m, "Answer")
16 | fmt.Println("The value:", m["Answer"])
17 |
18 | v, ok := m["Answer"]
19 | fmt.Println("The value:", v, "Present?", ok)
20 | }
21 |
22 | /*
23 | 맵 m 의 요소를 삽입하거나 수정하기:
24 |
25 | m[key] = elem
26 | 요소 값 가져오기:
27 |
28 | elem = m[key]
29 | 요소 지우기:
30 |
31 | delete(m, key)
32 | 키의 존재 여부 확인하기:
33 |
34 | elem, ok = m[key]
35 | 위의 ok 의 값은 m 에 key 가 존재한다면 true 존재하지 않으면 false , elem 은 타입에 따라 0(zero value) 가 됩니다.
36 |
37 | 이처럼 map 을 읽을 때, 존재하지 않는 key 의 반환 값은 타입에 맞는 zero value 입니다.
38 |
39 | Written by arahansa
40 | https://www.facebook.com/groups/golangko/
41 | 모든 내용은 http://go-tour-kr.appspot.com/
42 | */
43 |
--------------------------------------------------------------------------------
/packages/net/http/02_하이재커.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | )
8 |
9 | func main() {
10 | http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
11 | hj, ok := w.(http.Hijacker)
12 | if !ok {
13 | http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
14 | return
15 | }
16 | conn, bufrw, err := hj.Hijack()
17 | if err != nil {
18 | http.Error(w, err.Error(), http.StatusInternalServerError)
19 | return
20 | }
21 | // Don't forget to close the connection:
22 | defer conn.Close()
23 | bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
24 | bufrw.Flush()
25 | s, err := bufrw.ReadString('\n')
26 | if err != nil {
27 | log.Printf("error reading string: %v", err)
28 | return
29 | }
30 | fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
31 | bufrw.Flush()
32 | })
33 | }
34 |
--------------------------------------------------------------------------------
/gobyexample/08_배열들.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/arrays
4 |
5 | Go by Example: Arrays
6 |
7 | Go에서 배열은 특정 길이를 가진, 번호가 붙은 요소들의 나열이다.
8 | */
9 | package main
10 |
11 | import "fmt"
12 |
13 | func main() {
14 |
15 | // a는 상수배열이고 크기 5를 가진다. 요소타입과 길이는 둘다 배열타입의 일부다..
16 | // int배열의 기본값은 zero-value 즉 0을 가진다.
17 | var a [5]int
18 | fmt.Println("emp:", a)
19 |
20 | // 배열[순번] = 값 으로 배열의 값을 지정하고, 배열[순번]으로 값을 불러온다.
21 | a[4] = 100
22 | fmt.Println("set:", a)
23 | fmt.Println("get:", a[4])
24 |
25 | // 내장된 len으로 배열의 길이 가져오기
26 | fmt.Println("len:", len(a))
27 |
28 | //다음과 같이 한줄로 배열을 선언하고, 초기화할수도 있다.
29 | b := [5]int{1, 2, 3, 4, 5}
30 | fmt.Println("dcl:", b)
31 |
32 | // 배열은 1차원일수도있고, 다차원이 될 수도 있다(그냥 짧게 번역함)
33 | var twoD [2][3]int
34 | for i := 0; i < 2; i++ {
35 | for j := 0; j < 3; j++ {
36 | twoD[i][j] = i + j
37 | }
38 | }
39 | fmt.Println("2d: ", twoD)
40 | }
41 |
--------------------------------------------------------------------------------
/gotour/64_채널.go:
--------------------------------------------------------------------------------
1 | // 64_채널
2 | package main
3 |
4 | import "fmt"
5 |
6 | func sum(a []int, c chan int) {
7 | sum := 0
8 | for _, v := range a {
9 | sum += v
10 | }
11 | c <- sum // send sum to c
12 | }
13 |
14 | func main() {
15 | a := []int{7, 2, 8, -9, 4, 0}
16 |
17 | c := make(chan int)
18 | go sum(a[:len(a)/2], c)
19 | go sum(a[len(a)/2:], c)
20 | x, y := <-c, <-c // receive from c
21 |
22 | fmt.Println(x, y, x+y)
23 | }
24 |
25 | /*
26 | 채널은 채널 연산자 <- 를 이용해 값을 주고 받을 수 있는, 타입이 존재하는 파이프입니다.
27 |
28 | ch <- v // v 를 ch로 보냅니다.
29 | v := <-ch // ch로부터 값을 받아서
30 | // v 로 넘깁니다.
31 | (데이터가 화살표 방향에 따라 흐릅니다.)
32 |
33 | 맵이나 슬라이스처럼, 채널은 사용되기 전에 생성되어야 합니다:
34 |
35 | ch := make(chan int)
36 | 기본적으로, 송/수신은 상대편이 준비될 때까지 블록됩니다.
37 | 이런 특성이 고루틴이 명시적인 락이나 조건 없이도 동기화 될 수 있도록 돕습니다.
38 |
39 | Written by arahansa
40 | https://www.facebook.com/groups/golangko/
41 | 모든 내용은 http://go-tour-kr.appspot.com/
42 | */
43 |
--------------------------------------------------------------------------------
/gobyexample/61_환경변수.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/environment-variables
4 | Go by Example: environment-variables
5 |
6 | 환경변수[Environment variables]는 설정정보를 유닉스프로그램에 전달하기 위한 일반적인 메커니즘이다.
7 | 어떻게 환경변수를 설정하고, 값을 얻고 리스트화하는지 알아보자
8 | */
9 |
10 | package main
11 |
12 | import "os"
13 | import "strings"
14 | import "fmt"
15 |
16 | func main() {
17 |
18 | // 키밸류 페어를 설정하기 위해, os.Setenv를 이용하자.
19 | // 키값에 대한 값을 얻기 위해, os.Getenv를 이용하다.
20 | // 만약 환경에 맞는 키가 없으면 빈 문자열을 리턴할 것이다.
21 | os.Setenv("FOO", "1")
22 | fmt.Println("FOO:", os.Getenv("FOO"))
23 | fmt.Println("BAR:", os.Getenv("BAR"))
24 |
25 | // 환경의 모든 키밸류 쌍을 리스트출력하기 위해 os.Environ을 사용하자.D
26 | //이것은 문자열의 슬라이스를 KEY=value 폼으로 리턴한다.
27 | // strings.Split으로 그것들을 키와 밸류로 나눌 수 잇다. 여기 모든 키를 출력하는 예제가 있다.
28 | fmt.Println()
29 | for _, e := range os.Environ() {
30 | pair := strings.Split(e, "=")
31 | fmt.Println(pair[0])
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/gotour/54_인터페이스의암시적충족.go:
--------------------------------------------------------------------------------
1 | // 54_인터페이스의암시적충족
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "os"
7 | )
8 |
9 | type Reader interface {
10 | Read(b []byte) (n int, err error)
11 | }
12 |
13 | type Writer interface {
14 | Write(b []byte) (n int, err error)
15 | }
16 |
17 | type ReadWriter interface {
18 | Reader
19 | Writer
20 | }
21 |
22 | func main() {
23 | var w Writer
24 |
25 | // os.Stdout implements Writer
26 | w = os.Stdout
27 |
28 | fmt.Fprintf(w, "hello, writer\n")
29 | }
30 |
31 | /*
32 | 타입이 인터페이스의 메소드들을 구현하면 인터페이스를 구현한 게 됩니다.
33 | 이를 위해 명시적으로 선언할 게 없습니다.
34 | 암시적 인터페이스는 인터페이스를 정의한 패키지로 부터
35 | 구현 패키지를 분리(decouple)해 줍니다. 다른 의존성 또한 없음은 물론입니다.
36 | 이 특징은 상세하게 인터페이스를 정의하게 독려합니다. 모든 구현을 찾아
37 | 새 인터페이스 이름으로 태그할 필요가 없기 때문입니다.
38 | 패키지 io에 Reader 와 Writer 가 정의되어 있습니다. 따로 정의할 필요가 없습니다.
39 |
40 |
41 | Written by arahansa
42 | https://www.facebook.com/groups/golangko/
43 | 모든 내용은 http://go-tour-kr.appspot.com/
44 | */
45 |
--------------------------------------------------------------------------------
/effectivego/06_함수/02_명명된파라미터값.go:
--------------------------------------------------------------------------------
1 | /*
2 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
3 | 명명된 파라미터 결과값(Named result parameters)
4 | Go 함수에서는 리턴값 또는 parameter 결과값들에 대해 명명하는 것이 가능하며
5 | 입력되는 parameter들 처럼 일반적인 변수로 사용하는 것 또한 가능합니다.
6 |
7 | 리턴값을 명명하게 되면 그 함수가 시작될 때 리턴값은 리턴값의 타입에 대해
8 | zero 값으로 초기화 됩니다. 만약 함수가 argument 없이 리턴문을 실행하게 되면
9 | 현재 parameter들의 결과값을 리턴값으로써 사용하게 됩니다.
10 |
11 | 결과값에 이름을 짓는 것은 필수 사항이 아니지만, 리턴값에 명명하는 것은 코드를
12 | 좀 더 간단하고 명료하게 할 수 있습니다.
13 | : 만약 위의 예제에서 nextInt의 결과값을 이름을 붙여주게 되면
14 | 어떤 int값이 리턴되어 졌는지 확실히 알게 될 것입니다.
15 |
16 | func nextInt(b []byte, pos int) (value, nextPos int) {
17 | 위의 예에서 보듯이 이름붙여진 결과값들이 초기화되었고 간소화되었기 때문에,
18 | 단순할 뿐만아니라 명확해질 수 있습니다.
19 | 여기 자주 사용되는 io.ReadFull?의 예가 있습니다.
20 | */
21 | func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
22 | for len(buf) > 0 && err == nil {
23 | var nr int
24 | nr, err = r.Read(buf)
25 | n += nr
26 | buf = buf[nr:len(buf)]
27 | }
28 | return
29 | }
--------------------------------------------------------------------------------
/gobyexample/27_셀렉트.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/select
4 | Go by Example: select
5 |
6 | Go의 셀렉트는 여러 채널 운영에서 당신을 기다리게 해준다.
7 | 고루틴과 채널을 셀렉트와 조합은 Go의 파워풀한 특징이다.
8 | */
9 |
10 | package main
11 |
12 | import "time"
13 | import "fmt"
14 |
15 | func main() {
16 |
17 | // 우리의 예제를 위해 우리는 이 두 채널에서 셀렉트할 것이다.
18 | c1 := make(chan string)
19 | c2 := make(chan string)
20 |
21 | // 각각의 채널은 일정시간이후 값을 받을 것이다.
22 | // 예를 들자면 동시에 발생하는 고루틴에서 실행되는 원격프로시저 호출을 블락킹할 것이다.
23 | go func() {
24 | time.Sleep(time.Second * 1)
25 | c1 <- "one"
26 | }()
27 | go func() {
28 | time.Sleep(time.Second * 2)
29 | c2 <- "two"
30 | }()
31 |
32 | //우리는 동시에 이러한 값 둘다 기다리기 위해 select 를 사용할 것이며
33 | // 값이 도착하면 각각의 값들을 출력할 것이다.
34 | for i := 0; i < 2; i++ {
35 | select {
36 | case msg1 := <-c1:
37 | fmt.Println("received", msg1)
38 | case msg2 := <-c2:
39 | fmt.Println("received", msg2)
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/gotour/53_인터페이스.go:
--------------------------------------------------------------------------------
1 | // 53_인터페이스
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | type Abser interface {
10 | Abs() float64
11 | }
12 |
13 | func main() {
14 | var a Abser
15 | f := MyFloat(-math.Sqrt2)
16 | v := Vertex{3, 4}
17 |
18 | a = f // a MyFloat implements Abser
19 | a = &v // a *Vertex implements Abser
20 | a = v // a Vertex, does NOT
21 | // implement Abser
22 |
23 | fmt.Println(a.Abs())
24 | }
25 |
26 | type MyFloat float64
27 |
28 | func (f MyFloat) Abs() float64 {
29 | if f < 0 {
30 | return float64(-f)
31 | }
32 | return float64(f)
33 | }
34 |
35 | type Vertex struct {
36 | X, Y float64
37 | }
38 |
39 | func (v *Vertex) Abs() float64 {
40 | return math.Sqrt(v.X*v.X + v.Y*v.Y)
41 | }
42 |
43 | /*
44 | 인터페이스는 메소드의 집합으로 정의됩니다.
45 |
46 | 그 메소드들의 구현되어 있는 타입의 값은 모두 인터페이스 타입의 값이 될 수 있습니다.
47 |
48 | Written by arahansa
49 | https://www.facebook.com/groups/golangko/
50 | 모든 내용은 http://go-tour-kr.appspot.com/
51 | */
52 |
--------------------------------------------------------------------------------
/packages/time/01_Example.go:
--------------------------------------------------------------------------------
1 | // 01_Example.go
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "time"
7 | )
8 |
9 | func main() {
10 | fmt.Println("1초마다 계속 울림 ")
11 | //func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
12 | t2 := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
13 | fmt.Printf("Go launched at %s\n", t2.Local())
14 |
15 | t := time.Date(0, 0, 0, 12, 15, 30, 918273645, time.UTC)
16 | round := []time.Duration{
17 | time.Nanosecond,
18 | time.Microsecond,
19 | time.Millisecond,
20 | time.Second,
21 | 2 * time.Second,
22 | time.Minute,
23 | 10 * time.Minute,
24 | time.Hour,
25 | }
26 |
27 | for _, d := range round {
28 | fmt.Printf("t.Round(%6s) = %s\n", d, t.Round(d).Format("15:04:05.999999999"))
29 | }
30 |
31 | for {
32 | select {
33 | case <-time.After(1000 * time.Millisecond):
34 | fmt.Println("timed out : 약 1 초 지남. 지금시간은 :", time.Now())
35 |
36 | }
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/gotour/56_연습_에러.go:
--------------------------------------------------------------------------------
1 | // 56_연습_에러
2 | package main
3 |
4 | import (
5 | "fmt"
6 | )
7 |
8 | func Sqrt(f float64) (float64, error) {
9 | return 0, nil
10 | }
11 |
12 | func main() {
13 | fmt.Println(Sqrt(2))
14 | fmt.Println(Sqrt(-2))
15 | }
16 |
17 | /*
18 | 당신의 Sqrt 함수를 이전 연습에서 복사하고 error 값을 반환하도록 수정하십시오.
19 |
20 | Sqrt 함수는 복소수를 지원하지 않기 때문에, 음수가 주어지면 nil 이 아닌 에러 값을 반환해야 합니다.
21 |
22 | 새로운 타입을 만드십시오.
23 |
24 | type ErrNegativeSqrt float64
25 | and make it an error by giving it a 그리고 아래 메소드를 구현함으로써
26 | 그 타입이 error 가 되게 하십시오.
27 |
28 | func (e ErrNegativeSqrt) Error() string
29 | 이는 ErrNegativeSqrt(-2).Error() 가 "cannot Sqrt negative number: -2" 를 반환하는 그러한 메소드입니다.
30 |
31 | Note: Error 메소드 내에서 fmt.Print(e) 를 호출하면 이 프로그램을 무한루프에 빠질 것입니다.
32 | e 를 바꿈으로써 이 문제를 피할 수 있습니다. 왜 그럴까요?
33 |
34 | 음수가 주어졌을 때 ErrNegativeSqrt 값을 반환하도록 당신의 Sqrt 함수를 바꾸십시오.
35 |
36 | Written by arahansa
37 | https://www.facebook.com/groups/golangko/
38 | 모든 내용은 http://go-tour-kr.appspot.com/
39 | */
40 |
--------------------------------------------------------------------------------
/gobyexample/07_스위치.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | Go by Example: Switch
4 |
5 | Go by Example: Switch
6 |
7 | 스위치 는 많은 경우들을 표현할 수 있다.(의역)
8 | */
9 | package main
10 |
11 | import "fmt"
12 | import "time"
13 |
14 | func main() {
15 |
16 | // 기본적인 스위치문
17 | i := 2
18 | fmt.Print("write ", i, " as ")
19 | switch i {
20 | case 1:
21 | fmt.Println("one")
22 | case 2:
23 | fmt.Println("two")
24 | case 3:
25 | fmt.Println("three")
26 | }
27 |
28 | // 콤마들(,)을 사용해서 여러 조건들을 하나의 case 문에 사용가능하다.
29 | // default 로 아무조건도 걸리지 않는 경우를 처리할 수 있다(의역)
30 | switch time.Now().Weekday() {
31 | case time.Saturday, time.Sunday:
32 | fmt.Println("it's the weekend")
33 | default:
34 | fmt.Println("it's a weekday")
35 | }
36 |
37 | // 표현식이 없는 swich는 ifelse 처럼 쓸 수 있다.
38 | // 상수가 아닌 것도 case 표현식에 적을 수 있다.
39 | t := time.Now()
40 | switch {
41 | case t.Hour() < 12:
42 | fmt.Println("it's before noon")
43 | default:
44 | fmt.Println("it's after noon")
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/gotour/66_Range와Close.go:
--------------------------------------------------------------------------------
1 | // 66_Range와Close
2 | package main
3 |
4 | import (
5 | "fmt"
6 | )
7 |
8 | func fibonacci(n int, c chan int) {
9 | x, y := 0, 1
10 | for i := 0; i < n; i++ {
11 | c <- x
12 | x, y = y, x+y
13 | }
14 | close(c)
15 | }
16 |
17 | func main() {
18 | c := make(chan int, 10)
19 | go fibonacci(cap(c), c)
20 | for i := range c {
21 | fmt.Println(i)
22 | }
23 | }
24 |
25 | /*
26 | 데이터 송신측은 더이상 보낼 값이 없다는 것을 알리기 위해 채널을 close 할 수 있습니다.
27 | 수신측은 다음과 같이 수신 코드에 두번째 인자를 줌으로써 채널이 닫혔는지 테스트 할 수 있습니다.
28 |
29 | v, ok := <-ch
30 | 채널이 이미 닫혔고 더이상 받을 값이 없다면 ok 는 false 가 됩니다.
31 |
32 | for i := range c 반복문은 채널이 닫힐 때까지 계속해서 값을 받습니다.
33 |
34 | 주의: 송신측만 채널을 닫을 수 있습니다. 수신측에선 불가능합니다.
35 | 이미 닫힌 채널에 데이터를 보내면 패닉이 일어납니다.
36 |
37 | 또하나의 주의: 채널은 파일과 다릅니다; 항상 닫을 필요는 없습니다.
38 | 채널을 닫는 행위는 오로지 수신측에게 더이상 보낼 값이 없다고 말해야 할때만 행해지면 됩니다.
39 | range 루프를 종료시켜야 할 때처럼요.
40 |
41 | Written by arahansa
42 | https://www.facebook.com/groups/golangko/
43 | 모든 내용은 http://go-tour-kr.appspot.com/
44 | */
45 |
--------------------------------------------------------------------------------
/gobyexample/19_메소드.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/methods
4 |
5 | Go by Example: Methods
6 |
7 | Go는 구조체 타입 위에서 메소드를 만들 수 있다.
8 |
9 | */
10 |
11 | package main
12 |
13 | import "fmt"
14 |
15 | type rect struct {
16 | width, height int
17 | }
18 |
19 | // 이 `area` 메소드는 `*rect`의 리시버타입을 가지고 있다. (포인터 형식이란 얘기: 역주)
20 | func (r *rect) area() int {
21 | return r.width * r.height
22 | }
23 |
24 | // 메소드는 포인터나 값 전달 타입으로 생성할 수 있다. 여기에 값전달 타입이 있다.
25 | //(역주: 포인터 안 붙임)
26 | func (r rect) perim() int {
27 | return 2*r.width + 2*r.height
28 | }
29 |
30 | func main() {
31 | r := rect{width: 10, height: 5}
32 |
33 | // 우리의 구조체에서 생성된 두개의 메소드를 불러본다.
34 | fmt.Println("area: ", r.area())
35 | fmt.Println("perim:", r.perim())
36 |
37 | // Go는 자동으로 메소드호출을 위하여 값과 포인터의 변환을 처리한다.
38 | // 당신은 메소드가 호출될때 복사를 피하거나 메소드가 receiving 구조체를 변경시키기 위해
39 | //포인터 리시버 타입을 사용할 수도 있다.
40 | rp := &r
41 | fmt.Println("area: ", rp.area())
42 | fmt.Println("perim:", rp.perim())
43 | }
44 |
--------------------------------------------------------------------------------
/gobyexample/22_Go루틴.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/goroutines
4 |
5 | Go by Example: Goroutines
6 |
7 | Go루틴은 실행가능한(of execution) 경량화쓰레드다.
8 | */
9 |
10 | package main
11 |
12 | import "fmt"
13 |
14 | func f(from string) {
15 | for i := 0; i < 3; i++ {
16 | fmt.Println(from, ":", i)
17 | }
18 | }
19 |
20 | func main() {
21 |
22 | //우리가 f(s)라는 함수를 가지고 있다고 생각해보자.
23 | // 우리는 저 함수를 동시에 일어나게(synchronously) 실행하며 보통 방법으로 실행시킬 것이다.
24 | f("direct")
25 |
26 | // 이 함수를 Go 루틴에서 적용(invoke)하기 위해, go f(s)를 사용하자.
27 | // 이 새로운 Go루틴은 함수를 호출하면서 동시에(concurrently) 시작될 것이다.
28 | // 역주) new Thread 같은 개념인 것같다고 말하고 싶다.
29 | go f("goroutine")
30 |
31 | // 당신은 또한 익명함수호출로 Go루틴을 시작할 수 있다.
32 | go func(msg string) {
33 | fmt.Println(msg)
34 | }("going")
35 |
36 | //우리의 두 함수호출은 지금 다른 Go루틴속에서 비동기적으로 실행될 것이다.
37 | // so execution falls through to here.
38 | // 이 Scanln 은 메시지를 받아서 사용자가 키보드값을 입력해야 프로그램이 종료됨.
39 | var input string
40 | fmt.Scanln(&input)
41 | fmt.Println("done")
42 | }
43 |
--------------------------------------------------------------------------------
/gobyexample/54_Sha1해쉬.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/sha1-hashes
4 | Go by Example: sha1-hashes
5 |
6 | SHA1 hashes는 바이너리나 텍스트 blob를 위한 짧은 정체들을(identities) 계산하는데 자주 사용된다.
7 | 예를들면 git 리비젼 컨트롤시스템은 Sha1을 파일과 디렉토리의 버젼확인을 위해 널리 사용을 한다.
8 | 여기 어떻게 GO에서 SHA1 해쉬를 계산하는지 나와있다.
9 |
10 | */
11 | package main
12 |
13 | // Go는 많은 crypto/* 패키지에서 몇몇의 해쉬 함수를 구현한다.
14 | import "crypto/sha1"
15 | import "fmt"
16 |
17 | func main() {
18 | s := "sha1 this string"
19 |
20 | // 해쉬를 만드는 패턴은 sha1.New() , sha1.Write(bytes) 그리고 sha1.Sum([]bytes{}) 이다.
21 | //여기 새로운 해쉬로 시작하는 방법이 있다.
22 | h := sha1.New()
23 |
24 | // Write는 bytes를 기대한다(Expects) 만약 당신이 문자열 s 를 가지고 있다면,
25 | // 그것을 byte로 강제하기 위해 []byte(s)를 사용하라
26 | h.Write([]byte(s))
27 |
28 | // 이것은 확정된 해쉬값을 바이트슬라이스로 받는다
29 | // Sum의 아규먼트는 존재하는 바이트 슬라이스에서 더 추가하기 위해 사용될 수 있다.(보통 필요하지 않다)
30 | bs := h.Sum(nil)
31 |
32 | // 깃커밋의 예를 들자면 SHA1 값은 종종 hex값으로 출력된다.
33 | // %x 형식을 사용하여서 해쉬값을 hex문자열로 바꿔보자.
34 | fmt.Println(s)
35 | fmt.Printf("%x\n", bs)
36 | }
37 |
--------------------------------------------------------------------------------
/effectivego/01_형식화하기.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | /*
4 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
5 |
6 | 본글을 조금 내용을 요약해서 적어보겠다.
7 |
8 | 다음과 같이 주어진 선언이 있다면.. 밑에 것을 자동으로 정렬해서 바꿔줄 것이다.(예)
9 |
10 | type T struct {
11 | name string // name of the object
12 | value int // its value
13 | }
14 | gofmt tool 을 이용해서 gofmt 파일이름 를 실행시키면 아마 정렬이 된 것을 볼 것이다.
15 | */
16 | type T struct {
17 | name string // name of the object
18 | value int // its value
19 | }
20 |
21 | /*
22 | 들여쓰기
23 | 줄길이
24 | 괄호구문등을 바꿔줄 것이다.
25 |
26 |
27 | 들여쓰기(Indentation)
28 | 들여쓰기를 위해서 tab을 사용합니다. gofmt 는 tab을 default 들여쓰기로 변환해줄 것입니다. 꼭 그래야 할 경우만 space를 사용하세요.
29 |
30 | 줄 길이(Line Length)
31 | Go 언어는 줄 길이의 제한이 없습니다. 오버플로우에 대해서는 걱정할 필요가 없습니다. 만약 줄이 너무 길다면 줄을 tab으로 둘러싸면 됩니다.
32 |
33 | 괄호구문(Parentheses)
34 | Go 언어는 아주 적은 수의 괄호구문만을 필요로 합니다: 제어문(if, for, switch)은 Go언어의 문법상 괄호구문을 필요로 하지 않습니다. 또한, 연산자 우선순위는 더 짧고 더 간단합니다.
35 | 즉,
36 |
37 | x<<8 + y<<16
38 |
39 | 위의 수식에서 space가 우선순위를 암시하는 것을 말함.
40 | (역주:괄호를 사용하지 않고도 space만으로 우선순위가 나뉜다는 의미임.)
41 | */
42 |
--------------------------------------------------------------------------------
/gobyexample/17_포인터.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/pointers
4 |
5 | Go by Example: Pointers
6 |
7 | Go는 포인터를 지원하며
8 | 당신의 프로그램안에서 값과 기록에게 참조를 전달할 수 있다.
9 |
10 | */
11 |
12 | package main
13 |
14 | import "fmt"
15 |
16 | // 우리는 당신에게 포인터가 값에 대해서 어떻게 작동하는지 2개의 function과 함께 보여줄 것이다.
17 | // 하나의 func는 zeroval 이고 두번째 변수는 zeroptr 이다.
18 | // zeroval 은 int형의 파라미터를 가지며, 값형태로 아규먼트가 전달된다.
19 | // zeroval은 그것을 호출한 function과는 구별된 ival의 복사본을 얻게된다.
20 | func zeroval(ival int) {
21 | ival = 0
22 | }
23 |
24 | // 그에 반해서 `zeroptr` 은 `*int` 파라미터를 가진다. 이것은 Int형 포인터를 가진다는 것을 의미하며,
25 | // 이 함수 몸체에서 *iptr은 포인터의 참조를 찾아가서 실제 메모리 주소로 접근하여
26 | // 값을 할당합니다. (생략번역함)
27 | func zeroptr(iptr *int) {
28 | *iptr = 0
29 | }
30 |
31 | func main() {
32 | i := 1
33 | fmt.Println("initial:", i)
34 |
35 | zeroval(i)
36 | fmt.Println("zeroval:", i)
37 |
38 | // `&i` 는 'i'에 대한 메모리주소를 준다.
39 | // i.e. a pointer to `i`.
40 | zeroptr(&i)
41 | fmt.Println("zeroptr:", i)
42 |
43 | // 포인터는 또한 출력될 수 있다.
44 | fmt.Println("pointer:", &i)
45 | }
46 |
--------------------------------------------------------------------------------
/gobyexample/32_타이머.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/timers
4 | Go by Example: timers
5 |
6 | 우리는 나중에 특정 시점이나 어느정도의 시간이 흐른뒤에 반복적으로 Go코드를 실행시키기를 원할 것이다.
7 | Go의 내장된 timer와 ticker는 이러한 일들을 쉽게 해준다.
8 | 처음에 timer를 알아보고 그다음에 ticker를 알아보자.
9 | */
10 |
11 | package main
12 |
13 | import "time"
14 | import "fmt"
15 |
16 | func main() {
17 |
18 | //타이머는 미래의 단일 이벤트를 나타낸다.
19 | // 당신은 타이머에게 얼마나 오랫동안 당신이 기다리는지 말할 수 있다.
20 | // 그리고 타이머는 그때에 알릴수 있는 채널을 제공한다.
21 | //이 타이머는 2초동안을 기다릴 것이다.
22 |
23 | timer1 := time.NewTimer(time.Second * 2)
24 |
25 | // <-timer1.C 는 타이머의 채널 C가 타이머가 종료되었다는 것을 가리키는 값을 보낼때까지 블락된다.
26 | <-timer1.C
27 | fmt.Println("Timer 1 expired")
28 |
29 | //만약 네가 단지 기다리기를 원한다면, 당신은 아마 time.Sleep 을 사용할 수 있을 것이다.
30 | // 타이머가 유용한 또 하나의 이유는 타이머가 종료되기 전에 그것을 취소할 수 있다는 것이다.
31 | //여기 예제가 있다.
32 | timer2 := time.NewTimer(time.Second)
33 | go func() {
34 | <-timer2.C
35 | fmt.Println("Timer 2 expired")
36 | }()
37 | stop2 := timer2.Stop()
38 | if stop2 {
39 | fmt.Println("Timer 2 stopped")
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/packages/os/00_오버뷰.go:
--------------------------------------------------------------------------------
1 | /*
2 | os 패키지는 운영체제 기능에 대하여 플랫폼-독립적인 인터페이스를 제공합니다.
3 | 에러핸들링은 Go같이 되었지만. 디자인은 유닉스와 같이 되었습니다.
4 |
5 | 실패된 호출은 에러 넘버들을 리턴하기보다는, 타입에러 값을 리턴합니다.
6 | 종종, 많은 정보들이 에러 내에서 사용가능합니다.
7 |
8 | 예를 들자면, Open 이나 Stat같은 파일이름으로 하는 호출이 실패하였을 경우,
9 | 에러가 출력될 때, 실패한 파일이름을 포함하고 에러는 더 많은 정보를 위해 unpack 된 *PathError 타입이 될 것입니다.
10 |
11 | os 인터페이스는 모든 운영체제에 대하여 유연하게 설계되었습니다.(일부러 사전적단어를 바꾼 번역함 intended to be uniform)
12 | Features not generally available appear in the system-specific package syscall.
13 | (이건 뭔소리인지 감이 잘 안오네요^^)
14 |
15 | 여기 파일을 열고 읽는 예제가 있습니다.
16 | */
17 | file, err := os.Open("file.go") // For read access.
18 | if err != nil {
19 | log.Fatal(err)
20 | }
21 | /*
22 | 열기에 실패하면, 에러문자열은 설명적으로 다음과 같이 나타날 것이다.*/
23 |
24 | open file.go: no such file or directory
25 |
26 | /*
27 | 파일의 데이터는 byte의 슬라이스로 읽혀질 것입니다..
28 | 읽고쓰는 작업은 slice의 길이로부터 그 파일의 byte counts를 가질 것입니다.
29 | */
30 | data := make([]byte, 100)
31 | count, err := file.Read(data)
32 | if err != nil {
33 | log.Fatal(err)
34 | }
35 | fmt.Printf("read %d bytes: %q\n", count, data[:count])
36 |
37 |
38 |
--------------------------------------------------------------------------------
/gobyexample/41_패닉.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/panic
4 |
5 | Go by Example: panic
6 |
7 | 패닉은 일반적으로 어떤 것인가가 예상치못하게 잘못되었단 것을 의미한다.
8 | 대부분 보통의 작업동안 발생하지 않아야하거나, 우아하게 다룰(handle) 준비가 안 된 에러가 발생했을 때
9 | 빠르게 실패(fail)시키기 위해 패닉을 사용한다.
10 |
11 | */
12 |
13 | package main
14 |
15 | import "os"
16 |
17 | func main() {
18 |
19 | //우리는 패닉을 이 곳(site)에서 예상치 못한 에러를 체크하기 위해 사용할 것이다.
20 | // 이 곳은 패닉을 발생시키기 위한 위치(site)이다.
21 | // We'll use panic throughout this site to check for
22 | // unexpected errors. This is the only program on the
23 | // site designed to panic.
24 | panic("a problem")
25 |
26 | // 패닉을 보통 사용하는 방법은 함수가 우리가 어떻게 처리할지 모르거나 (혹은 아예 모르는) 에러값을 리턴했을 때 그것을
27 | // 무시하는 것이다.
28 | //여기 새로운 파일을 생성하면서 익숙하지 않은 예외를 얻었을 경우 panic 을 사용하는 예제가 있다.
29 |
30 | _, err := os.Create("/tmp/file")
31 | if err != nil {
32 | panic(err)
33 | }
34 |
35 | //이 프로그램을 실행하면 패닉에 이를 것이고 에러 메시지와 고루틴 트레이스를 출력할 것이다.
36 | // 그리고 non-zero status와 함께 프로그램이 종료될 것이다.
37 | // 많은 에러를 예외를 사용해서 처리하는 다른 언어와 달리 Go에서는 가능하면 에러를 리턴값에서 받는 것이 흔하다.
38 | }
39 |
--------------------------------------------------------------------------------
/gobyexample/52_숫자파싱.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/number-parsing
4 | Go by Example: number-parsing
5 |
6 | 문자열에서 숫자를 파싱하시는 것은 기초적이지만, 많은 프로그램에서 흔한 작업이다.
7 | 여기에 어떻게 Go에서 그것을 하는지 나와있다.
8 | */
9 |
10 | package main
11 |
12 | // 내장된 패키지 strconv는 숫자파싱을 제공한다.
13 | import "strconv"
14 | import "fmt"
15 |
16 | func main() {
17 |
18 | // `ParseFloat`와 함께 이 `64`는 얼마나 많은 비트수가 파싱될 것인지 말해준다.
19 | f, _ := strconv.ParseFloat("1.234", 64)
20 | fmt.Println(f)
21 |
22 | // `ParseInt`에서 `0` 는 means infer the base from the string (번역요구)
23 | // 64는 결과가 64비트에 맞춰질 것을 요구한다.
24 | i, _ := strconv.ParseInt("123", 10, 64)
25 | fmt.Println(i)
26 |
27 | // ParseInt는 hex-형식숫자를 인식한다.
28 | d, _ := strconv.ParseInt("0x1c8", 0, 64)
29 | fmt.Println(d)
30 |
31 | //ParseUint 또한 사용가능하다.
32 | u, _ := strconv.ParseUint("789", 0, 64)
33 | fmt.Println(u)
34 |
35 | //`Atoi` 는 기초적인 10진수 파싱을 위한 편리한 함수이다.
36 | k, _ := strconv.Atoi("135")
37 | fmt.Println(k)
38 |
39 | // 나쁜 입력값에서 파싱함수는 에러를 리턴한다.
40 | _, e := strconv.Atoi("wat")
41 | fmt.Println(e)
42 | }
43 |
--------------------------------------------------------------------------------
/gobyexample/18_구조체.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/structs
4 |
5 | Go by Example: Structs
6 |
7 | Go의 구조체는 필드의 모음형식입니다.
8 | 구조체는 기록을 형성하기 위하여 데이터들을 그룹핑하는 데 유용합니다.
9 | 당신의 프로그램안에서 값과 기록에게 참조를 전달할 수 있다.
10 |
11 | */
12 |
13 | package main
14 |
15 | import "fmt"
16 |
17 | // 이 person 구조체는 name 과 age 필드를 가집니다.
18 | type person struct {
19 | name string
20 | age int
21 | }
22 |
23 | func main() {
24 |
25 | //이 문법은 새로운 구조체를 생성합니다.
26 | fmt.Println(person{"Bob", 20})
27 |
28 | // 구조체를 초기화할 때 당신은 필드명을 사용할 수 있습니다.
29 | fmt.Println(person{name: "Alice", age: 30})
30 |
31 | // 생략된 필드는 제로값이 됩니다.
32 | fmt.Println(person{name: "Fred"})
33 |
34 | // `&` 접두어는 포인터를 구조체에게 넘겨준다. (&prefix yields a pointer to the struct)
35 | fmt.Println(&person{name: "Ann", age: 40})
36 |
37 | //.과 함께 구조체 필드에 접근한다.
38 | s := person{name: "Sean", age: 50}
39 | fmt.Println(s.name)
40 |
41 | // .을 또한 구조체 포인터와 사용할 수 있다. 포인터는 자동으로 참조되게된다.(dereference)
42 | sp := &s
43 | fmt.Println(sp.age)
44 |
45 | // 구조체는 변경 가능하다.
46 | sp.age = 51
47 | fmt.Println(sp.age)
48 | }
49 |
--------------------------------------------------------------------------------
/gobyexample/10_맵.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/maps
4 |
5 | Go by Example: Maps
6 | 맵은 Go의 내장된 연관데이터타입이다(때론 다른 언어에서 해쉬나 dicts 로 불린다)
7 | */
8 | package main
9 |
10 | import "fmt"
11 |
12 | func main() {
13 |
14 | // 빈 맵을 생성하기위해서
15 | // `make(map[키타입]값타입)`.
16 | m := make(map[string]int)
17 |
18 | // 키/값 쌍 값 저장은 다음과 같이 변수명[키]값 문법.
19 | m["k1"] = 7
20 | m["k2"] = 13
21 |
22 | // Println을 하면 맵의 모든 키/값이 나온다.
23 | fmt.Println("map:", m)
24 |
25 | // `name[key]`로 해당 키에 대한 값을 받는다.
26 | v1 := m["k1"]
27 | fmt.Println("v1: ", v1)
28 |
29 | // len 은 키/값 쌍의 갯수를나타낸다.
30 | fmt.Println("len:", len(m))
31 |
32 | // `delete` 는 맵으로 부터 해당 키/값을 지운다.
33 | delete(m, "k2")
34 | fmt.Println("map:", m)
35 |
36 | // 맵으로 부터 다중 리턴을 받는 경우 두번째 값은 이 키에대해서 값이 있는지 없는 지의 여부이다.
37 | // 이 키(k2)에 대한 값이 당장 안쓰기 때문에 생략을 위해 '_'로 쓸 수 있다.
38 | // 이 방법을 사용하므로써, 0이나 "" 같은 zero-value인지 아니면 아예 값이 없는 것인지 구별할 수 있다.
39 | _, prs := m["k2"]
40 | fmt.Println("prs:", prs)
41 |
42 | // 또한 한줄에 선언과 초기화를 할 수 있다.
43 | n := map[string]int{"foo": 1, "bar": 2}
44 | fmt.Println("map:", n)
45 | }
46 |
--------------------------------------------------------------------------------
/effectivego/07_데이터/08_덧붙임append.go:
--------------------------------------------------------------------------------
1 | /*덧붙임(Append)
2 |
3 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
4 |
5 |
6 | 이제 내장함수인 append 함수에 대해 설명하도록 하겠습니다.
7 | append 함수의 특징은 위에 나온 기존의 append 함수와는 좀 다릅니다. 대략 다음과 같습니다:
8 | */
9 |
10 | func append(slice []T, elements...T) []T
11 | /*
12 | T는 어떤 주어진 타입에 대한 위치표시(placeholder) 입니다.
13 | 사실 Go언어에서 호출자에 의해 T 타입이 결정되어지는 함수는 사용할 수 없습니다.
14 | 이 것이 append가 내장함수인 이유입니다.: 그것은 컴파일러의 지원이 필요합니다.
15 | append가 하는 것은 slice의 끝에 요소(element)를 추가하고 결과를 반환하는 것 입니다.
16 | 결과는 반환되어질 필요가 있습니다. 왜냐하면, 우리가 손으로 써서 글에 덧붙이는 것 처럼(append),
17 | 원본 배열이 변경될지도 모르기 때문입니다. 여기 간단한 예제가 있습니다.
18 | */
19 |
20 | x := []int{1,2,3}
21 | x = append(x, 4, 5, 6)
22 | fmt.Println(x)
23 | /*
24 | 위의 예제는 [1 2 3 4 5 6]을 출력 합니다. 따라서, append는 조금은 Printf의 동작과도 비슷하며,
25 | 임의의 개수의 인자들을 취합합니다. 하지만, 만약 slice와 slice를 append하기를 원한다면
26 | 어떻게 해야할까요? 쉽습니다: 위의 예제에서 Output을 호출하듯이, 호출하는 쪽에서 ...을 사용하면
27 | 됩니다. 이렇게 하는 것은 위의 예에서 한것과 동일한 결과를 출력합니다.
28 | */
29 | x := []int{1,2,3}
30 | y := []int{4,5,6}
31 | x = append(x, y...)
32 | fmt.Println(x)
33 | /*
34 | ... 없이는 컴파일이 되지 않습니다. 왜냐하면 타입이 잘못되었기 때문입니다. y는 int 타입이 아닙니다.
35 | */
--------------------------------------------------------------------------------
/gobyexample/15_클로저.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/closures
4 |
5 | Go by Example: Closures
6 |
7 | Go는 익명함수를 지원한다. [_anonymous functions_](http://en.wikipedia.org/wiki/Anonymous_function),
8 | 이것은 클로저로부터 유래되었다. http://en.wikipedia.org/wiki/Closure_(computer_science)
9 | 익명함수는 당신이 이름을 짓지않고 inline으로 함수를 선언할 때 유용하다.
10 | */
11 | package main
12 |
13 | import "fmt"
14 |
15 | // 이 intSeq함수는 intSeq안에 익명으로 정의한 다른 함수를 리턴한다.
16 | // 리턴된 함수는 변수 i 위에서 클로져를 생성하기 위해 닫혀진다? (원문 참고)
17 | //The returned function closes over the variable i to form a closure
18 | func intSeq() func() int {
19 | i := 0
20 | return func() int {
21 | i += 1
22 | return i
23 | }
24 | }
25 |
26 | func main() {
27 |
28 | //우리는 intSeq 이라는 것을 호출하고 결과를 (함수) nextInt 에 할당하였다.
29 | //이 함수는 자신이 가진 i 값을 가지고서 nextInt 가 호출될때마다 그것을 수정한다.
30 | nextInt := intSeq()
31 |
32 | // nextInt를 몇번 호출함으로써 클로저의 효과를 보시라~
33 | fmt.Println(nextInt())
34 | fmt.Println(nextInt())
35 | fmt.Println(nextInt())
36 |
37 | // 상태가 특정 함수에서 유일하다는 것을 확인하자. 새로운 하나를 만들어 테스트해보자.
38 | newInts := intSeq()
39 | fmt.Println(newInts())
40 | }
41 |
--------------------------------------------------------------------------------
/gobyexample/11_레인지.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/range
4 |
5 | Go by Example: range
6 |
7 | _range_ 는 다양한 데이터구조속에서 요소들을 반복한다.
8 | 우리가 이미 배운 데이터구조에서 어떻게 range 를 사용하는지 알아봅시다.
9 | */
10 | package main
11 |
12 | import "fmt"
13 |
14 | func main() {
15 |
16 | // 슬라이스에서 숫자들을 어떻게 합치는지 보여줍니다.
17 | // 배열도 이와 같이 작동합니다.
18 | // 역주) _, num 에서 _은 증가값이고 num은 데이터구조의 요소들입니다.
19 | nums := []int{2, 3, 4}
20 | sum := 0
21 | for _, num := range nums {
22 | sum += num
23 | }
24 | fmt.Println("sum:", sum)
25 |
26 | // 배열과 슬라이스에서의 `range` 는 각각의 요소에, 인덱스(순번)과 값을 제공하며
27 | //인덱스값이 필요하지 않을 때는 _로 생략할 수 있다.
28 | for i, num := range nums {
29 | if num == 3 {
30 | fmt.Println("index:", i)
31 | }
32 | }
33 |
34 | // 맵에서의 range는 키/값 을 돌려줍니다.
35 | kvs := map[string]string{"a": "apple", "b": "banana"}
36 | for k, v := range kvs {
37 | fmt.Printf("%s -> %s\n", k, v)
38 | }
39 |
40 | // 문자열에서의 `range` 는 유니코드 값에서 돌아간다.(역주: 다음에 rune 이 나오는데 뭔지 모르겠음)
41 | // 첫번째 값은 시작하는 the rune의 byte index고
42 | // 두번째값은 the `rune` 그 자신이다.
43 | for i, c := range "go" {
44 | fmt.Println(i, c)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/gobyexample/49_Epoch.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/epoch
4 | Go by Example: epoch
5 |
6 | 프로그램에서 보통 요구사항은 초,밀리세컨, 나노세컨의 개수(the numbers)를 얻는 것이다.
7 | [Unix epoch](http://en.wikipedia.org/wiki/Unix_time) 때문이다.
8 | (역주: 역주는 epoch가 익숙하지가 않다)
9 | 여기 Go에서 어떻게 하는지 예제가 있다.
10 | */
11 |
12 | package main
13 |
14 | import "fmt"
15 | import "time"
16 |
17 | func main() {
18 |
19 | // time.Now를 Unix나 UnixNano와 같이 사용하여서 경과시간을 얻을 수 있다.
20 | // Unix Epoch 가 초나 나노초에 각각 있기 때문이다?
21 | // since the Unix epoch in seconds or nanoseconds, respectively.
22 | now := time.Now()
23 | secs := now.Unix()
24 | nanos := now.UnixNano()
25 | fmt.Println(now)
26 |
27 | // `UnixMillis`가 없다는 것을 명심하자. 그러니 밀리세컨초를 얻자. since 이어서...
28 | //(죄송합니다;)밤인데 졸리네요; 이것만 하면 오늘 끝인지라^^.. 역주..
29 | // since epoch you'll need to manually divide from nanoseconds.
30 | millis := nanos / 1000000
31 | fmt.Println(secs)
32 | fmt.Println(millis)
33 | fmt.Println(nanos)
34 |
35 | //당신은 또한 정수초나 나노세컨초로 변환할 수 있다.
36 | //왜냐하면 epoch는 'time'에 상응할 수 있기 때문이다.
37 | fmt.Println(time.Unix(secs, 0))
38 | fmt.Println(time.Unix(0, nanos))
39 | }
40 |
--------------------------------------------------------------------------------
/packages/net/http/GetJava.java:
--------------------------------------------------------------------------------
1 | package chap15.network;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.io.BufferedReader;
6 | import java.io.InputStreamReader;
7 | import java.net.HttpURLConnection;
8 | import java.net.URL;
9 |
10 | import org.junit.Test;
11 |
12 | public class GetJava {
13 | private final String USER_AGENT = "Mozilla/5.0";
14 | @Test
15 | public void testName() throws Exception {
16 | long start = System.nanoTime();
17 |
18 | URL obj = new URL("http://localhost:9000");
19 | HttpURLConnection con = (HttpURLConnection) obj.openConnection();
20 | con.setRequestMethod("GET");
21 | con.setRequestProperty("User-Agent", USER_AGENT);
22 |
23 | BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
24 | String inputLine;
25 | StringBuffer response = new StringBuffer();
26 |
27 | while ((inputLine = in.readLine()) != null) {
28 | response.append(inputLine);
29 | }
30 | in.close();
31 | System.out.println(response.toString());
32 |
33 | long end = System.nanoTime();
34 | System.out.println( "실행 시간 : " + ( end - start )/1000.0 );
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/gobyexample/42_디퍼.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/defer
4 |
5 | Go by Example: defer
6 |
7 | Defer가 프로그램의 실행 중 함수호출이수행된 후에 cleanup 되었단 것을 보장하기 위해 사용된다.
8 | defer 는 종종 다른 언어에서 finally나 ensure 같은 것처럼 사용된다.
9 | */
10 |
11 | package main
12 |
13 | import "fmt"
14 | import "os"
15 |
16 | // 우리가 새로 파일을 생성하고 작성을 한뒤 우리의 작업을 마치고 닫는다고 가정하자.
17 | // 여기 우리가 어떻게 defer와 함께 그 일을 하는 지 나와있다.
18 | func main() {
19 |
20 | // 파일객체를 createFile로 받은 즉시, 우리는 그 파일을 닫는 것을 'closeFile'와 함께 연기(defer)할 것이다.
21 | // writeFile를 마친 후, 이것을 둘러싼 함수(main함수)가 끝나게 되면서 defer는 실행될 것이다.
22 | f := createFile("/tmp/defer.txt")
23 |
24 | //f := createFile("c:/gocode/defer.txt") 윈도우의 경우 다음과 같이 해보자(역주)
25 | defer closeFile(f)
26 | writeFile(f)
27 | }
28 |
29 | func createFile(p string) *os.File {
30 | fmt.Println("creating")
31 | f, err := os.Create(p)
32 | if err != nil {
33 | panic(err)
34 | }
35 | return f
36 | }
37 |
38 | func writeFile(f *os.File) {
39 | fmt.Println("writing")
40 | fmt.Fprintln(f, "data")
41 |
42 | }
43 |
44 | func closeFile(f *os.File) {
45 | fmt.Println("closing")
46 | f.Close()
47 | }
48 |
49 | // 프로그램을 실행하면 쓰기작업후에 file이 닫혀졌는지 확인한다.
50 |
--------------------------------------------------------------------------------
/gotour/52_포인터리시버를가지는메소드.go:
--------------------------------------------------------------------------------
1 | // 52_포인터리시버를가지는메소드
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "math"
7 | )
8 |
9 | type Vertex struct {
10 | X, Y float64
11 | }
12 |
13 | func (v *Vertex) Scale(f float64) {
14 | v.X = v.X * f
15 | v.Y = v.Y * f
16 | }
17 |
18 | func (v *Vertex) Abs() float64 {
19 | return math.Sqrt(v.X*v.X + v.Y*v.Y)
20 | }
21 |
22 | func main() {
23 | v := &Vertex{3, 4}
24 | v.Scale(5)
25 | fmt.Println(v, v.Abs())
26 | }
27 |
28 | /*
29 | 메소드는 이름이 있는 타입 또는 이름이 있는 타입의 포인터와 연결할 수 있습니다.
30 | 방금 두 개의 Abs 메소드를 보았는데, 하나는 *Vertex 라는 포인터 타입의 메소드고,
31 | 다른 하나는 MyFloat 값 타입의 메소드 입니다.
32 | 포인터 리시버를 사용하는 이유는 두 가지 입니다. 첫째, 메소드가 호출될 때 마다 값이
33 | 복사되는 것(큰 구조체 타입인 경우 값이 복사되는 것은 비효율적이죠)을 방지하기 위함 입니다.
34 | 다른 이유는 메소드에서 리시버 포인터가 가르키는 값을 수정하기 위함 입니다.
35 |
36 | *Vertex 타입의 리시버 대신 Vertex 를 사용하도록 메소드 Abs 와 Scale 의 선언부분을 바꿔 보세요.
37 | v 를 Vertex 타입으로 받으면 Scale 메소드가 더 이상 동작하지 않습니다. Scale 은 v 를 바꾸는데,
38 | v 가 (포인터가 아닌) 값 타입이기 때문에 Vertex 타입인 복사본에 작업을 하기 때문에 원래의 값은 바뀌지 않습니다.
39 | Abs 의 경우는 다릅니다. 여기서는 v 를 읽기만 하기 때문에,
40 | (포인터가 가르키는) 원래의 값이건 복사본이건 상관이 없게 됩니다.
41 |
42 | Written by arahansa
43 | https://www.facebook.com/groups/golangko/
44 | 모든 내용은 http://go-tour-kr.appspot.com/
45 | */
46 |
--------------------------------------------------------------------------------
/effectivego/07_데이터/01_new를사용한데이터할당.go:
--------------------------------------------------------------------------------
1 | /*
2 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
3 |
4 | new()를 사용한 메모리 할당(Allocation with new())
5 | Go언어에서는 new()와 make(), 두가지 메모리 할당 원형이 있습니다.
6 | new()와 make()는 서로 다르게 동작하며 다른 형태로 적용되어 지기 때문에 혼란스러울 수 있습니다.
7 | 하지만 규칙은 단순합니다. 먼저 new()에 대해서 얘기하자면, new()는 다른 언어들에서와 마찬가지로
8 | 기본적으로 탑재되어 있는 함수 입니다.:
9 | new(T)는 새로운 아이템 T를 위해 크기 0의 저장공간을 할 당할 것이며,
10 | *T 타입의 값을 가지고 있는 할당된 공간의 주소를 리턴할 것입니다.
11 |
12 | Go 용어로 말하자면, new(T)는 새로 할당된 0 값의 타입 T에 대한 포인터를 리턴할 것입니다.
13 |
14 | new()에 의해 반환된 메모리는 0 이기 때문에 객체는 추가적인 초기화없이 사용될 수 있습니다.
15 | 이것은 자료구조의 사용자가 new()로 하나를 새롭게 만들 수 있고 바로 작업할 수 있다는 것을 의미합니다.
16 | 예를 들어, bytes.Buffer문을 위해 주석을 단다면 "0값의 Buffer는 사용준비가 되어진 비어있는 buffer 입니다"라고 할 수 있습니다.
17 | 비슷하게, sync.Mutex는 분명한 생성자나 초기화 메소드를 가지고 있지 않습니다.
18 | 대신 sync.Mutex를 위한 0값은 mutex를 해제하기 위해 정의되어져 있습니다.
19 |
20 | zero 값이 유용하다는 속성은 타동적으로 동작합니다. 이런 형태의 정의를 고려해보십시오.
21 | */
22 | type SyncedBuffer struct {
23 | lock sync.Mutex
24 | buffer bytes.Buffer
25 | }
26 | /*
27 | SyncedBuffer? 타입의 값들은 할당 또는 정의된 즉시 사용할 준비가 되어져 있습니다.
28 | 다음에서 p와 v는 추가적인 처리 없이 정확히 동작할 것입니다.
29 | */
30 | p := new(SyncedBuffer) // type *SyncedBuffer
31 | var v SyncedBuffer // type SyncedBuffer
--------------------------------------------------------------------------------
/gobyexample/36_아토믹카운터.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/atomic-counters
4 |
5 | Go by Example: Atomic Counters
6 |
7 | Go에서 상태를 관리하는 주요 메커니즘은 채널을 통해 커뮤니케이션하는 것이다.
8 | 우리는 예제 worker-pool를 통해서 이러한 것들을 보았다.
9 | 그러나 다른 몇가지 옵션들이 있는데, 여기서 sync/atomic 패키지를 사용하는
10 | 멀티플고루틴에 의해 접근되는 atomic 카운터를 한번 살펴보겠다.
11 | */
12 |
13 | package main
14 |
15 | import "fmt"
16 | import "time"
17 | import "sync/atomic"
18 | import "runtime"
19 |
20 | func main() {
21 |
22 | //우리의 카운터를 위하여 unsigned integer 를 사용하겠다.
23 | var ops uint64 = 0
24 |
25 | //동시적 업데이터를 가정하기 위해서, 우리는 50개의 고루틴을 시작할 것이고
26 | //우리의 고루틴들은 1밀리세컨드 당 카운터를 각각 증가시킬 것이다.
27 | for i := 0; i < 50; i++ {
28 | go func() {
29 | for {
30 | // 원자적으로 카운터를 증가시키기 위해 우리는 AddUint64를 쓸 것이며 ops의 메모리주소를 &와 함께 줄 것이다.
31 | atomic.AddUint64(&ops, 1)
32 |
33 | // 다른 고루틴들이 처리되도록 허용한다.
34 | runtime.Gosched()
35 | }
36 | }()
37 | }
38 |
39 | // 몇몇 ops 가 모여지기를 허용하기 위해 1초 기다린다.
40 | time.Sleep(time.Second)
41 |
42 | // 다른 고루틴에 의해 업데이트 될 동안 안전하게 카운터를 사용하기 위해,
43 | // LoadUint64를 통하여 현재값의 복사본을 opsFinal로 추출한다.
44 | // 위에서 우리는 이 함수에게 값을 전송할 &ops메모리 주소를 주었다.
45 | opsFinal := atomic.LoadUint64(&ops)
46 | fmt.Println("ops:", opsFinal)
47 | }
48 |
--------------------------------------------------------------------------------
/packages/net/01_TCP서버.go:
--------------------------------------------------------------------------------
1 | /*
2 | 출처: https://coderwall.com/p/wohavg/creating-a-simple-tcp-server-in-go
3 | */
4 | package main
5 |
6 | import (
7 | "fmt"
8 | "net"
9 | "os"
10 | )
11 |
12 | const (
13 | CONN_HOST = "localhost"
14 | CONN_PORT = "3333"
15 | CONN_TYPE = "tcp"
16 | )
17 |
18 | func main() {
19 | //들어오는 접속에 대하여 대기함.
20 | l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
21 | if err != nil {
22 | fmt.Println("Error listening:", err.Error())
23 | os.Exit(1)
24 | }
25 | // 프로그램이 닫힐때 리스너도 끈다.
26 | defer l.Close()
27 | fmt.Println("Listening on " + CONN_HOST + ":" + CONN_PORT)
28 | for {
29 | // 들어오는 접속을 받는다.
30 | conn, err := l.Accept()
31 | if err != nil {
32 | fmt.Println("Error accepting: ", err.Error())
33 | os.Exit(1)
34 | }
35 | // 새로운 Go루틴에서 접속을 다룬다.
36 | go handleRequest(conn)
37 | }
38 | }
39 |
40 | //들어오는 요청을 다룬다.
41 | func handleRequest(conn net.Conn) {
42 | // 들어오는 데이터를 보관할 버퍼생성
43 | buf := make([]byte, 1024)
44 | // 들어오는 접속을 버퍼로 해서 읽음?
45 | reqLen, err := conn.Read(buf)
46 | if err != nil {
47 | fmt.Println("Error reading:", err.Error())
48 | }
49 | // 접속한 사람에게 응답을 돌려보낸다.
50 | conn.Write([]byte("Message received."))
51 | // 일을 다 하면 접속을 닫는다.
52 | conn.Close()
53 | }
54 |
--------------------------------------------------------------------------------
/gobyexample/55_Base64인코딩.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/base64-encoding
4 | Go by Example: base64-encoding
5 |
6 | Go는 base64를 위한 내장형 지원을 제공한다.
7 | */
8 |
9 | package main
10 |
11 | // 이 구문은 `encoding/base64`패키지를 디폴트값(base64)가 아닌 b64라는 이름으로 임포트 한다.
12 | // 그것은 우리에게 공간을 좀 줄여주게 할 것이다.
13 | import b64 "encoding/base64"
14 | import "fmt"
15 |
16 | func main() {
17 |
18 | // 여기 우리가 인코드/디코드할 문자열이 있다
19 | data := "abc123!?$*&()'-=@~"
20 |
21 | // Go는 표준과 URL호환 base64둘다 지원한다.
22 | // 여기 어떻게 표준인코더를 사용하여서 어떻게 인코드하는지 나와있다.
23 | // Encoder는 []byte를 필요로 하기 때문에 우리는 문자열을 바이트 타입으로 형변환할 것이다.
24 | sEnc := b64.StdEncoding.EncodeToString([]byte(data))
25 | fmt.Println(sEnc)
26 |
27 | // 디코딩은 아마 에러를 리턴할 것이고, 그 에러를 가지고서
28 | // 당신이 이미 잘 적혀진 입력값을 모르고 있는지 체크할 수 있다.
29 | // Decoding may return an error, which you can check
30 | // if you don't already know the input to be well-formed.
31 | sDec, _ := b64.StdEncoding.DecodeString(sEnc)
32 | fmt.Println("sdec:", string(sDec))
33 | fmt.Println()
34 |
35 | // 이것은 base64형식의 URL호환인코딩디코딩이다.
36 | uEnc := b64.URLEncoding.EncodeToString([]byte(data))
37 | fmt.Println(uEnc)
38 | uDec, _ := b64.URLEncoding.DecodeString(uEnc)
39 | fmt.Println(string(uDec))
40 | }
41 |
--------------------------------------------------------------------------------
/gobyexample/34_워커풀.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/worker-pools
4 | Go by Example: worker-pools
5 |
6 |
7 | 이 예제에서 우리는 어떻게 go루틴과 채널을 이용하여 worker pool을 구현할지 살펴보자.
8 | */
9 |
10 | package main
11 |
12 | import "fmt"
13 | import "time"
14 |
15 | //여기 worker 가 있는데 우리는 동시성 인스턴스 몇가지를 실행시킬 것이다.
16 | //이러한 worker들은 jobs채널로부터 work를 받아서 그에 상응하는 results를 보낼 것이다.
17 | //우리는 처리하는데 시간이 걸리는(expensive)한 job이란 시뮬레이션을 하기 위해 job한개당 일초간 Sleep 할 것이다.
18 | func worker(id int, jobs <-chan int, results chan<- int) {
19 | for j := range jobs {
20 | fmt.Println("worker", id, "processing job", j)
21 | time.Sleep(time.Second)
22 | results <- j * 2
23 | }
24 | }
25 |
26 | func main() {
27 |
28 | // workers의 pool을 사용하기 위해 우리는 그들에게 work를 보내고 그들의 결과를 모을 것이다.
29 | //우리는 이를 위해 2개의 채널을 만들 것이다.
30 | jobs := make(chan int, 100)
31 | results := make(chan int, 100)
32 |
33 | // 이것은 3 개의 workers를 실행시킬 것이고 처음엔 아무 jobs도 없기 때문에 블락될것이다.
34 | for w := 1; w <= 3; w++ {
35 | go worker(w, jobs, results)
36 | }
37 |
38 | //여기 우리는 9개의 jobs를 보내고 이것이 우리가 가진 모든 work란 것을 알리기 위해 저 채널을 닫을 것이다.
39 | for j := 1; j <= 9; j++ {
40 | jobs <- j
41 | }
42 | close(jobs)
43 | //마침내 우리는 work의 모든 결과들을 모을 것이다.
44 | for a := 1; a <= 9; a++ {
45 | <-results
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/gobyexample/29_논블록킹채널운영.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/non-blocking-channel-operations
4 | Go by Example: non-blocking-channel-operations
5 |
6 | 채널에서 기초적인 전송과 수신은 블록킹이다.
7 | 그러나, 우리는 select를 'default' 문과 같이 써서, 논블록킹 전송과 수신,
8 | 심지어 논블록킹 멀티 select를 구현할 수 있다.
9 |
10 | */
11 |
12 | package main
13 |
14 | import "fmt"
15 |
16 | func main() {
17 | messages := make(chan string)
18 | signals := make(chan bool)
19 |
20 | // 여기 논블록킹 수신이 있다. 만약 값이 message에서 사용가능하면
21 | // 셀렉트는 <-message 케이스를 값과 함께 선택할것이지만 그렇지 않다면
22 | //이것은 즉시 default 를 선택할 것이다.
23 | select {
24 | case msg := <-messages:
25 | fmt.Println("received message", msg)
26 | default:
27 | fmt.Println("no message received")
28 | }
29 |
30 | // 논블록킹 전송은 비슷하게 작동한다.
31 | msg := "hi"
32 |
33 | select {
34 | case messages <- msg:
35 | fmt.Println("sent message", msg)
36 | default:
37 | fmt.Println("no message sent")
38 | }
39 |
40 | //우리는 멀티웨이 논블록킹 셀렉트를 구현하기 위해
41 | // default 위에 멀티플 case를 사용할 수 있다.
42 | //여기에선 message와 signals 둘다에서 논블록킹 수신을 시도한다.
43 | select {
44 | case msg := <-messages:
45 | fmt.Println("received message", msg)
46 | case sig := <-signals:
47 | fmt.Println("received signal", sig)
48 | default:
49 | fmt.Println("no activity")
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/effectivego/06_함수/01_다중리턴값.go:
--------------------------------------------------------------------------------
1 | /*
2 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
3 | 다중 리턴 값(Multiple return values)
4 | Go언어에서 특이한 점 중에 하나는 함수와 메소드가 여러개의 값을 리턴할 수 있다는 것입니다.
5 | 이런 형태는 C 프로그램에서 몇몇 어색한 구문들을 개선하는데 사용될 수 있습니다.
6 | : in-band 에러 리턴(EOF를 위한 -1과 같은) 과 argument의 수정
7 |
8 | C언어에서 쓰기 에러는 임시 주소에서 에러 코드와 함께 음의 숫자로 표현됩니다.
9 | Go언어에서는 숫자와 에러를 리턴할 수 있습니다
10 | :"몇몇 byte를 쓸 수 있지만 그렇게하면 device 전체 공간을 체우게될 수도 있기 때문에 전부 다 쓸 수는 없습니다."
11 | os 패키지에서 *File.Write의 signature는 다음과 같습니다.
12 | */
13 |
14 | func (file *File) Write(b []byte) (n int, err Error)
15 | /*
16 | 그리고 문서에서 말하는 것 처럼, 이 함수는 쓰여진 byte의 수와 n != len(b)인 경우
17 | non-nil 에러를 리턴할 것 입니다. 이것은 일반적인 형태입니다;
18 |
19 | 더 많은 예제를 확인하고 싶으면 error handling section을 참고하십시오.
20 |
21 | 비슷한 접근법으로 parameter들을 참조하기 위해 리턴 값으로 부터 포인터를 사용하는 것을 피할 수 있습니다.
22 | 다음은 byte array의 한 위치로 부터 숫자를 리턴하고 다음 위치로 이동하기 위한 간단한 함수 예제입니다.
23 | */
24 | func nextInt(b []byte, i int) (int, int) {
25 | for ; i < len(b) && !isDigit(b[i]); i++ {
26 | }
27 | x := 0
28 | for ; i < len(b) && isDigit(b[i]); i++ {
29 | x = x*10 + int(b[i])-'0'
30 | }
31 | return x, i
32 | }
33 | /*
34 | 입력된 배열에서 숫자를 검색하기 위해 다음과 같이 할 수 있습니다.
35 | */
36 | for i := 0; i < len(a); {
37 | x, i = nextInt(a, i)
38 | fmt.Println(x)
39 | }
40 |
--------------------------------------------------------------------------------
/gobyexample/28_타임아웃.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/timeouts
4 | Go by Example: timeouts
5 |
6 | Timeout은 프로그램이 외부자원에 접근하거나 실행시간을 bound하기 위해 중요하다.
7 | 채널과 셀렉트 덕분에 Go에서 timeout을 구현하는 것은 쉽고 우아하다.
8 |
9 | */
10 |
11 | package main
12 |
13 | import "time"
14 | import "fmt"
15 |
16 | func main() {
17 |
18 | //예제를 위해 2촛후에 c1 채널에 그것의 값을 리턴하는 외부호출을 실행하는 것으로 가정한다.
19 | c1 := make(chan string, 1)
20 | go func() {
21 | time.Sleep(time.Second * 2)
22 | c1 <- "result 1"
23 | }()
24 |
25 | // 여기 timeout을 구현하는 select문이 있다.
26 | // res:= <-c1 은 값을 기다리고, <-Time.After 는 1초후에 값이 전송되기를 기다린다.
27 | // select 가 첫번째 receive와 함께 진행되기 때문에,
28 | // 프로그램이 허용된 1초를 넘을 경우 우리는 timeoutcase를 실행할 수 있다.
29 | // (역주 : 기다리기도하면서 타임아웃도 잰다는 뜻같다)
30 | select {
31 | case res := <-c1:
32 | fmt.Println(res)
33 | case <-time.After(time.Second * 1):
34 | fmt.Println("timeout 1")
35 | }
36 |
37 | //만약 우리가 더 긴시간인 3초의 타임아웃을 허용할 경우는 c2로부터 값을 받는 것은 성공할 것이고.
38 | //그 결과를 출력할 것이다.
39 | c2 := make(chan string, 1)
40 | go func() {
41 | time.Sleep(time.Second * 2)
42 | c2 <- "result 2"
43 | }()
44 | select {
45 | case res := <-c2:
46 | fmt.Println(res)
47 | case <-time.After(time.Second * 3):
48 | fmt.Println("timeout 2")
49 | }
50 | }
51 |
52 | // todo: cancellation?
53 |
--------------------------------------------------------------------------------
/effectivego/04_세미콜론.go:
--------------------------------------------------------------------------------
1 |
2 |
3 | /*
4 | https://code.google.com/p/golang-korea/wiki/EffectiveGo#Semicolons
5 |
6 |
7 | Semicolons
8 | C언어 처럼 Go언어의 정규화된 문법은 한 문장을 끝내기 위해 세미콜론(;)을 사용합니다.
9 | 하지만 C언어와는 다르게 세미콜론들은 소스코드 상에는 나타나지 않습니다.
10 | 대신 구문분석기(lexer)는 스캔하듯이 자동으로 세미콜론을 넣기 위해 단순한 규칙을 사용합니다.
11 | 그렇기 때문에 코드를 작성하는데 있어 대부분 세미콜론을 사용할 필요가 없습니다.
12 |
13 | 규칙은 다음과 같습니다. 새로운 라인 앞에 마지막 token이 구분자(int또는 float64, 숫자 또는 문자상수
14 | 또는 token의 하나와 같은 기본적인 문자를 포함해서)가 됩니다.
15 |
16 | break continue fallthrough return ++ -- ) }
17 | 구문분석기(lexer)는 항상 token뒤에 세미콜론을 추가합니다.
18 | 이것은 "만약 새로운 라인이 어떤 token뒤에 온다면 문장의 끝을 의미하며
19 | 세미콜론을 추가해라"라고 축약해서 말하는 것과 같습니다.
20 |
21 | 또한, 세미콜론은 중괄호({}) 앞인 경우는 생략될 수 있습니다.
22 | 아래 예에서 보는 것과 같이 세미콜론이 필요하지 않습니다.
23 | */
24 |
25 | go func() { for { dst <- <-src } }()
26 | /*
27 | Go언어의 문법에서는 오직 for 루프문에서만 초기화와 condition, continuation 요소를 구분하기 위해
28 | 세미콜론을 사용합니다. 또한 한 라인에서 여러개의 문장을 구분하기 위해서는 세미콜론을 사용합니다.
29 |
30 | 한가지 주의할 점은, 제어문(if, for, switch, select)에서 제어문 다음 라인에 중괄호({)를 사용하면
31 | 안된다는 것 입니다. 만약 그렇게 하면 제어문의 중괄호({) 앞에
32 | 세미콜론이 추가될 것이며 예상하지 못한 결과를 가져오게 될 것 입니다.
33 |
34 | 예로 아래와 같이 사용하십시요.
35 | */
36 | if i < f() {
37 | g()
38 | }
39 | /*다음과 같이 사용하면 안됩니다.*/
40 |
41 | if i < f() // wrong! (<-- lexer는 이부분에 세미콜론을 추가하게 될 것입니다.)
42 | { // wrong!
43 | g()
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/gobyexample/57_파일쓰기.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/writing-files
4 | Go by Example: writing-files
5 |
6 | GO에서 파일을 쓰는 것은 이전에 본 읽기와 비슷하다.
7 | */
8 |
9 | package main
10 |
11 | import (
12 | "bufio"
13 | "fmt"
14 | "io/ioutil"
15 | "os"
16 | )
17 |
18 | func check(e error) {
19 | if e != nil {
20 | panic(e)
21 | }
22 | }
23 |
24 | func main() {
25 |
26 | //시작하기 위해, 여기 어떻게 문자열을 파일로 저장하는지 나타있다
27 | d1 := []byte("hello\ngo\n")
28 | err := ioutil.WriteFile("/tmp/dat1", d1, 0644)
29 | check(err)
30 |
31 | // 더 다른 방법의 쓰기를 위해서, 쓰기를 위해 파일을 열어보겠다
32 | f, err := os.Create("/tmp/dat2")
33 | check(err)
34 |
35 | // 관용적으로 defer를 써서 파일을 연 후에 닫아주도록 한다.
36 | defer f.Close()
37 |
38 | // 당신이 예상한대로 바이트슬라이스를 Write한다.
39 | d2 := []byte{115, 111, 109, 101, 10}
40 | n2, err := f.Write(d2)
41 | check(err)
42 | fmt.Printf("wrote %d bytes\n", n2)
43 |
44 | // WriteString또한 사용가능하다.
45 | n3, err := f.WriteString("writes\n")
46 | fmt.Printf("wrote %d bytes\n", n3)
47 |
48 | // `Sync` 는 안정된 공간에 쓸 것을 플러쉬한다.
49 | f.Sync()
50 |
51 | // bufio는 이전에 본 버퍼된 리더같은 버퍼된 라이터를 제공한다.
52 | w := bufio.NewWriter(f)
53 | n4, err := w.WriteString("buffered\n")
54 | fmt.Printf("wrote %d bytes\n", n4)
55 |
56 | //Flush를 써서 버퍼된 작업들이 writer에 적용될 수 있도록 보장하자.
57 | w.Flush()
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/gobyexample/30_채널닫기.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/closing-channels
4 | Go by Example: closing-channels
5 |
6 | 채널을 닫는 것은 더이상 어떤 값도 그것으로 보내지지 않을 것이란 것을 가리킨다.
7 | 이것은 채널의 리시버와 통신은 완료하는데 유용하다.
8 | 여기서 worker는 따로 일하는 고루틴을 말하는 듯하다(역주)
9 | */
10 |
11 | package main
12 |
13 | import "fmt"
14 |
15 | // 이 예제에서, 우리는 jobs 채널을 이용하여 main() 고루틴으로부터 work고루틴으로 작업이 완료되었다고
16 | // 통신할 것이다. worker로 할일이 더 이상 없다면 우리는 jobs채널을 닫을 것이다.
17 |
18 | func main() {
19 | jobs := make(chan int, 5)
20 | done := make(chan bool)
21 |
22 | //여기예 worker고루틴이 있다. 이것은 반복적으로 jobs로부터 j를, more는 jobs를 수신한다.
23 | // 이 특별할 2개의 값수신을 하면서 모든 작업을 완료되어 jobs가 close됬을 때
24 | //more의 값은 false가 될 것이다.
25 | //우리는 우리의 모든 작업을 했을 때, done'채널에 이것을 알리기 위해 이것을 사용한다.
26 | go func() {
27 | for {
28 | j, more := <-jobs
29 | if more {
30 | fmt.Println("received job", j)
31 | } else {
32 | fmt.Println("received all jobs")
33 | done <- true
34 | return
35 | }
36 | }
37 | }()
38 |
39 | // 이것은 세개의 jobs를 jobs채널을 이용하여 worker에게 전송하고 jobs채널을 닫는다.
40 | for j := 1; j <= 3; j++ {
41 | jobs <- j
42 | fmt.Println("sent job", j)
43 | }
44 | close(jobs)
45 | fmt.Println("sent all jobs")
46 |
47 | //worker가 이전에 본 [synchronization](channel-synchronization)접근을 이용하여
48 | //기다리는 것을 볼 수 있다.
49 | <-done
50 | }
51 |
--------------------------------------------------------------------------------
/effectivego/07_데이터/03_make를사용한메모리할당.go:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
4 |
5 |
6 | 메모리 할당으로 다시 돌아가보면, 내장함수 make(T, args)는 new(T)와는 다른 기능을 제공합니다.
7 | make()는 slice, map, channel을 만드는 용도로만 사용됩니다.
8 | 또, *T가 아니라 T 타입의 초기 값(초기값은 0이 아님)을 반환합니다.
9 | 구분해야하는 이유는 숨겨져있고, 사용전에 반드시 초기화되어야 하는 자료 구조를 참조하는 이러한 세가지 형태가 있기 때문입니다..
10 | slice를 예로 들어보면, slice는 데이타(배열 내부)에 대한 포인터, 길이, 용량의 세가지 아이템을 가지고 있는 descriptor이고,
11 | 아이템들이 초기화되기 전까지 slice는 nil입니다.
12 | make()는 slice, map, channel의 내부 데이터 구조를 초기화하고 사용할 수 있도록 해줍니다. 예를 들면,
13 |
14 | */
15 |
16 | make([]int, 10, 100)
17 | /*
18 | 위의 예문은 100개의 int 배열을 위해 메모리 할당을 하고 배열의 처음 10개 요소를 가리키는
19 | 길이 10, 용량 100을 가지는 slice 구조를 만듭니다.
20 | (slice를 만들 때, 용량은 생략될 수 있습니다.; 더 많은 정보를 원하면 slice 섹션을 보기 바랍니다.) .
21 | 반면, {{{new(int)는 새롭게 할당된, 0값의 slice 구조에 대한 포인터를 반환합니다. (즉, nil slice에 대한 포인터를 의미함)
22 |
23 | 다음 예제는 new()와 make()의 차이점에 대해서 설명해줍니다.
24 | */
25 | var p *[]int = new([]int) // slice구조를 할당함; *p == nil; 그다지 유용하지 않음
26 | var v []int = make([]int, 100) // slice v는 이제 100개의 int를 가지는 새로운 배열을 참조함
27 |
28 | // 불필요하게 복잡함:
29 | var p *[]int = new([]int)
30 | *p = make([]int, 100, 100)
31 |
32 | // 자연스러움:
33 | v := make([]int, 100)
34 | /*
35 | 꼭 기억해야할 것은 make()는 오직 map, slice, channel을 위해서만 적용가능하다는 것이며,
36 | 포인터를 반환하지 않습니다. 따라서, 분명한 포인터 값을 얻기 위해서는 new()를 사용해야 합니다.
37 |
38 | */
--------------------------------------------------------------------------------
/gotour/70_연습_동등한이진트리.go:
--------------------------------------------------------------------------------
1 | // 70_연습_동등한이진트리
2 | package main
3 |
4 | import "code.google.com/p/go-tour/tree"
5 |
6 | // Walk walks the tree t sending all values
7 | // from the tree to the channel ch.
8 | func Walk(t *tree.Tree, ch chan int)
9 |
10 | // Same determines whether the trees
11 | // t1 and t2 contain the same values.
12 | func Same(t1, t2 *tree.Tree) bool
13 |
14 | func main() {
15 | }
16 |
17 | /*
18 | 노드(leaf)들에 있는 값들의 정렬 순열는 같지만 생김새가 다른 이진트리가 있을 수 있습니다.
19 | 예를들어, 다음 그림의 두 이진 트리를 정렬 순열는 1, 1, 2, 3, 5, 8, 13 으로 같습니다.
20 |
21 | 대부분의 프로그래밍 언어에서 두 이진 트리가 같은 순열인지를 검사하는 함수의 구현은 복잡합니다.
22 | 이제 고의 동시성과 채널을 사용한 단순한 방법으로 해결해 봅시다.
23 |
24 | 이 예제는 다음의 Tree 구조체가 정의된 tree 패키지를 사용합니다.
25 |
26 | type Tree struct {
27 | Left *Tree
28 | Value int
29 | Right *Tree
30 | }
31 |
32 | 1. Walk 함수를 구현하세요.
33 |
34 | 2. Walk 함수를 테스트 해 보세요.
35 |
36 | 함수 `tree.New(k)`는 k , 2k , 3k , ..., 10k 의 값을 가지는, 무작위로 구성된 이진트리를 만들어 냅니다.
37 |
38 | 채널 ch 를 만들고, 작성한 Walk 함수의 인자로 넣어 줍니다.
39 |
40 | go Walk(tree.New(1), ch)
41 | 이제 채널에서 10개의 값을 읽어 봅니다. 읽힌 값은 1, 2, 3, ..., 10 이어야 합니다.
42 |
43 | 3. Walk 함수를 사용해 두 트리 t1 과 t2 이 값은 값들을 가지고 있는지 비교하는 Same 함수를 구현해 보세요.
44 |
45 | 4. Same 함수를 테스트 해 보세요.
46 |
47 | `Same(tree.New(1),`tree.New(1))`의 수행결과는 true, `Same(tree.New(1),`tree.New(2))`의 수행 결과는 false 이어야 합니다.
48 |
49 |
50 | Written by arahansa
51 | https://www.facebook.com/groups/golangko/
52 | 모든 내용은 http://go-tour-kr.appspot.com/
53 | */
54 |
--------------------------------------------------------------------------------
/gobyexample/53_Url파싱.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/url-parsing
4 | Go by Example: url-parsing
5 |
6 | url은 자원(resource)들을 위치(locate)시키는 한결같은 방법을 제공한다.
7 | 여기 Go에서 URL을 어떻게 파싱하는지 나와있다.
8 | */
9 | package main
10 |
11 | import "fmt"
12 | import "net/url"
13 | import "strings"
14 |
15 | func main() {
16 |
17 | //우리는 스키마, 인증정보, 호스트, 포스,경로 , 쿼리 파라미터와 쿼리조각등을 가지고 있는, 이 예제 URL을 파싱할 것이다.
18 | s := "postgres://user:pass@host.com:5432/path?k=v#f"
19 |
20 | // URL을 파싱하고 에러가 없단 것을 보장한다.
21 | u, err := url.Parse(s)
22 | if err != nil {
23 | panic(err)
24 | }
25 |
26 | // 스키마에 접근하는 것은 간단하다.
27 | fmt.Println(u.Scheme)
28 |
29 | // User는 모든 인증정보를 포함한다.
30 | // 여기서 개인적인 값을 위해 Username과 Password 를 호출한다.
31 | fmt.Println(u.User)
32 | fmt.Println(u.User.Username())
33 | p, _ := u.User.Password()
34 | fmt.Println(p)
35 |
36 | // Host 는 호스트네임과 포트를 포함하고 만약 존재하면 수동으로 포트와 호스트를 추출해야한다. (배열씀)
37 | fmt.Println(u.Host)
38 | h := strings.Split(u.Host, ":")
39 | fmt.Println(h[0])
40 | fmt.Println(h[1])
41 |
42 | // 여기 우리는 경로와 조각을 #이후로 추출한다.
43 | fmt.Println(u.Path)
44 | fmt.Println(u.Fragment)
45 |
46 | // `k=v`형식의 문자열에서 쿼리 파라미터를 얻기 위해
47 | // RawQuery를 사용한다. 당신은 또한 쿼리파라미터들을 맵으로 파싱한다.
48 | // 문자열슬라이스나 문자열로부터 파싱된 쿼리파라미터맵으로 파싱되며 만약 첫번째 값을 얻고 싶으면 index값은 [0]이다.
49 | fmt.Println(u.RawQuery)
50 | m, _ := url.ParseQuery(u.RawQuery)
51 | fmt.Println(m)
52 | fmt.Println(m["k"][0])
53 | }
54 |
--------------------------------------------------------------------------------
/gobyexample/44_문자열함수.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/string-functions
4 |
5 | Go by Example: string-functions
6 |
7 | 표준라이브러리의 string 패키지는 많은 유용한 문자열관련함수를 제공하는데
8 | 여기에 패키지에 대한 이해를 도울만한 예제를 제공한다.
9 | */
10 |
11 | package main
12 |
13 | import s "strings"
14 | import "fmt"
15 |
16 | // 우리는 fmt.Println을 짧은 별명을 지어서 밑에와 같이 많이 사용할 수 있다
17 | var p = fmt.Println
18 |
19 | func main() {
20 |
21 | // 여기 문자열에서 사용가능한 함수예제가 있다.
22 | // string패키지에서 온 이러한 모든 함수는 string객체 자신의 메소드가 아니란 것을 주의하자.
23 | // 이것은 질문(밑의 HasPrefix등등을 말하는 듯 : 역주)에서
24 | // 문자열을 함수의 첫번째 아규먼트로 전달해야 된다는 것을 의미한다.
25 |
26 | p("Contains: ", s.Contains("test", "es"))
27 | p("Count: ", s.Count("test", "t"))
28 | p("HasPrefix: ", s.HasPrefix("test", "te"))
29 | p("HasSuffix: ", s.HasSuffix("test", "st"))
30 | p("Index: ", s.Index("test", "e"))
31 | p("Join: ", s.Join([]string{"a", "b"}, "-"))
32 | p("Repeat: ", s.Repeat("a", 5))
33 | p("Replace: ", s.Replace("foo", "o", "0", -1))
34 | p("Replace: ", s.Replace("foo", "o", "0", 1))
35 | p("Split: ", s.Split("a-b-c-d-e", "-"))
36 | p("ToLower: ", s.ToLower("TEST"))
37 | p("ToUpper: ", s.ToUpper("test"))
38 | p()
39 |
40 | //당신은 좀더 많은 함수를 docs에서 찾을 수 있다. (http://golang.org/pkg/strings/)
41 |
42 | // string의 부분은 아니지만 언급할만한 가치가 있는 메커니즘은 string의 길이를 구하는 것과
43 | // index로 문자를 얻는 것이다.
44 |
45 | p("Len: ", len("hello"))
46 | p("Char:", "hello"[1])
47 | }
48 |
--------------------------------------------------------------------------------
/gobyexample/40_Function정렬.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/sorting-by-functions
4 |
5 | Go by Example: Sorting by Functions
6 |
7 | 때떄로 우리는 정렬된 순서와는 다른 것으로 콜렉션을 정렬하고 싶다.
8 | 예를 들자면 우리가 문자열을 그들의 알파벳이 아닌 길이로 정렬하고 싶다고 하자.
9 | 여기 Go에서 커스텀 Sort의 예제가 있다.
10 | */
11 |
12 | package main
13 |
14 | import "sort"
15 | import "fmt"
16 |
17 | // Go에서 커스텀펑션으로 정렬하기위해 우리는 그에 맞는 타입이 필요하다.
18 | // 단지 []string 타입의 다른 이름일 뿐인 ByLength라는 타입을 만들었다.
19 | type ByLength []string
20 |
21 | // 우리는 sort.Interface- Len, Less, Swap 을 구현했다. - 우리의 타입에서
22 | // 우리는 sort 패키지의 일반적인 Sort 함수를 사용할 수 있을 것이다.
23 | // Len과 Swap은 일반적으로 비슷하고 Less는 실제 커스텀 정렬 로직을 가지고 있다.
24 | // (Len` and `Swap` will usually be similar across types : 참고)
25 | // 우리의 경우, 우리는 길이에 따라 정렬하기를 원하므로 우리는 len(s[i])와 len(s[j])를 여기선 사용할 것이다.
26 | func (s ByLength) Len() int {
27 | return len(s)
28 | }
29 | func (s ByLength) Swap(i, j int) {
30 | s[i], s[j] = s[j], s[i]
31 | }
32 | func (s ByLength) Less(i, j int) bool {
33 | return len(s[i]) < len(s[j])
34 | }
35 |
36 | // 준비된 이것들과 함께, 원본 'fruits'를 ByLength로 형변환하면서 우리의 커스텀정렬을 해볼 것이다.
37 | // 그리고 타입슬라이스에 sort.Sort를 이용할 것이다.
38 | func main() {
39 | fruits := []string{"peach", "banana", "kiwi"}
40 | sort.Sort(ByLength(fruits))
41 | fmt.Println(fruits)
42 | }
43 |
44 | // 우리가 의도한 대로 우리의 프로그램은 정렬된 리스트를 보여줄 것이다.
45 | // 커스텀타입을 생성하는 이와같은 패턴을 따르면서, 저 타입에 세가지 Interface메소드를 구현하고
46 | // 저 커스텀타입콜렉션에 sort.Sort 를 호출하여서 우리는 임의의 함수로 Go slice를 정렬할 수 있다
47 |
--------------------------------------------------------------------------------
/gobyexample/48_시간.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/time
4 | Go by Example: time
5 |
6 | Go는 광범위한 시간과 간격(시간차)에 관한 지원을 제공하며, 여기 예제가 있다.
7 | */
8 |
9 | package main
10 |
11 | import "fmt"
12 | import "time"
13 |
14 | func main() {
15 | p := fmt.Println
16 |
17 | //우리는 현재 시간을 얻음으로써 시작한다.
18 | now := time.Now()
19 | p(now)
20 |
21 | // 우리는 time구조체를 년, 월, 날짜 등등을 제공하면서 빌드할 수 있으며,
22 | // 시간은 언제나 위치(time zons)과 연관된다.
23 | then := time.Date(
24 | 2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
25 | p(then)
26 |
27 | //당신은 또한 예상한대로 시간값에서 다양한 컴포넌트들을 추출할 수 있다.
28 | p(then.Year())
29 | p(then.Month())
30 | p(then.Day())
31 | p(then.Hour())
32 | p(then.Minute())
33 | p(then.Second())
34 | p(then.Nanosecond())
35 | p(then.Location())
36 |
37 | // 월요일-일요일 `Weekday` 또한 사용가능하다.
38 | // The Monday-Sunday `Weekday` is also available.
39 | p(then.Weekday())
40 |
41 | // 두 시간대를 비교하는 이 메소드들이 있는데, 첫번째것은 전에 발생, 후에 발생했는지 테스트하고
42 | // Equals은 동시에 발생했는지 각각 테스트한다.
43 | p(then.Before(now))
44 | p(then.After(now))
45 | p(then.Equal(now))
46 |
47 | // `Sub`메소드는 두 시간대 사이의 간격을 나타내는 `Duration`을 리턴한다.
48 | diff := now.Sub(then)
49 | p(diff)
50 |
51 | // 우리는 간격의 차이를 다양한 단위로 계산할 수 있다
52 | p(diff.Hours())
53 | p(diff.Minutes())
54 | p(diff.Seconds())
55 | p(diff.Nanoseconds())
56 |
57 | // 당신은 Add를 사용할 수 있다. 주어진 시간만큼 시간을 당길 수 있다.
58 | // 아니면 - 를 줘서 시간을 이전으로 당길 수 있다.
59 | p(then.Add(diff))
60 | p(then.Add(-diff))
61 | }
62 |
--------------------------------------------------------------------------------
/gobyexample/51_랜덤숫자.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/random-numbers
4 | Go by Example: random-numbers
5 |
6 | Go의 math/rand 패키지는 수도랜덤숫자 일반화를 제공한다.
7 | [pseudorandom number](http://en.wikipedia.org/wiki/Pseudorandom_number_generator)
8 | */
9 |
10 | package main
11 |
12 | import "fmt"
13 | import "math/rand"
14 |
15 | func main() {
16 |
17 | //예를 들자면, `rand.Intn`은 랜덤정수 n을 리턴한다. n은 이 밑에서는 0이상100미만 값이다.
18 | fmt.Print(rand.Intn(100), ",")
19 | fmt.Print(rand.Intn(100))
20 | fmt.Println()
21 |
22 | // randFloat64는 float64 타입의 f를 리턴한다. 여기선 0.0 <=f < 1.0 값이다.
23 | fmt.Println(rand.Float64())
24 |
25 | // 이것은 랜덤 실수를 다른 범위에서 생성해본다. 예를 들자면 `5.0 <= f' < 10.0`.
26 | fmt.Print((rand.Float64()*5)+5, ",")
27 | fmt.Print((rand.Float64() * 5) + 5)
28 | fmt.Println()
29 |
30 | // deterministic인 수도랜덤 생성기(pseudorandom generator)를 만들기 위해, 잘 알려진 seed를 주자.
31 | // 역주: 번역이 매끄럽지 못해 원문을 남깁니다. 좋은 번역 제시해주시면 감사하겠구요.
32 | // 그냥 어떤 값을 넣어서 숫자를 뽑아내는 것같습니다~
33 | // To make the pseudorandom generator deterministic,
34 | // give it a well-known seed.
35 | s1 := rand.NewSource(42)
36 | r1 := rand.New(s1)
37 |
38 | // `rand.Source`은 rand패키지의 함수같은 결과를 호출한다.
39 | fmt.Print(r1.Intn(100), ",")
40 | fmt.Print(r1.Intn(100))
41 | fmt.Println()
42 |
43 | //만약 당신이 같은 숫자를 가지고서 랜덤을 돌리면
44 | //그것은 같은 랜덤숫자의 같은 나열을 만들 것이다.
45 | s2 := rand.NewSource(42)
46 | r2 := rand.New(s2)
47 | fmt.Print(r2.Intn(100), ",")
48 | fmt.Print(r2.Intn(100))
49 | fmt.Println()
50 | }
51 |
--------------------------------------------------------------------------------
/gobyexample/20_인터페이스.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/interfaces
4 |
5 | Go by Example: interfaces
6 |
7 | 인터페이스는 이름붙여진, 메소드 모음이다.
8 |
9 | */
10 |
11 | package main
12 |
13 | import "fmt"
14 | import "math"
15 |
16 | // 여기 기하학모양을 위한 기본적인 인터페이스가 있다.
17 | type geometry interface {
18 | area() float64
19 | perim() float64
20 | }
21 |
22 | // 우리의 예제를 위해서 우리는 이 인터페이스를 square와 circle 타입에서 구현할 것이다.
23 | type square struct {
24 | width, height float64
25 | }
26 | type circle struct {
27 | radius float64
28 | }
29 |
30 | // Go에서 인터페이스를 구현하기 위해, 우리는 단지
31 | // 인터페이스를 모두 구현하면 된다. 여기 square에 geometry 인터페이스를 구현하는 예제가 있다.
32 | func (s square) area() float64 {
33 | return s.width * s.height
34 | }
35 | func (s square) perim() float64 {
36 | return 2*s.width + 2*s.height
37 | }
38 |
39 | // circle에서 구현하는 것이다.
40 | func (c circle) area() float64 {
41 | return math.Pi * c.radius * c.radius
42 | }
43 | func (c circle) perim() float64 {
44 | return 2 * math.Pi * c.radius
45 | }
46 |
47 | // 만약 변수가 인터페이스 타입을 가지고 있다면, 우리는 그 인터페이스 안의 메소드를 호출할 수 있다.
48 | // 여기에, 이러한 장점을 이용하여 어떤 gemetry 가 오더라도 포괄적으로 사용하는 measure function이 있다.
49 | func measure(g geometry) {
50 | fmt.Println(g)
51 | fmt.Println(g.area())
52 | fmt.Println(g.perim())
53 | }
54 |
55 | func main() {
56 | s := square{width: 3, height: 4}
57 | c := circle{radius: 5}
58 |
59 | // circle 과 square구조체는 둘다 geometry 인터페이스를 구현하고
60 | // 우리는 이 구조체를 measure 에 아규먼트로 보낼 수 있다
61 | measure(s)
62 | measure(c)
63 | }
64 |
--------------------------------------------------------------------------------
/gobyexample/58_라인필터.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/line-filters
4 | Go by Example: line-filters
5 |
6 | line 필터는 프로그램의 보통 타입으로, stdin 에서 입력을 읽고 처리하며,
7 | 나온 결과들을 stdout에 출력한다.
8 | grep과 sed는 line filter이다.
9 |
10 | 여기 Go에서 line필터 예제가 있으며, 모든 입력글자들을 대문자로 쓴다.
11 | 당신은 이러한 패턴을 당신 자신의 GO 라인필터에 쓸 수 있다.
12 |
13 | 애매한 번역은 원문을 남긴다. 역주
14 | */
15 |
16 | package main
17 |
18 | import (
19 | "bufio"
20 | "fmt"
21 | "os"
22 | "strings"
23 | )
24 |
25 | func main() {
26 |
27 | // 버퍼되지 않은 os.Stdin을 버퍼된 스캐너로 포장하는 것은 우리에게 편리한 Scan메소드를 제공하며
28 | // 스캐너를 다음 토큰으로 진행시킨다. 기본 스캐너에서 다음토큰은 다음줄이다.
29 | // Wrapping the unbuffered `os.Stdin` with a buffered
30 | // scanner gives us a convenient `Scan` method that
31 | // advances the scanner to the next token; which is
32 | // the next line in the default scanner.
33 | scanner := bufio.NewScanner(os.Stdin)
34 |
35 | for scanner.Scan() {
36 | // 'Text'는 현재 토큰을 리턴한다. 여기 입력에서 받은 다음 토큰이 있다.
37 | // `Text` returns the current token, here the next line,
38 | // from the input.
39 | ucl := strings.ToUpper(scanner.Text())
40 |
41 | //대문자된 줄을 출력한다.
42 | // Write out the uppercased line.
43 | fmt.Println(ucl)
44 | }
45 |
46 | // Scan도중에 에러가 있는지 검사한다.
47 | // 파일의 끝이 기대되며,Scan에 의해 에러로 보고되지 않는다.
48 | // Check for errors during `Scan`. End of file is
49 | // expected and not reported by `Scan` as an error.
50 | if err := scanner.Err(); err != nil {
51 | fmt.Fprintln(os.Stderr, "error:", err)
52 | os.Exit(1)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/gobyexample/50_시간형식화.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/time-formatting-parsing
4 | Go by Example: time-formatting-parsing
5 |
6 | Go는 패턴기반한 레이아웃을 통해서 시간을 형식화하고 파싱하는 것을 지원한다.
7 | */
8 |
9 | package main
10 |
11 | import "fmt"
12 | import "time"
13 |
14 | func main() {
15 | p := fmt.Println
16 |
17 | // 여기 RFC3339를 따라서 시간을 형식화하는 예제가 있다.
18 | // 그에 상응하는 레이아웃 상수를 사용한다.
19 | t := time.Now()
20 | p(t.Format(time.RFC3339))
21 |
22 | // 시간을 파싱하는 것은 같은 레이아웃 값을 `Format`으로 이용한다.
23 | // Time parsing uses the same layout values as `Format`.
24 | t1, e := time.Parse(
25 | time.RFC3339,
26 | "2012-11-01T22:08:41+00:00")
27 | p(t1)
28 |
29 | // `Format`과 `Parse` 는 예제기반한 레이아웃을 사용한다.
30 | // 보통 당신은 이러한 레이아웃들을 위해 time에서 온 상수를 사용할 것이지만, 커스텀 레이아웃도 사용할 수 있다.
31 | // 레이아웃은 무조건 참조 시간(`Mon Jan 2 15:04:05 MST 2006`)을 사용하여 주어진 시간/문자열이 형식/파싱될 패턴을 보여줘야 한다.
32 | // 이 예제 시간은 정확히 다음과 같이 보여질 것이다.(시간은 2006 같이, 시간을 위한 15, 요일을 위한 Monday 같은 형식으로 말이다)
33 | p(t.Format("3:04PM"))
34 | p(t.Format("Mon Jan _2 15:04:05 2006"))
35 | p(t.Format("2006-01-02T15:04:05.999999-07:00"))
36 | form := "3 04 PM"
37 | t2, e := time.Parse(form, "8 41 PM")
38 | p(t2)
39 |
40 | // 순수한 숫자 표현을 위해 당신은 또한 표준문자열형식을 시간값에서 추출한 요소들과 함께 사용할 수 있다.
41 | fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
42 | t.Year(), t.Month(), t.Day(),
43 | t.Hour(), t.Minute(), t.Second())
44 |
45 | // `Parse` 는 잘못된 입력이 있을때 에러를 리턴하며 파싱문제를 설명할 것이다.
46 | ansic := "Mon Jan _2 15:04:05 2006"
47 | _, e = time.Parse(ansic, "8:41PM")
48 | p(e)
49 | }
50 |
--------------------------------------------------------------------------------
/gobyexample/60_커맨드라인플래그.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/command-line-flags
4 | Go by Example: command-line-flags
5 |
6 | 커맨드라인플래그는 커맨드라인프로그램을 위한 옵션을 명시하는 흔한 방법이다.
7 | 예를 들자면 wc -l 에서 -l 은 커맨드라인플래그이다.
8 | */
9 |
10 | package main
11 |
12 | // Go는 flag패키지를 제공하여, 기본적인 커맨드라인 플래그 파싱을 지원한다.
13 | // 우리는 이 패키지를 사용하여 우리의 커맨드라인프로그램을 구현해보고자 한다.
14 | import "flag"
15 | import "fmt"
16 |
17 | func main() {
18 |
19 | // 기본 플래그 선언은 문자열, 정수, 불린형으로 선언 가능하다.
20 | //여기 문자열 플래그 word를 기본값인 foo와 짧은 설명과 함께 선언했다.
21 | // 이 flag.String 함수는 string포인터를 리턴한다. (String값이 아니다)
22 | // 우리는 이 포인터를 어떻게 쓸 것인지 밑에서 볼 것이다.
23 | wordPtr := flag.String("word", "foo", "a string")
24 |
25 | // 이것은 numb와 fork 플래그를 선언한다.
26 | // word플래그와 비슷한 접근을 한다.
27 | numbPtr := flag.Int("numb", 42, "an int")
28 | boolPtr := flag.Bool("fork", false, "a bool")
29 |
30 | // 다른 곳에서 선언하여 프로그램에 이미 존재하는 변수를 사용하는 옵션을 선언하는 것도 가능하다.
31 | // flag선언 함수에 포인터를 전달해야 한다는 것을 기억하자
32 | var svar string
33 | flag.StringVar(&svar, "svar", "bar", "a string var")
34 |
35 | // 한번 모든 플래그들이 선언되면 flag.Parse() 를 호출하여 커맨드라인파싱을 실행한다.
36 | flag.Parse()
37 |
38 | // 여기 우리는 파싱된 옵션들과 그것에 따르는 아규먼트들을 출력한다.
39 | //우리는 포인터를 디레퍼런스 해야한다는 것을 기억하자
40 | // 예를 들자면 *wordPtr은 실제 옵션값을 얻는다.
41 | // Here we'll just dump out the parsed options and
42 | // any trailing positional arguments. Note that we
43 | // need to dereference the points with e.g. `*wordPtr`
44 | // to get the actual option values.
45 | fmt.Println("word:", *wordPtr)
46 | fmt.Println("numb:", *numbPtr)
47 | fmt.Println("fork:", *boolPtr)
48 | fmt.Println("svar:", svar)
49 | fmt.Println("tail:", flag.Args())
50 | }
51 |
--------------------------------------------------------------------------------
/effectivego/09_메소드.go:
--------------------------------------------------------------------------------
1 | /*
2 | 원본 주소 :
3 | https://code.google.com/p/golang-korea/wiki/EffectiveGo#메소드(Methods)
4 |
5 |
6 |
7 | 메소드(Methods)
8 | 포인터 vs 값(Pointers vs. Values)
9 | 메소드는 pointer나 interface가 아니라면 어떤 이름의 타입으로든지 정의되어 질 수 있습니다.
10 | 수신자(receiver)는 구조체(struct)여서는 안됩니다.
11 |
12 | 위에 slice에 대해 토론한 부분에서, append 함수에 대해서 언급했었습니다.
13 | 대신 우리는 슬라이스에서 그것을 메소드로 정의할 수도 있습니다.
14 | 이렇게 하기 위해서, 우리는 먼저 메소드와 묶을 수 있도록 타입을 정의해야 합니다.
15 | 그리고, 그 타입의 값인 메소드에 대한 수신자(receiver)를 만들어야 합니다.
16 | */
17 | type ByteSlice []byte
18 |
19 | func (slice ByteSlice) Append(data []byte) []byte {
20 | // Body는 위에서 했던것과 똑같습니다.
21 | }
22 |
23 | //이 예제는 여전히 업데이트된 slice를 반환하기 위한 방법이 필요합니다.
24 | //우리는 수신자(receiver)로서 Byteslice의 포인터를 받아들이도록 메소드를 다시 정의함으로써
25 | //어색한 부분을 고칠 수 있습니다. 그렇게하면 메소드는 호출자(caller)의 slice를 덮어쓸 수 있습니다.
26 | func (p *ByteSlice) Append(data []byte) {
27 | slice := *p
28 | // Body는 위와 같지만 return이 없습니다.
29 | *p = slice
30 | }
31 | //사실 우리는 이것보다 더 잘할 수 있습니다.
32 | //만약 우리가 우리의 함수를 수정한다면 아래 예제처럼 그것은 표준적인 메소드처럼 보일 것 입니다.
33 | func (p *ByteSlice) Write(data []byte) (n int, err os.Error) {
34 | slice := *p
35 | // 위의 예제와 같음
36 | *p = slice
37 | return len(data), nil
38 | }
39 | //그렇게되면, *ByteSlice 타입은 표준 인터페이스인 io.Writer를 만족시키며 편리합니다.
40 | //예를들면, 우리는 아래 예처럼 한번에 출력할 수 있습니다.
41 |
42 | var b ByteSlice
43 | fmt.Fprintf(&b, "This hour has %d days\n", 7)
44 | //우리는 ByteSlice?의 주소값을 넘겼습니다. 왜냐하면 *ByteSlice만이 io.Writer에 적합하기 때문입니다.
45 | //수신자(receiver)에 대한 포인터와 값에 대한 규칙은 값 메소드는(value method) 포인터와 값을 불러올 수 있지만
46 | //포인터 메소드는(pointer method) 오로지 포인터만을 불러올 수 있다는 것 입니다.
47 | //이것은 포인터 메소드는 수신자(receiver)를 수정할 수 있기 때문입니다.
48 | //값의 복사본에서 그것들을 불러오는 경우는 이런 수정들이 적용되지 않을 것 입니다.
49 | //byte slice에서 사용되어진 아이디어는 bytes.Buffer에 구현되어 있습니다.
--------------------------------------------------------------------------------
/effectivego/07_데이터/02_생성자와복합문장.go:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
4 |
5 |
6 | 때때로, zero 값으로는 충분하지 않기 때문에 여기있는 os package로 부터 파생된 예처럼 초기화 생성자가 필요할 때가 있습니다.
7 | */
8 | func NewFile(fd int, name string) *File {
9 | if fd < 0 {
10 | return nil
11 | }
12 | f := new(File)
13 | f.fd = fd
14 | f.name = name
15 | f.dirinfo = nil
16 | f.nepipe = 0
17 | return f
18 | }
19 | /*
20 | 위 예에는 많은 정보가 들어있습니다. 우리는 매번 그 값이 계산될 때 마다
21 | 새로운 인스턴스가 생성되는 표현인 복합문장(composite literal)을 사용해서 그것을 단순화시킬 수 있습니다.
22 | */
23 | func NewFile(fd int, name string) *File {
24 | if fd < 0 {
25 | return nil
26 | }
27 | f := File{fd, name, nil, 0}
28 | return &f
29 | }
30 | /*
31 | C언어에서와는 다르게, 지역 변수의 주소를 반환하는것은 괜찮습니다.
32 | 변수의 저장소는 함수가 반환된 뒤에도 살아있을 것입니다.
33 | 사실, 복합문장의 주소를 가져가는 것은 그것이 계산될 때마다 새로운 인스턴스를 할당하기 때문에
34 | 우리는 위 예에서 마지막 두 줄을 다음과 같이 섞어서 사용할 수 있습니다.
35 | */
36 | return &File{fd, name, nil, 0}
37 | /*
38 | 복합문장의 필드는 순서대로이며 반드시 모두 있어야 합니다.
39 | 하지만, 필드:필드값 처럼 명확히 요소들을 라벨링한 경우는 초기화는 어떤 순서로든 사용될 수 있습니다.
40 | 몇가지는 생략도 가능하며, 생략된 경우는 zero값으로 초기화됩니다. 그러므로 위의 예는 다음과 같이 사용 될 수 있습니다.
41 | */
42 | return &File{fd: fd, name: name}
43 | /*
44 | 제한된 경우로, 만약 복합문장이 어떤 필드도 가지지 않은 경우, 그 타입에 대해 zero 값을 생성할 것입니다.
45 | new(File)과 &File()의 표현식은 둘다 동일합니다.
46 |
47 | 복합 문장들은 또한 array, slice, map을 위해 사용될 수 있으며,
48 | 이 경우도 인덱싱된 필드라벨 또는 map 키를 함께 사용할 수 있습니다.
49 | 아래 예들의 경우, Enone, Eio, Einval이 구분되어지기만 한다면 가지고 있는 값에 상관없이 정상적으로 초기화 될 것입니다.
50 | */
51 | a := [...]string {Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
52 | s := []string {Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
53 | m := map[int]string{Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
--------------------------------------------------------------------------------
/gobyexample/64_시그널.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/signals
4 | Go by Example: signals
5 |
6 | 때때로 우리는 Go프로그램이 지능적으로 Unix시그널들을 처리하기를 원한다.
7 | 예를 들면, 우리는 SIGTERM이나, 입력처리를 그만두게하는 커맨드라인툴을 받았을 때 서버가 우아하게 꺼지길 원한다.
8 | (when it receives a `SIGTERM`, or a command-line tool to stop processing input if it receives a `SIGINT`.)
9 | 여기에 Go에서 채널과 함께 어떻게 그런 신호를 다루는지 나와있다.
10 | */
11 |
12 | package main
13 |
14 | import "fmt"
15 | import "os"
16 | import "os/signal"
17 | import "syscall"
18 |
19 | func main() {
20 |
21 | // Go 신호 알림은 'os.Signal'값을 채널에서 전송함으로써 동작한다.
22 | // 우리는 저러한 알림들을 받을 채널을 만들 것이다.
23 | // (우리는 또한 프로그램이 종료될 수 있을 때 우리에게 알릴 채널또한 만들 것이다)
24 | // Go signal notification works by sending `os.Signal`
25 | // values on a channel. We'll create a channel to
26 | // receive these notifications (we'll also make one to
27 | // notify us when the program can exit).
28 | sigs := make(chan os.Signal, 1)
29 | done := make(chan bool, 1)
30 |
31 | // 'signal.Notify' 는 명시된 시그널알림들을 수신할 채널을 등록한다.
32 | // `signal.Notify` registers the given channel to
33 | // receive notifications of the specified signals.
34 | signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
35 |
36 | // 이 고루틴은 시그널을 위해 블락킹수신을 실행한다.
37 | // 이것이 수신을 할때 이것은 그것을 print하고 그리고 프로그램에게 마칠 수 있단 것을 알린다.
38 | // This goroutine executes a blocking receive for
39 | // signals. When it gets one it'll print it out
40 | // and then notify the program that it can finish.
41 | go func() {
42 | sig := <-sigs
43 | fmt.Println()
44 | fmt.Println(sig)
45 | done <- true
46 | }()
47 |
48 | // 여기서 프로그램이 예상된 시그널(위의 done에게 값을 보내는 고루틴이 보내는)을 받을 때까지 기다린다.
49 | //그리고 종료된다.
50 | // The program will wait here until it gets the
51 | // expected signal (as indicated by the goroutine
52 | // above sending a value on `done`) and then exit.
53 | fmt.Println("awaiting signal")
54 | <-done
55 | fmt.Println("exiting")
56 | }
57 |
--------------------------------------------------------------------------------
/effectivego/03_명칭/01_패키지네임.go:
--------------------------------------------------------------------------------
1 | // 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo#명칭(Names)
2 | /*
3 |
4 | Package names
5 | package가 import될 때, package 이름은 package 내용에 대한 접근자가 됩니다.
6 |
7 | import "bytes"
8 |
9 | 위와 같이 썼다면 importing된 package는 byte에 관해 다룰 것입니다.
10 | 만약 모든 사람들이 같은 package를 참조하기 위해 같은 이름을 사용한다면 편리할 것이며,
11 | 그것은 곧 package의 이름이 반드시 좋아야 한다는 것을 의미합니다.: 짧고, 간결해야하며,
12 | 유추가능해야 함. 규정에 따라, package 이름은 소문자를 사용하며, 한단어 이름 을 사용합니다.
13 |
14 | 밑줄(_) 또는 대소문자를 섞어서 사용할 필요가 없습니다. 당신의 package를 사용하는 모든 사람이
15 | 그 이름을 사용할 것이기 때문에 간결함이 문제가 될 수도 있지만, package 이름은 import를 위한
16 | 기본 이름으로만 사용되기 때문에 중복 및 충돌에 대해서는 걱정할 필요가 없습니다.
17 |
18 | (모든 소스코드에 있어서 유일한 이름일 필요는 없으며, 가끔 충돌이 발생하는 경우에 한해서
19 |
20 | 국지적으로(local) 쓰기위해 다른 이름을 사용하면 됩니다.) import되는 경우 파일의 이름으로
21 |
22 | 어떤 package가 사용되어 졌는지를 결정할 것 이기 때문에 혼동되는 경우는 거의 없습니다.
23 |
24 | 또 다른 규정은 package 이름은 package 소스 디렉토리에 기반한 이름이어야 한다는 것입니다.
25 |
26 | 즉, package 소스 디렉토리가 src/pkg/container/vector 라고 가정하면 그
27 | package는 "container/vector"로 import 되어지며 이름은 vector 입니다.
28 | (container_vector 또는 containerVector가 아닙니다.)
29 |
30 | package를 import하려면 package 내용을 참조하기 위해 package의 이름을 사용할 것입니다.
31 | '.' 기호는 test나 일반적이지 않은 상황을 위한 것이며 꼭 필요하지 않다면 피해야합니다.
32 |
33 | 예를 들어 bufio package에서 buffered reader type은 BufReader?가 아니라 Reader로 불립니다.
34 | 왜냐하면 사용자들은 buffered reader type을 bufio.Reader로써 볼 것이고,
35 | 그것이 분명하고 간결한 이름이기 때문이며, 더욱이, import된 객체들은 항상
36 | 그 객체의 package 이름과 함께 사용되기 때문입니다. bufio.Reader는 io.Reader와 충돌을 일으키지 않습니다.
37 |
38 | 유사한 예로, ring.Ring(Go언어에서 한 생성자의 정의임)의 새로운 개체를 만들기 위한 함수는 일반적으로 NewRing?으로 호출될 것 입니다.
39 | 그렇지만 Ring은 ring package에 의해 export된 유일한 type이며,
40 | 그 package는 ring이기 때문에 새로운 개체는 그냥 New라고 호출되며 그 package의 client들에게는 ring.New로 보일 것입니다.
41 | 좋은 이름을 선택하기 위해서는 package 구조를 사용하십시요.
42 |
43 | 또 다른 간단한 예는 once.Do 입니다. once.Do(setup)은 읽기에 쉽고
44 | once.DoOrWaitUntilDone?(setup) 보다 좋습니다. 긴 이름들은 읽기에 쉽지 않습니다.
45 | 만약에 그 이름이 뭔가 복잡하고 어려운 무언가를 대표한다면,
46 | 그 이름에 모든 정보를 넣기보다는 doc 주석으로 남기는 것이 더 좋습니다.
47 |
48 | */
--------------------------------------------------------------------------------
/gobyexample/09_슬라이스.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/slices
4 |
5 | Go by Example: Slices
6 | */
7 | package main
8 |
9 | import "fmt"
10 |
11 | func main() {
12 |
13 | // 배열과 달리, 오직 슬라이스가 가지고 있는 요소들의 타입을 속성으로 가진다.
14 | // 이 말은 배열은 요소타입, 길이를 가지는데 슬라이스는 요소타입만 가진다는 얘기.(역주, 가변길이)
15 | // 가변길이이기 때문에 이따가 더 추가하는 것이 나온다. 한번 보자!!
16 |
17 | // 길이가 0이 아닌 슬라이스를 만들기 위해,
18 | // 내장 기능인 make 를 이용해봅니다. 이것은 문자열, 크기3을 가진 슬라이스를 만듭니다.
19 | // zero-value 로 초기화됩니다.
20 | s := make([]string, 3)
21 | fmt.Println("emp:", s)
22 |
23 | // 배열처럼 요소들의 값을 저장하고 불러올 수 있습니다.
24 | s[0] = "a"
25 | s[1] = "b"
26 | s[2] = "c"
27 | fmt.Println("set:", s)
28 | fmt.Println("get:", s[2])
29 |
30 | //len 은 길이 리턴하시는 것~ 기억하시죠~
31 | fmt.Println("len:", len(s))
32 |
33 | // 배열보다 더 많은 기능중의 하나는 append 이다.
34 | // append는 하나 혹은 그 이상의 새로운 값을 포함하는 슬라이스를 리턴한다.
35 | // append 시에 리턴 값을 받아야 한다는 것을 잊지마세요!
36 | s = append(s, "d")
37 | s = append(s, "e", "f")
38 | fmt.Println("apd:", s)
39 |
40 | // 슬라이스는 또한 `copy` 될 수 있다.여기에 빈 슬라이스 c를 만드는데,
41 | //길이는 s의 길이로 만들어서 s 의 내용을 c로 복사하는 내용이 나온다.
42 | c := make([]string, len(s))
43 | copy(c, s)
44 | fmt.Println("cpy:", c)
45 |
46 | // 슬라이스는 연산자를 제공하는데 슬라이스[low:high]이다.
47 | // 이것은 `s[2]`, `s[3]`, and `s[4]` 를 얻는다.
48 | l := s[2:5]
49 | fmt.Println("sl1:", l)
50 |
51 | // 이것은 s[5]이전것(비포함)까지를 보여준다.
52 | l = s[:5]
53 | fmt.Println("sl2:", l)
54 |
55 | // `s[2]` 부터(포함) 보여준다.
56 | l = s[2:]
57 | fmt.Println("sl3:", l)
58 |
59 | // 한줄로 또한 슬라이스를 선언&초기화할 수 있다. (배열과는 다르게 [숫자]가 안 들어감을 보자.역주)
60 | t := []string{"g", "h", "i"}
61 | fmt.Println("dcl:", t)
62 |
63 | // 슬라이스또한 다차원이 될 수 있다. 다차원 배열과는 다르게 내부의
64 | twoD := make([][]int, 3)
65 | for i := 0; i < 3; i++ {
66 | innerLen := i + 1
67 | twoD[i] = make([]int, innerLen)
68 | for j := 0; j < innerLen; j++ {
69 | twoD[i][j] = i + j
70 | }
71 | }
72 | fmt.Println("2d: ", twoD)
73 | //이곳에 더 많은 자료가 있다고 한다. http://blog.golang.org/go-slices-usage-and-internals
74 | }
75 |
--------------------------------------------------------------------------------
/gobyexample/35_RateLimiting.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/rate-limiting
4 | Go by Example: rate-limiting
5 |
6 | (http://en.wikipedia.org/wiki/Rate_limiting)
7 | RateLitming 은 리소스활용 컨트롤과 서비스퀄리티유지에 중요한 메커니즘이다.
8 | Go는 go루틴, 채널, tickers와 함께 우아하게 rate limiting을 지원한다.
9 | */
10 |
11 | package main
12 |
13 | import "time"
14 | import "fmt"
15 |
16 | func main() {
17 |
18 | // 먼저 기본적인 rate limiting을 보도록 하자.
19 | // 우리가 들어오는 요청 핸들링을 제한하고 싶다고 하자.
20 | // 우리는 이러한 요청들을 같은 이름의 채널에서 다루게?(serve off) 할 것이다?
21 | // We'll serve these requests off a channel of the same name.
22 | requests := make(chan int, 5)
23 | for i := 1; i <= 5; i++ {
24 | requests <- i
25 | }
26 | close(requests)
27 |
28 | //이 limiter채널은 매 200밀리초마다 값을 받을 것이다.
29 | //이것은 우리의 rate limiting 계획에서 조절장치이다.
30 | limiter := time.Tick(time.Millisecond * 200)
31 |
32 | // 각각의 요청을 다루기 전에, limiter채널에서 수신을 블락킹하기전
33 | //우리는 우리자신을 1개의 요청당 200밀리초로 제한할 것이다.
34 | for req := range requests {
35 | <-limiter
36 | fmt.Println("request", req, time.Now())
37 | }
38 |
39 | // 전체의 rate 한계를 보존하는동안, 우리는 그 rate 한계속에서 요청들의 short bursts를 허락할 것이다.
40 | // We may want to allow short bursts of requests in
41 | // our rate limiting scheme while preserving the
42 | // overall rate limit.
43 | // 우리는 우리의 리미터채널에 버퍼링함으로써 이것을 할 수 있다.
44 | //We can accomplish this by buffering our limiter channel.
45 | // 이 burstyLimiter 채널은 3개의 이벤트까지 bursts를 허락한다.
46 | burstyLimiter := make(chan time.Time, 3)
47 |
48 | // Fill up the channel to represent allowed bursting.
49 | for i := 0; i < 3; i++ {
50 | burstyLimiter <- time.Now()
51 | }
52 |
53 | // 매 200밀리초마다 우리는 새로운 값들을 burstyLimiter에 그것의 한계치인 3개까지 추가할 것이다.
54 | go func() {
55 | for t := range time.Tick(time.Millisecond * 200) {
56 | burstyLimiter <- t
57 | }
58 | }()
59 |
60 | // 여기서 5개 이상의 요청을 가정해보자. 이 요청들에서 3번째것까지만 burstyLimiter 의 burst 수용능력안에 들어갈 것이다.
61 | burstyRequests := make(chan int, 5)
62 | for i := 1; i <= 5; i++ {
63 | burstyRequests <- i
64 | }
65 | close(burstyRequests)
66 | for req := range burstyRequests {
67 | <-burstyLimiter
68 | fmt.Println("request", req, time.Now())
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/packages/net/http/00_오버뷰.go:
--------------------------------------------------------------------------------
1 | /*
2 | http패키지는 http 클라이언트와 서버구현을 제공한다.
3 | GET, HEAD, POST 와 PostForm 은 http(혹은 https)요청을 만든다.
4 | */
5 | resp, err := http.Get("http://example.com/")
6 | ...
7 | resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
8 | ...
9 | resp, err := http.PostForm("http://example.com/form", url.Values{"key": {"Value"}, "id": {"123"}})
10 | /*
11 | 클라이언트는 반ㄷ싀 응답몸체를 닫아야 한다. 그것과 함께 끝났을 때:"
12 | */
13 | resp, err := http.Get("http://example.com/")
14 | if err != nil {
15 | // handle error
16 | }
17 | defer resp.Body.Close()
18 | body, err := ioutil.ReadAll(resp.Body)
19 | // ...
20 | // http 클라이언트 헤더들, redirect방침, 다른 세팅들을 컨트롤하기 위해 Client를 생성한다.
21 |
22 | client := &http.Client{
23 | CheckRedirect: redirectPolicyFunc,
24 | }
25 |
26 | resp, err := client.Get("http://example.com")
27 | // ...
28 |
29 | req, err := http.NewRequest("GET", "http://example.com", nil)
30 | // ...
31 | req.Header.Add("If-None-Match", `W/"wyzzy"`)
32 | resp, err := client.Do(req)
33 | // ...
34 | // 프록시들 TLS설정, keep-alives, compression, 그리고 다른 세팅들을 컨트롤하기 위해 Transport를 생성한다.
35 |
36 | tr := &http.Transport{
37 | TLSClientConfig: &tls.Config{RootCAs: pool},
38 | DisableCompression: true,
39 | }
40 | client := &http.Client{Transport: tr}
41 | resp, err := client.Get("https://example.com")
42 | /*
43 | 클라이언트와 Transports는 멀티고루틴에 의해 동시성사용에 안전하다.
44 | //Clients and Transports are safe for concurrent use by multiple goroutines and for efficiency should only be created once and re-used.
45 |
46 | ListenAndServe는 HTTP 서버를 주어진 주소와 핸들러와 함께 실행시킨다.
47 | handler는 보통 DefaultServeMux를 사용하기위해 nil이다.
48 | Handle과 HandleFunc는 DefaultServeMux에 handler를 추가한다.
49 | */
50 | http.Handle("/foo", fooHandler)
51 |
52 | http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
53 | fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
54 | })
55 |
56 | log.Fatal(http.ListenAndServe(":8080", nil))
57 | //커스텀서버를 만듦으로써 서버행동에 관한 더 많은 컨트롤이 가능하다.
58 |
59 | s := &http.Server{
60 | Addr: ":8080",
61 | Handler: myHandler,
62 | ReadTimeout: 10 * time.Second,
63 | WriteTimeout: 10 * time.Second,
64 | MaxHeaderBytes: 1 << 20,
65 | }
66 | log.Fatal(s.ListenAndServe())
--------------------------------------------------------------------------------
/effectivego/07_데이터/05_슬라이스.go:
--------------------------------------------------------------------------------
1 | /*
2 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
3 |
4 |
5 | Slices
6 | slice는 연속적인 자료에 대해 더 일반화하고, 강력하며, 편리한 인터페이스를 제공하기 위해 배열을 둘러쌉니다.
7 | 변환 행렬 같은 명확한 크기를 갖는 아이템을 제외하고, Go에서 대부분의 배열 프로그램은 단순 배열 보다는 slice를 사용합니다.
8 |
9 | slice는 참조 타입입니다. 즉, 만약 하나의 slice를 다른쪽에 지정하면 둘다 같은 배열을 참조하는 것을 의미합니다.
10 | 예를 들어, 만약 함수가 slice 인자를 받는다면, 값이 변경되는 경우 slice의 요소들을 호출하는 쪽에서
11 | 볼 수 있을 것입니다.(배열의 포인터를 넘겨주는 것과 유사합니다.)
12 |
13 | 따라서, Read 함수는 포인터나 count를 인자로 받기 보다 slice를 인자로 받는 것이 좋습니다.
14 | slice 내부의 길이는 얼마나 많은 data를 읽을 지에 대한 제한이 있습니다.
15 | 여기에 예로, os package에서 File 타입의 Read 메소드의 특징이 있습니다.
16 | */
17 | func (file *File) Read(buf []byte) (n int, err os.Error)
18 | /*
19 | 위의 메소드는 읽은 byte의 숫자와 error값을 반환합니다. 더 큰 buffer b로 처음 32byte를 읽기위해 buffer를 분할합니다.
20 | */
21 | n, err := f.Read(buf[0:32])
22 | /*
23 | 이런 분할은 매우 일반적이며 효율적입니다. 사실, 잠시 효율성을 떠나서, 이 조각은 buffer의 처음 32byte를 읽을 것입니다.
24 | */
25 | var n int
26 | var err os.Error
27 | for i := 0; i < 32; i++ {
28 | nbytes, e := f.Read(buf[i:i+1]) // Read one byte.
29 | if nbytes == 0 || e != nil {
30 | err = e
31 | break
32 | }
33 | n += nbytes
34 | }
35 | /*
36 | slice의 길이는 배열의 크기 제한이 허용하는 한도 내에서 변화될 것 입니다. ;
37 | slice를 지정하십시오. 내장함수인 cap을 사용해 slice의 최대 용량을 알 수 있습니다.
38 | 여기 slice에 data를 추가하는 예가 있습니다. 만약 data가 slice의 용량을 초과한다면, slice는 재할당될 것입니다.
39 | 그 결과로 재할당된 slice가 반환됩니다. 아래 예제 함수에서는
40 | len()과 cap()이 nil slice에도 사용이 가능하다는 점을 사용하고 있습니다.(nil slice인 경우 0을 반환함)
41 | */
42 | func Append(slice, data[]byte) []byte {
43 | l := len(slice)
44 | if l + len(data) > cap(slice) { // 재할당
45 | // 공간을 더 키우기 위해 두배로 할당
46 | newSlice := make([]byte, (l+len(data))*2)
47 | // copy 함수는 미리 선언되어져있으며 어떤 slice 타입이나 동작함
48 | copy(newSlice, slice)
49 | slice = newSlice
50 | }
51 | slice = slice[0:l+len(data)]
52 | for i, c := range data {
53 | slice[l+i] = c
54 | }
55 | return slice
56 | }
57 | /*
58 | 반드시 뒤에 slice를 리턴해야만 합니다. 왜냐하면 Append()가 slice의 요소들을 수정할 수 있다하더라도
59 | slice 자체는(포인터, 길이, 용량을 가지고 있는 run-time 자료구조) 값으로 넘겨져야 합니다.
60 |
61 | slice에 data를 추가하는 아이디어는 꽤 유용하며, append 함수는 내장 함수로 포함되어 있습니다.
62 | append 함수의 설계를 이해하기 위해서는 좀 더 많은 정보가 필요하기 때문에 추후에 다시 살펴보겠습니다.
63 |
64 | */
--------------------------------------------------------------------------------
/gobyexample/56_파일읽기.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/reading-files
4 | Go by Example: reading-files
5 |
6 | 많은 Go프로그램들에서 기본적으로 파일을 읽고 쓰는 작업이 필요하다.
7 | 먼저 우리는 파일을 읽는 몇가지 예제들을 살펴보겠다.
8 | */
9 |
10 | package main
11 |
12 | import (
13 | "bufio"
14 | "fmt"
15 | "io"
16 | "io/ioutil"
17 | "os"
18 | )
19 |
20 | // 파일을 읽는 것은 에러를 위한 검사를 먼저 필요로 한다.
21 | // 이 helper 는 우리의 에러체크를 간소화하게 해줄 것이다.
22 | func check(e error) {
23 | if e != nil {
24 | panic(e)
25 | }
26 | }
27 |
28 | func main() {
29 | // 아마 가장 기본적인 파일 읽기 작업은 파일전체를 메모리로 읽어들이는 것이다.
30 | // 윈도우용일 경우를 따로 추가했다(역주)
31 | //dat, err := ioutil.ReadFile("/tmp/dat")
32 | dat, err := ioutil.ReadFile("c:/go/text.txt") //역주
33 | check(err)
34 | fmt.Print(string(dat))
35 |
36 | // 당신은 종종 파일의 어떤 부분을 어떻게 읽을지 컨트롤 하고 싶을 것이다.
37 | // 이러한 작업을 위해, 파일을 Open하여서 os.File 값을 얻도록 하자
38 | //f, err := os.Open("/tmp/dat")
39 | f, err := os.Open("c:/go/text.txt")
40 | check(err)
41 |
42 | // 파일의 시작으로부터 몇 바이트를 읽는다.
43 | // 5까지 읽는 것을 허용한다. 얼마나 실제로 읽어들이는지 보자.
44 | b1 := make([]byte, 5)
45 | n1, err := f.Read(b1)
46 | check(err)
47 | fmt.Printf("%d bytes: %s\n", n1, string(b1))
48 |
49 | // 당신은 또한 'Seek' 을 써서 파일에서 그 부분부터 Read읽을 수 있다.
50 | o2, err := f.Seek(6, 0)
51 | check(err)
52 | b2 := make([]byte, 2)
53 | n2, err := f.Read(b2)
54 | check(err)
55 | fmt.Printf("%d bytes @ %d: %s\n", n2, o2, string(b2))
56 |
57 | // io패키지는 파일읽는데 도움이 되는 몇가지 함수를 제공한다.
58 | // 예를 들자면, 여기 있는 것들 처럼 읽는 것은 ReadAtLeast 와 함께 구현되어서 좀 더 튼튼(?robustly)하다
59 | // The `io` package provides some functions that may
60 | // be helpful for file reading. For example, reads
61 | // like the ones above can be more robustly
62 | // implemented with `ReadAtLeast`.
63 | o3, err := f.Seek(6, 0)
64 | check(err)
65 | b3 := make([]byte, 2)
66 | n3, err := io.ReadAtLeast(f, b3, 2)
67 | check(err)
68 | fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))
69 |
70 | // 내장된 되돌리는 기능없지만, Seek(0, 0)은 이러한 일들을 하게 해준다.
71 | _, err = f.Seek(0, 0)
72 | check(err)
73 |
74 | // bufio 패키지는 버퍼된 리더를 구현한다.
75 | // 버퍼된 리더는 추가적으로 제공하는 읽기메소드와 그것의 효율성 덕분에 유용하다.
76 | r4 := bufio.NewReader(f)
77 | b4, err := r4.Peek(5)
78 | check(err)
79 | fmt.Printf("5 bytes: %s\n", string(b4))
80 |
81 | // 모든 작업을 마치면 파일을 닫는다 (보통 이것은 Open되면 defer와 함께 예약된다.)
82 | f.Close()
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/gobyexample/63_프로세스실행.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/execing-processes
4 | Go by Example: execing-processes
5 |
6 | 이전의 예제에서 우리는 외부 프로세스들을 생성하는 법을 살펴보았는데,
7 | 우리는 실행중인 Go 프로그램에서 접근가능한 외부프로세스가 필요할 때 이런 것을 할 수 있다.
8 | 때때로 우리는 현재의 Go프로세스를 Go프로세스가 아닌 다른 것으로 대체하고 싶을 때가 있다.
9 | 이러한 것을 하기 위해, 우리는 Go의 exec함수를 사용할 것이다.
10 | */
11 |
12 | // In the previous example we looked at
13 | // [spawning external processes](spawning-processes). We
14 | // do this when we need an external process accessible to
15 | // a running Go process. Sometimes we just want to
16 | // completely replace the current Go process with another
17 | // (perhaps non-Go) one. To do this we'll use Go's
18 | // implementation of the classic
19 | // exec
20 | // function.
21 |
22 | package main
23 |
24 | import "syscall"
25 | import "os"
26 | import "os/exec"
27 |
28 | func main() {
29 |
30 | // 우리의 예제에서, 우리는 ls를 실행할 것이다. Go는 우리가 실행하고자 하는 binary에의 절대경로를 필요로 한다.
31 | // 그래서 우리는 exec.LookPath를 사용하여서 그것을 찾아볼 것이다.
32 | // For our example we'll exec `ls`. Go requires an
33 | // absolute path to the binary we want to execute, so
34 | // we'll use `exec.LookPath` to find it (probably
35 | // `/bin/ls`).
36 | binary, lookErr := exec.LookPath("ls")
37 | if lookErr != nil {
38 | panic(lookErr)
39 | }
40 |
41 | // 'Exec'는 나란히 한 줄로 놓여진 슬라이스 형식의 아규먼트를 필요로 한다.
42 | // 우리는 ls에게 몇가지 흔한 아규먼트들을 줄 것이다.
43 | // 첫번째 아규먼트는 프로그램 이름이 되어야 한다는 것을 기억하자.
44 | args := []string{"ls", "-a", "-l", "-h"}
45 |
46 | // 'Exec'는 또한 환경변수 모음이 필요하다
47 | // 여기 우리는 우리의 환경변수를 줄 수 있다.
48 | // `Exec` also needs a set of [environment variables](environment-variables)
49 | // to use. Here we just provide our current
50 | // environment.
51 | env := os.Environ()
52 |
53 | // 여기 실제 os.Exec호출이 있다. 만약 이 호출이 성공적이라면
54 | // 우리의 프로세스의 실행은 여기서 끝나고 /bin/ls -a -l -h 프로세스가 대신할 것이다.
55 | // 만약 에러가 있다면, 우리는 리턴값을 얻을 것이다.
56 | // Here's the actual `os.Exec` call. If this call is
57 | // successful, the execution of our process will end
58 | // here and be replaced by the `/bin/ls -a -l -h`
59 | // process. If there is an error we'll get a return
60 | // value.
61 | execErr := syscall.Exec(binary, args, env)
62 | if execErr != nil {
63 | panic(execErr)
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/gobyexample/37_뮤텍스.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/mutexes
4 |
5 | Go by Example: mutexes
6 |
7 | 우리의 지난 예제에서 우리는 어떻게 간단한 카운터상태를 atomic운영을 이용하여 관리하는지 알아보았다.
8 | 더 복잡한 상태를 위해서는, 멀티플고루틴에서 안전하게 데이터에 접근하기 위한 mutex를 쓴다.
9 | */
10 |
11 | package main
12 |
13 | import (
14 | "fmt"
15 | "math/rand"
16 | "runtime"
17 | "sync"
18 | "sync/atomic"
19 | "time"
20 | )
21 |
22 | func main() {
23 |
24 | //우리의 예제에서 state는 map이 될 것이다.
25 | var state = make(map[int]int)
26 |
27 | //이 'mutex'는 상태에의 접근을 동기화할 것이다.
28 | var mutex = &sync.Mutex{}
29 |
30 | // 나중에 볼 다른 것과 mutex-based접근을 비교하기 위해
31 | //'ops'는 상태(state)에 관하여, 나중에 얼마나 많은 작업을 우리가 수행할지 카운트해줄 것이다.
32 | var ops int64 = 0
33 |
34 | // 여기 우리는 100개의 고루틴을 실행시켜서 반복된 상태(state)조회를 실행시킬 것이다.
35 | for r := 0; r < 100; r++ {
36 | go func() {
37 | total := 0
38 | for {
39 |
40 | // 각각의 조회를 위해 우리는 접근을 위한 key를 하나 집을 것이다.
41 | // mutex의 Lock() 은 상태(state)에 관한 독점적인 접근을 보장한다.
42 | // 주어진 키에 있는 값을 읽고 mutex의 Unlock()을 하여 ops카운트를 증가시킨다.
43 |
44 | key := rand.Intn(5)
45 | mutex.Lock()
46 | total += state[key]
47 | mutex.Unlock()
48 | atomic.AddInt64(&ops, 1)
49 |
50 | // 이 고루틴이 스케쥴러를 굶어죽이지않는다는 것(원문:doesn't starve)을 보장하기 위해
51 | // 우리는 runtime.Gosched()의 각각의 작업 후에 명백하게 넘겨줘야(yield)한다.
52 | //이러한 넘겨줌은 자동으로 다뤄진다. 예를 들자면 모든 채널작업과 time.Sleep 같은 블로킹호출같은 것말이다.
53 | //그러나 이러한 경우 우리는 수동으로 해줄 필요가 있다.
54 | runtime.Gosched()
55 | }
56 | }()
57 | }
58 |
59 | // 우리는 또한 10개의 고루틴을 실행시켜서 글쓰기를 가정해본다.
60 | // 우리가 조회를 했었을 때와 같은 패턴을 사용할 것이다.
61 | for w := 0; w < 10; w++ {
62 | go func() {
63 | for {
64 | key := rand.Intn(5)
65 | val := rand.Intn(100)
66 | mutex.Lock()
67 | state[key] = val
68 | mutex.Unlock()
69 | atomic.AddInt64(&ops, 1)
70 | runtime.Gosched()
71 | }
72 | }()
73 | }
74 |
75 | // 10개의 고루틴이 상태(state)에서 일을 하게 하고
76 | // Let the 10 goroutines work on the `state` and
77 | // `mutex` for a second.
78 | time.Sleep(time.Second)
79 |
80 | // 마지막 작업 카운트 값을 받아 보고한다.
81 | opsFinal := atomic.LoadInt64(&ops)
82 | fmt.Println("ops:", opsFinal)
83 |
84 | // 마지막 상태(state)를 락걸면서, 어떻게 이것이 끝나는지 보여준다.
85 | mutex.Lock()
86 | fmt.Println("state:", state)
87 | mutex.Unlock()
88 | // 프로그램실행은 우리가 mutex동기화된 state에 대하여 3,500,000작업을 실행했다는 것을 보여준다.
89 | //다음은 우리는 이와 같은 상태관리를 오직 고루틴과 채널을 이용하여 구현해볼 것이다.
90 | }
91 |
--------------------------------------------------------------------------------
/gobyexample/46_정규식표현.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/regular-expressions
4 | Go by Example: regular-expressions
5 |
6 | Go는 내장된 정규식 표현을 지원하며, 여기 Go에서의 정규식관련작업 예제가 있다.
7 | */
8 |
9 | package main
10 |
11 | import "bytes"
12 | import "fmt"
13 | import "regexp"
14 |
15 | func main() {
16 |
17 | // 이것은 문자열이 패턴에 맞는지 검사하는 것이다.
18 | match, _ := regexp.MatchString("p([a-z]+)ch", "peach")
19 | fmt.Println(match)
20 |
21 | // 위에서 문자열패턴을 직접 사용했지만, 다른 정규식 작업을 위해
22 | // 최적화된 `Regexp`구조체를 `Compile`할 필요가 있을 것이다
23 | r, _ := regexp.Compile("p([a-z]+)ch")
24 |
25 | // 이 구조체에 많은 메소드들이 사용가능하다.
26 | //여기 우리가 전에서 본것과 비슷한 매치 테스트가 있다.
27 | fmt.Println(r.MatchString("peach"))
28 |
29 | // 이것은 정규식에 매칭되는 것을 찾아낸다.
30 | fmt.Println(r.FindString("peach punch"))
31 |
32 | // 이것은 첫번째 매칭되는 것을 찾을 뿐만 아니라, 매칭된 텍스트가 아닌 매칭된 것의 처음과 끝의 인덱스값을 리턴한다.
33 | fmt.Println(r.FindStringIndex("peach punch"))
34 |
35 | // `Submatch` 이 변종녀석은 정보를 포함하는데, 매칭되는 전체매칭과 그러한 전체 매칭에서의 하위매칭을 보여준다.
36 | // (역주: 정규식이 p로 시작하고 ch로 끝나는 것인데 먼저 peach를 찾고 peach에서 p, ch를 자른 ea를 리턴함)
37 | // 예제로, 이것은 p([a-z]+)ch 와 ([a-z]+)에 대한 정보 둘다를 리턴한다.
38 | fmt.Println(r.FindStringSubmatch("peach punch"))
39 |
40 | // 비슷하게 이것은 매칭되는 것의 인덱스와 서브매칭되는 것의 인덱스를 리턴한다.
41 | fmt.Println(r.FindStringSubmatchIndex("peach punch"))
42 |
43 | // 이 'All' 변형은 입력에 대해서 첫번째값만이 아닌 모든 매칭값에 적용된다.
44 | // 예제에서 정규식에 맞는 모든 매칭값을 찾을 것이다.
45 | fmt.Println(r.FindAllString("peach punch pinch", -1))
46 |
47 | // 이러한 'All' 변형은 우리가 위에서 보았던 다른 함수들에도 적용가능하다.
48 | fmt.Println(r.FindAllStringSubmatchIndex(
49 | "peach punch pinch", -1))
50 |
51 | // 네거티브하지 않은 정수(양수)를 두번째 파라미터로 제공함으로써 매칭되는 것의 개수를 정할 수 있다.
52 | fmt.Println(r.FindAllString("peach punch pinch", 2))
53 |
54 | // 우리의 위의 예제에서 문자열 파라미터를 썼었고 `MatchString` 같은 이름을 썼었지만,
55 | // 우리는 또한 []byte 아규먼트를 주고 함수 이름에서 'String'을 얻을 수 있다.
56 | fmt.Println(r.Match([]byte("peach")))
57 |
58 | // 정규식표현과 함께 상수(constants)를 생성할 때, 우리는 'Compile'의 변종인 `MustCompile`을 사용할 수 있다.
59 | // Compile은 2개의 리턴값을 가지므로 상수에서 쓰일 수 없다.
60 | r = regexp.MustCompile("p([a-z]+)ch")
61 | fmt.Println(r)
62 |
63 | // `regexp` 패키지는 어떤 다른 값을 가지고, 문자열의 일부분을 바꾸는 데 사용할 수도 있다.
64 | fmt.Println(r.ReplaceAllString("a peach", ""))
65 |
66 | // `Func`변종은 매칭된 텍스트를 주어진 함수로 함께 바꿀 수 있게 해준다.
67 | in := []byte("a peach")
68 | out := r.ReplaceAllFunc(in, bytes.ToUpper)
69 | fmt.Println(string(out))
70 | }
71 |
--------------------------------------------------------------------------------
/gotour/71_웹크롤러.go:
--------------------------------------------------------------------------------
1 | // 71_웹크롤러
2 | package main
3 |
4 | import (
5 | "fmt"
6 | )
7 |
8 | type Fetcher interface {
9 | // Fetch returns the body of URL and
10 | // a slice of URLs found on that page.
11 | Fetch(url string) (body string, urls []string, err error)
12 | }
13 |
14 | // Crawl uses fetcher to recursively crawl
15 | // pages starting with url, to a maximum of depth.
16 | func Crawl(url string, depth int, fetcher Fetcher) {
17 | // TODO: Fetch URLs in parallel.
18 | // TODO: Don't fetch the same URL twice.
19 | // This implementation doesn't do either:
20 | if depth <= 0 {
21 | return
22 | }
23 | body, urls, err := fetcher.Fetch(url)
24 | if err != nil {
25 | fmt.Println(err)
26 | return
27 | }
28 | fmt.Printf("found: %s %q\n", url, body)
29 | for _, u := range urls {
30 | Crawl(u, depth-1, fetcher)
31 | }
32 | return
33 | }
34 |
35 | func main() {
36 | Crawl("http://golang.org/", 4, fetcher)
37 | }
38 |
39 | // fakeFetcher is Fetcher that returns canned results.
40 | type fakeFetcher map[string]*fakeResult
41 |
42 | type fakeResult struct {
43 | body string
44 | urls []string
45 | }
46 |
47 | func (f *fakeFetcher) Fetch(url string) (string, []string, error) {
48 | if res, ok := (*f)[url]; ok {
49 | return res.body, res.urls, nil
50 | }
51 | return "", nil, fmt.Errorf("not found: %s", url)
52 | }
53 |
54 | // fetcher is a populated fakeFetcher.
55 | var fetcher = &fakeFetcher{
56 | "http://golang.org/": &fakeResult{
57 | "The Go Programming Language",
58 | []string{
59 | "http://golang.org/pkg/",
60 | "http://golang.org/cmd/",
61 | },
62 | },
63 | "http://golang.org/pkg/": &fakeResult{
64 | "Packages",
65 | []string{
66 | "http://golang.org/",
67 | "http://golang.org/cmd/",
68 | "http://golang.org/pkg/fmt/",
69 | "http://golang.org/pkg/os/",
70 | },
71 | },
72 | "http://golang.org/pkg/fmt/": &fakeResult{
73 | "Package fmt",
74 | []string{
75 | "http://golang.org/",
76 | "http://golang.org/pkg/",
77 | },
78 | },
79 | "http://golang.org/pkg/os/": &fakeResult{
80 | "Package os",
81 | []string{
82 | "http://golang.org/",
83 | "http://golang.org/pkg/",
84 | },
85 | },
86 | }
87 |
88 | /*
89 | 이 연습에서는 고의 동시성 기능을 사용해 웹 크롤러를 병렬화 해 볼 것입니다.
90 |
91 | Crawl 함수를 고쳐서, 같은 URL을 두번 가져오는 중복을 피하면서 URL들을 병렬로 패치하게 고쳐보세요.
92 |
93 | Written by arahansa
94 | https://www.facebook.com/groups/golangko/
95 | 모든 내용은 http://go-tour-kr.appspot.com/
96 | */
97 |
--------------------------------------------------------------------------------
/effectivego/07_데이터/06_맵스.go:
--------------------------------------------------------------------------------
1 | /*Maps
2 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
3 |
4 |
5 | Map은 서로 다른 타입의 값들에 접근하기 위한 편리하고 강력한 자료구조 입니다.
6 | Key는 동등연산자(==)이 가능한 integer, float, 복소수, string, 포인터,
7 | 그리고 인터페이스(dynamic 타입이 동등연산을 지원한다면)와 같이 어떤 타입이든 될 수 있습니다.
8 |
9 | 반면, struct와 배열 그리고 slice는 동등연산을 할 수 없기 때문에 map key로는 사용할 수 없습니다.
10 | slice처럼 map은 참조타입 입니다. 함수에 map을 값으로 넘기고 함수 안에서 변경하게 되면,
11 | map 값의 변경사항을 호출자가 확인할 수 있을 것 입니다.
12 |
13 | map은 일반적으로 콜론으로 구분되어지는 key값들을 사용해 생성하게 됩니다.
14 | 즉, map을 초기화하여 만드는 것은 쉽습니다.
15 | */
16 |
17 | var timeZone = map[string] int {
18 | "UTC": 0*60*60,
19 | "EST": -5*60*60,
20 | "CST": -6*60*60,
21 | "MST": -7*60*60,
22 | "PST": -8*60*60,
23 | }
24 | //map의 값을 지정하고 불러오는 것은 인덱스에 정수를 사용하지 않는 것 말고는 배열과 동일한 것 처럼 보입니다.
25 |
26 | offset := timeZone["EST"]
27 | /*map에서 map에 존재하지 않는 key를 사용해 값을 불러오려고 시도하면 0 값을 반환할 것 입니다.
28 | 예를 들면, map이 integer값을 포함하고 있다면, 존재하지 않는 key 값으로 검색을 하면 0을 반환하게 됩니다.
29 | 집합(set)은 bool 타입의 map으로 구현될 수 있습니다.
30 | 집합에 포함시키기 위해 map 항목의 값을 true로 정하면 됩니다. 그리고 인덱스로 테스트 해보십시오.*/
31 |
32 | attended := map[string] bool {
33 | "Ann": true,
34 | "Joe": true,
35 | ...
36 | }
37 |
38 | if attended[person] { // will be false if person is not in the map
39 | fmt.Println(person, "was at the meeting")
40 | }
41 | /*
42 | 때로는 zero 값을 사용해서 빠진 항목을 구분해야할 필요가 있습니다.
43 | (위 예제에서) UTC라는 항목이 있는지 또는 그것이 map 안에 전혀 없기 때문에 값이 zero 값인지
44 | 다중 할당(multiple assignment)을 사용해서 구분할 수 있습니다.
45 | */
46 | var seconds int
47 | var ok bool
48 | seconds, ok = timeZone[tz]
49 | /*
50 | 이 것은 "comma ok"라고 불려집니다. 예를 들어, 만약 tz가 존재한다면, seconds는 적절한 값이
51 | 들어갈 것이고 ok는 true가 될 것 입니다. 만약 그렇지 않다면, seconds는 zero값이 될 것이고
52 | ok는 false가 될 것 입니다. 여기 그 두가지를 함께 사용한 error report 함수 예제가 있습니다.
53 | */
54 |
55 | func offset(tz string) int {
56 | if seconds, ok := timeZone[tz]; ok {
57 | return seconds
58 | }
59 | log.Println("unknown time zone:", tz)
60 | return 0
61 | }
62 | /*
63 | 실제 값에 대해 map 안에 존재하는지 여부를 시험하기 위해서, blank 식별자나 underscore(_)를 사용할 수도 있습니다.
64 | blank 식별자는 지정되거나(assign) 또는 어떤 타입의 값으로든 선언될 수 있습니다.
65 | map에 존재하는지 테스트하기 위해서 일반적인 변수를 사용하는 곳에 blank 식별자를 사용해 보십시오.
66 | */
67 |
68 | _, present := timeZone[tz]
69 | /*
70 | map의 항목을 삭제하기 위해서는, 다중 할당(multiple assignment)에서 위치를 서로 바꾸고,
71 | boolean 값을 오른쪽에 위치시키면 됩니다.(아래 예와 같이) 만약 boolean 값이 false라면
72 | 그 항목은 삭제될 것입니다. 심지어, map에서 이미 그 key가 삭제되었다고 하더라도 이렇게 하는 것은 안전합니다.
73 | */
74 |
75 | timeZone["PDT"] = 0, false // Now on Standard Time
--------------------------------------------------------------------------------
/gobyexample/21_에러.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/errors
4 |
5 | Go by Example: Errors
6 |
7 | Go 에서는 명시적이고 분리된 리턴값으로 에러를 처리하는 것이 자연스럽다.
8 | 이것은 자바나 루비에서 사용되는 예외, 혹은 과적된 단일 결과와는 대조적이다.
9 | 에러값은 때때로 C에서 사용되었다. Go의 접근은 어떤 함수가 에러를 리턴하는지 보기 쉽게 하고,
10 | 에러를 같은언어구조를 사용하여 에러를 다루는 것이다.
11 |
12 | *여긴 같은 언어구조에 대한 설명 : constructs employed for any other, non-error tasks.
13 | same language 뒤에 바로 나온 말인데 무슨 말인지 그냥 패쓰함; 별로 안 중요한 것같기도하고;
14 | 요새 좀 바쁘다 ㅠ흙.
15 |
16 | 역주 개요: f1 과 f2를 만들어서 에러를 테스트 해본다.
17 | f1은 errors.New로 에러를 만들어 리턴하고,
18 | f2는 &접두어를 이용하여 새로운 구조체를 만들어 리턴한다.
19 | */
20 | package main
21 |
22 | import "errors"
23 | import "fmt"
24 |
25 | // 관습적으로, 에러는 마지막으로 리턴된 값이고. 내장된 인터페이스 타입 'error'를 가짐.
26 | func f1(arg int) (int, error) {
27 | if arg == 42 {
28 |
29 | // `errors.New` 는 기초적인 'error'값을 주어진 메시지와 함께 생성한다.
30 | return -1, errors.New("can't work with 42")
31 |
32 | }
33 | // 에러 포지션에서 nil값은 에러가 없다는 것을 가리킨다.
34 | return arg + 3, nil
35 | }
36 |
37 | // 에러의 커스텀타입을 사용하는 것은 가능하며, Error() 메소드를 구현하면 된다.
38 | // 여기에 명시적으로 아규먼트 에러를 나타내는 커스텀 타입을 사용하는 다양한 예제가 있다.
39 | type argError struct {
40 | arg int
41 | prob string
42 | }
43 |
44 | func (e *argError) Error() string {
45 | return fmt.Sprintf("%d - %s", e.arg, e.prob)
46 | }
47 |
48 | func f2(arg int) (int, error) {
49 | if arg == 42 {
50 |
51 | // 이러한 경우 우리는 &argError 문법을 사용하여서 새로운 구조체를 만든다.
52 | // 구조체는 두개의 필드 arg와 prob를 제공한다.
53 | return -1, &argError{arg, "can't work with it"}
54 | }
55 | return arg + 3, nil
56 | }
57 |
58 | func main() {
59 |
60 | // 이 밑에 있는 두개의 반복문은 각각 에러-리턴 function을 test한다.
61 | // if문에서 인라인에러체크의 사용은 Go code에서 흔한 사용이라는 것을 알아두자.
62 | // if문에서 한줄로 e!=nil 이것 말하는 것임(역주)
63 | for _, i := range []int{7, 42} {
64 | if r, e := f1(i); e != nil {
65 | fmt.Println("f1 failed:", e)
66 | } else {
67 | fmt.Println("f1 worked:", r)
68 | }
69 | }
70 | for _, i := range []int{7, 42} {
71 | if r, e := f2(i); e != nil {
72 | fmt.Println("f2 failed:", e)
73 | } else {
74 | fmt.Println("f2 worked:", r)
75 | }
76 | }
77 | // 만약 커스텀에러에서 프로그래밍적으로 데이터를 사용하고 싶다면
78 | // type assertion을 통해서 커스텀에러의 인스턴스를 에러로서 받기를 필요로 할 것이다.
79 | //역주 : ae, ok := e.(*argError);이 type assertion인듯하다.
80 | _, e := f2(42)
81 | if ae, ok := e.(*argError); ok {
82 | fmt.Println("여기가 에러 출력부분(역주: 더 넣음) ")
83 | fmt.Println(ae.arg)
84 | fmt.Println(ae.prob)
85 | }
86 | // If you want to programmatically use the data in
87 | // a custom error, you'll need to get the error as an
88 | // instance of the custom error type via type
89 | // assertion.
90 | }
91 |
--------------------------------------------------------------------------------
/gobyexample/45_문자열포맷팅.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/string-formatting
4 | Go by Example: string-formatting
5 |
6 | Go는 printf전통속에서 문자열 형식을 훌륭하게 지원한다.
7 | 여기 평범한 문자열형식처리의 예제가 있다.
8 | */
9 |
10 | package main
11 |
12 | import "fmt"
13 | import "os"
14 |
15 | type point struct {
16 | x, y int
17 | }
18 |
19 | func main() {
20 |
21 | //Go는 몇몇 printing "동사"를 제공하는데 이것은 일반적 Go의 값들을 형식화하기 위해서다.
22 | //예를 들자면 이것은 point구조체의 인스턴스를 출력한다.
23 | p := point{1, 2}
24 | fmt.Printf("%v\n", p)
25 |
26 | //만약 값이 구조체라면 %+v 변종은 구조체의 name또한 포함한다.
27 | fmt.Printf("%+v\n", p)
28 |
29 | // %#v 변종은 값의 Go문법표현을 출력한다. 예를 들어서 그 값을 만들어내는 소스코드 snippet 같은 것들말이다.
30 | fmt.Printf("%#v\n", p)
31 |
32 | // 값의 타입을 출력하기 위해 %T를 사용했다.
33 | fmt.Printf("%T\n", p)
34 |
35 | // 참거짓형식화는 간단하다.
36 | fmt.Printf("%t\n", true)
37 |
38 | // 정수를 형식화하는 데는 많은 옵션이 있는데 %d가 표준이고 10진수다.
39 | fmt.Printf("%d\n", 123)
40 |
41 | // 바이러니 표현을 출력한다.
42 | fmt.Printf("%b\n", 14)
43 |
44 | //주어진 값에 맞는 문자를 출력한다.
45 | fmt.Printf("%c\n", 33)
46 | // %x는 hex인코딩을 제공한다.
47 | fmt.Printf("%x\n", 456)
48 |
49 | // Float를 위한 몇몇 옵션또한 있다.
50 | //기본적인 Decimal 포맷은 %f사용이다.
51 | fmt.Printf("%f\n", 78.9)
52 |
53 | // %e나 %E 는(약간 다른 버젼이다) 과학적 표시에서의 형식이다.
54 | fmt.Printf("%e\n", 123400000.0)
55 | fmt.Printf("%E\n", 123400000.0)
56 |
57 | // 기본 문자열출력은 %s를 사용
58 | fmt.Printf("%s\n", "\"string\"")
59 |
60 | // Go 소스 에서 두개 더블 인용문자열을 하려면%q를 사용하라.
61 | fmt.Printf("%q\n", "\"string인용구 테스트\"")
62 |
63 | // 우리가 전에 본 정수처럼, %x는 입력바이트당 두개의 출력문자열들을 가지고서 16진수문자열을 렌더링한다.
64 | fmt.Printf("%x\n", "hex this")
65 |
66 | // 포인터 표현(representation)을 출력하기 위해 여기선 %p를 썼다.
67 | fmt.Printf("%p\n", &p)
68 |
69 | // 숫자를 형식화할때, 종종 결과수치의 가로길이를 종종 조정하고 싶을 지도 모른다.
70 | // 가로길이를 정하기 위해, %뒤에 숫자를 써준다.
71 | // 디폴트로 결과를 오른쪽정렬될 것이며 왼쪽에 공백(왼쪽)과 함께 들어갈 것이다.
72 | fmt.Printf("|%6d|%6d|\n", 12, 345)
73 |
74 | // 당신은 또한 출력된 실수의 가로길이를 정할 수 있는데, 또한 실수 소수점 뒷자리 부분길이도 정하고 싶을 것이다.
75 | // 그럴때는 길이.소수점뒷자리수길이 로 해주면 된다.
76 | fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)
77 |
78 | // 왼쪽 정렬을 하기 위해 - 플래그를 이용하자
79 | fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)
80 |
81 | // 문자열 포맷팅 할때 가로길이를 정하고 싶을 지도 모른다. 특히 테이블비슷한 출력을 하고 싶을 때 말이다.
82 | // 다음은 오른쪽 정렬되는 문자열들이다.
83 | fmt.Printf("|%6s|%6s|\n", "foo", "b")
84 |
85 | //왼쪽정렬을 할때는 - 플래그를 써준다.
86 | fmt.Printf("|%-6s|%-6s|\n", "foo", "b")
87 |
88 | //지금까지 우리는 'Printf'를 살펴보았는데, 이것은 형식화된 문자열을 'os.Stdout'에 출력한다
89 | // Sprintf는 문자열을 형식화하며, 출력을 하지 않고 문자열을 리턴한다.
90 | s := fmt.Sprintf("a %s", "string")
91 | fmt.Println(s)
92 |
93 | //또한 Fprintf를 사용하여 형식화+출력을 'os.Stdout'이 아닌 'io.Writers'에 할 수 있다.
94 | fmt.Fprintf(os.Stderr, "an %s\n", "error")
95 | }
96 |
--------------------------------------------------------------------------------
/effectivego/08_초기화.go:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | 원본주소 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
4 |
5 | 비록, C나 C++의 초기화 과정과 표면적으로 아주 다르게 보이는 부분은 없지만,
6 | Go 언어의 초기화 과정은 보다 강력합니다.
7 | 초기화 과정에서 복잡한 구조체가 만들어지고,
8 | 초기화된 Object와 여타 package간의 배치가 보다 명확하게 다루어집니다.
9 |
10 | 상수(Constants)
11 | Go 언어에서 상수는 말그대로 상수입니다.
12 | 상수는 컴파일 시점에 생성되며, - 심지어 함수의 지역 상수라도 - 그 값은 숫자, 문자열, boolean 만 가능합니다.
13 | 컴파일 시점에 생성되는 제약때문에, 상수를 정의하는 표현은 컴파일러가 이해할 수 있는 상수 형태이어야 합니다.
14 | 예를 들어 1<<3 은 상수 형태이고, math.Sin(math.Pi/4)는 math.Sin 함수가 런타임에 호출되어야 하므로 상수 형태라고 할 수 없습니다.
15 |
16 | Go 언어에서, 열거된 상수는 iota 열거자(iota enumerator)를 사용해서 생성합니다.
17 | iota는 expression의 한 부분이 될 수 있고, expression은 무조건적인 반복이 될 수 있기 때문에,
18 | 그것은 복잡한 값의 집합이 되기 쉽습니다.
19 | */
20 | type ByteSize float64
21 |
22 | const (
23 | _ = iota // ignore first value by assigning to blank identifier
24 | KB ByteSize = 1 << (10 * iota)
25 | MB
26 | GB
27 | TB
28 | PB
29 | EB
30 | ZB
31 | YB
32 | )
33 |
34 | /*
35 | String과 같은 메소드를 추가하는 기능은 일반적인 타입의 한 부분일지라도,
36 | 출력에 대해 그런 값들이 자동으로 형식화되도록 하는 것을 가능하게 합니다.
37 | */
38 | func (b ByteSize) String() string {
39 | switch {
40 | case b >= YB:
41 | return fmt.Sprintf("%.2fYB", float64(b/YB))
42 | case b >= ZB:
43 | return fmt.Sprintf("%.2fZB", float64(b/ZB))
44 | case b >= EB:
45 | return fmt.Sprintf("%.2fEB", float64(b/EB))
46 | case b >= PB:
47 | return fmt.Sprintf("%.2fPB", float64(b/PB))
48 | case b >= TB:
49 | return fmt.Sprintf("%.2fTB", float64(b/TB))
50 | case b >= GB:
51 | return fmt.Sprintf("%.2fGB", float64(b/GB))
52 | case b >= MB:
53 | return fmt.Sprintf("%.2fMB", float64(b/MB))
54 | case b >= KB:
55 | return fmt.Sprintf("%.2fKB", float64(b/KB))
56 | }
57 | return fmt.Sprintf("%.2fB", float64(b))
58 | }
59 |
60 | /*
61 | ( float64 변환은 Sprintf가 ByteSize?에 대해 String 메소드를 통해 반복되는 것을 막아줍니다.)
62 | YB 표현식(expression)은 1.00YB로 출력됩니다. 반면 ByteSize?(1e13)은 9.09TB로 출력됩니다.
63 |
64 | 변수(Variables)
65 |
66 | 변수는 상수처럼 초기화될 수 있지만 초기화는 런타임(run time)에 계산되는 일반적인 표현식(expression)이 될 수도 있습니다.
67 | */
68 | var (
69 | HOME = os.Getenv("HOME")
70 | USER = os.Getenv("USER")
71 | GOROOT = os.Getenv("GOROOT")
72 | )
73 |
74 | /*
75 | 초기화 함수(The init function)
76 | 마침내, 각 소스파일은 어떤 명령문이던 간에 필요하다면 셋업하기 위해 자신만의 init() 함수를 정의할 수 있습니다.
77 | 유일한 제한은 비록, 초기화하는 동안 go 루틴이 시작될 수 있다고 해도, 초기화가 끝날때까지는 실행되지 않을 것이라는 점입니다.
78 | 초기화는 항상 단일 스레드로 실행됩니다. 그리고 마지막으로, 팩케지 안에 모든 변수 선언이 초기화된 뒤에 init()이 호출되어 집니다.
79 |
80 | 선언으로서 표현될 수 없는 초기화에 비해, init() 함수의 일반적인 사용은 실제 실행이 시작되기 전에
81 | 검증이나 프로그램 명령문의 정확한 수정을 위해 사용될 수 있습니다.
82 | */
83 | func init() {
84 | if USER == "" {
85 | log.Fatal("$USER not set")
86 | }
87 | if HOME == "" {
88 | HOME = "/usr/" + USER
89 | }
90 | if GOROOT == "" {
91 | GOROOT = HOME + "/go"
92 | }
93 | // GOROOT may be overridden by --goroot flag on command line.
94 | flag.StringVar(&GOROOT, "goroot", GOROOT, "Go root directory")
95 | }
--------------------------------------------------------------------------------
/gobyexample/43_콜렉션펑션.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/collection-functions
4 |
5 | Go by Example: collection-functions
6 |
7 | 우리는 종종 우리의 프로그램이 데이터콜렉션 위에서 작업을 수행하기를 원한다.
8 | 주어진 술어(predicate)를 만족시키는 모든 아이템들을 selecting 하거나
9 | 커스텀 함수를 이용하여 모든 item들을 새로운 콜렉션에 매핑하는 일같은 것들 말이다.
10 |
11 | 어떤 언어에서는 제너릭 데이터구조와 알고리즘을 사용하는 것이 흔하다.
12 | Go는 제너릭을 지원하지 않는다.
13 | 당신의 프로그램과 데이터 타입이 특별히 제너릭을 필요로 할때는 Go에서는 콜렉션함수를 제공하는 것이 흔하다.
14 |
15 | 여기 문자열 슬라이스를 위한 콜렉션함수의 예제가 있다. 이 예제를 이용해서 당신 자신만의 함수를 만들 수 있다.
16 | 어떤 경우에는 헬퍼함수를 생성하고 호출하는 것보다 코드를 직접적으로 조정하며 콜렉션을 처리하는 것이 제일 깔끔할 수도 있다.
17 | */
18 |
19 | package main
20 |
21 | import "strings"
22 | import "fmt"
23 |
24 | // 타겟문자열t 의 인덱스를 리턴하거나, 매칭되는게 없다면 -1을 리턴한다.
25 | func Index(vs []string, t string) int {
26 | for i, v := range vs {
27 | if v == t {
28 | return i
29 | }
30 | }
31 | return -1
32 | }
33 |
34 | // 만약 타겟문자열 t가 슬라이스에 있다면 true를 리턴한다.
35 | func Include(vs []string, t string) bool {
36 | return Index(vs, t) >= 0
37 | }
38 |
39 | // 만약 슬라이스 안의 문자열중의 하나가 f(역주: 단어뜻은 술어? 인데 여기선 f func를 말하는듯)를 만족하면
40 | // true를 리턴한다.
41 | func Any(vs []string, f func(string) bool) bool {
42 | for _, v := range vs {
43 | if f(v) {
44 | return true
45 | }
46 | }
47 | return false
48 | }
49 |
50 | // 만약 슬라이스의 모든 문자열이 f술어를 만족하면 참을 리턴한다.
51 | func All(vs []string, f func(string) bool) bool {
52 | for _, v := range vs {
53 | if !f(v) {
54 | return false
55 | }
56 | }
57 | return true
58 | }
59 |
60 | // f를 만족시키는 슬라이스에서 모든 문자열을 가지고 있는 새로운 슬라이스를 리턴한다.
61 | // 원문 참조
62 | // Returns a new slice containing all strings in the
63 | // slice that satisfy the predicate `f`.
64 | func Filter(vs []string, f func(string) bool) []string {
65 | vsf := make([]string, 0)
66 | for _, v := range vs {
67 | if f(v) {
68 | vsf = append(vsf, v)
69 | }
70 | }
71 | return vsf
72 | }
73 |
74 | // 원래 슬라이스에있는 문자열마다 func f를 적용시킨 결과를 가지고 있는 새로운 슬라이스를 리턴한다.
75 | func Map(vs []string, f func(string) string) []string {
76 | vsm := make([]string, len(vs))
77 | for i, v := range vs {
78 | vsm[i] = f(v)
79 | }
80 | return vsm
81 | }
82 |
83 | func main() {
84 | // 여기 우리가 테스트해보려는 다양한 콜렉션 함수가 있다.
85 | var strs = []string{"peach", "apple", "pear", "plum"}
86 |
87 | fmt.Println(Index(strs, "pear"))
88 |
89 | fmt.Println(Include(strs, "grape"))
90 |
91 | fmt.Println(Any(strs, func(v string) bool {
92 | return strings.HasPrefix(v, "p")
93 | }))
94 |
95 | fmt.Println(All(strs, func(v string) bool {
96 | return strings.HasPrefix(v, "p")
97 | }))
98 |
99 | fmt.Println(Filter(strs, func(v string) bool {
100 | return strings.Contains(v, "e")
101 | }))
102 |
103 | //위의 예제에서 우리는 익명함수를 사용했지만 당신은 또한 올바른 타입의 이름있는 함수를 사용할 수 있다.
104 | fmt.Println(Map(strs, strings.ToUpper))
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/gobyexample/62_프로세스생성.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/spawning-processes
4 | Go by Example:spawning-processes
5 |
6 |
7 | 때때로 우리의 Go 프로그램들은 Go 가 아닌 프로세스같은 것들을 만들기 원한다.
8 | 예를 들자면 이 사이트의 신택스 Go 프로그램에서 pygmentize를 spawning함으로써 구현되었다.
9 | Go로부터 spawning 프로세스들의 예제를 한번 살펴보자.
10 | */
11 |
12 | package main
13 |
14 | import "fmt"
15 | import "io/ioutil"
16 | import "os/exec"
17 |
18 | func main() {
19 |
20 | // 우리는 어떠한 아규먼트나 입력값을 받지 않는 간단한 커맨드로 시작해보고자 한다.
21 | //그리고 어떤 것을 stdout에 출력시킬 것이다.
22 | // 'exe.Command' 헬퍼는 객체를 생성하여 이러한 외부 처리를 표현한다.
23 | dateCmd := exec.Command("date")
24 |
25 | // .Output 은 다른 다른 헬퍼로써, 보통 실행중인 커맨드를 다루는 경우나, 그것이 마칠때까지 기다리거나
26 | // 그것의 결과를 모은다. 에러가 없다면 dateOut은 날짜 정보와 함께 바이트를 가지고 있을 것이다.
27 | dateOut, err := dateCmd.Output()
28 | if err != nil {
29 | panic(err)
30 | }
31 | fmt.Println("> date")
32 | fmt.Println(string(dateOut))
33 |
34 | // 다음 우리는 좀더 연관된 케이스를 살펴 볼 것인데 이 케이스는
35 | // 외부 프로세스의 stdin으로 데이터를 보내고
36 | // 결과를 그것의 stdout으로 받을 것이다.
37 | // Next we'll look at a slightly more involved case
38 | // where we pipe data to the external process on its
39 | // `stdin` and collect the results from its `stdout`.
40 | grepCmd := exec.Command("grep", "hello")
41 |
42 | // 여기 우리는 명시적으로 input/output 파이프들을 잡을 것이다.
43 | // 프로세스를 시작하면서 몇몇 입력을 여기에 할 것이고
44 | // 결과 출력을 읽을 것이며, 최종적으로 프로세스가 종료되길 기다릴 것이다.
45 | // Here we explicitly grab input/output pipes, start
46 | // the process, write some input to it, read the
47 | // resulting output, and finally wait for the process
48 | // to exit.
49 | grepIn, _ := grepCmd.StdinPipe()
50 | grepOut, _ := grepCmd.StdoutPipe()
51 | grepCmd.Start()
52 | grepIn.Write([]byte("hello grep\ngoodbye grep"))
53 | grepIn.Close()
54 | grepBytes, _ := ioutil.ReadAll(grepOut)
55 | grepCmd.Wait()
56 |
57 | // 우리는 위의 예제에서 에러체크를 생략했다. 그러나 우리는 흔한 'if err != nil '패턴을 모든 이것들에 써도 된다.
58 | // 우리는 또한 'StdoutPipe'결과귿릉ㄹ 모을 것이나, 당신은 또한 정확히 같은 방법으로 'StderrPipe'를 받아도 된다.
59 | // We ommited error checks in the above example, but
60 | // you could use the usual `if err != nil` pattern for
61 | // all of them. We also only collect the `StdoutPipe`
62 | // results, but you could collect the `StderrPipe` in
63 | // exactly the same way.
64 | fmt.Println("> grep hello")
65 | fmt.Println(string(grepBytes))
66 |
67 | // 커맨드를 실행할 때는 우리가 기술된 커맨드와 아규먼트들을 제공할 필요가 있다는 것을 기억하자
68 | // 반면에 하나의 커맨드-라인 문자열을 전달해도 된다.
69 | // 만약 당신이 완전한 커맨드를 문자열로 실행시키고 싶으면 당신은 'bash'의 '-c'옵션을 사용할 수 있다
70 | // Note that when spawning commands we need to
71 | // provide an explicitly delineated command and
72 | // argument array, vs. being able to just pass in one
73 | // command-line string. If you want to spawn a full
74 | // command with a string, you can use `bash`'s `-c`
75 | // option:
76 | lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
77 | lsOut, err := lsCmd.Output()
78 | if err != nil {
79 | panic(err)
80 | }
81 | fmt.Println("> ls -a -l -h")
82 | fmt.Println(string(lsOut))
83 | }
84 |
--------------------------------------------------------------------------------
/effectivego/06_함수/03_Defer.go:
--------------------------------------------------------------------------------
1 | /*Defer
2 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
3 | Go 언어에서 defer 문은 함수가 지연된 리턴값을 실행하기 전에 즉시 실행될 수 있도록
4 | 하나의 function call을 예약합니다.(the deferred function)
5 | 일반적이지는 않지만 어떤 경로의 함수가 값을 리턴하는지에 관계없이 자원을 해제해야만하는 상황을
6 | 다루기 위해서는 효과적인 방법입니다.전형적인 예로 mutex를 해제하거나 file을 닫는 경우 입니다.
7 |
8 | // Contents returns the file's contents as a string.
9 | */
10 | func Contents(filename string) (string, os.Error) {
11 | f, err := os.Open(filename, os.O_RDONLY, 0)
12 | if err != nil {
13 | return "", err
14 | }
15 | defer f.Close() // f.Close()는 현재의 함수가 종료되면 실행되어 질 것입니다.
16 |
17 | var result []byte
18 | buf := make([]byte, 100)
19 | for {
20 | n, err := f.Read(buf[0:])
21 | result = append(result, buf[0:n]...) // append와 관련해서는 추후에 다루게 될 것입니다.
22 | if err != nil {
23 | if err == os.EOF {
24 | break
25 | }
26 | return "", err // 여기서 리턴한다면 f는 닫히게 될 것입니다.
27 | }
28 | }
29 | return string(result), nil // 여기서 리턴한다면 f는 닫히게 될 것입니다.
30 | }
31 | /*
32 | Close와 같은 함수에서 지연 호출은 2가지 장점이 있습니다.
33 | 첫번째로, 파일을 닫는 것을 잊지 않도록 해 줄 것입니다.
34 | (만약 함수에서 뒤에 파일 닫는 부분을 작성한다면 잊기 쉽습니다.)
35 |
36 | 두번째로, 이것은 close가 open 근처에 놓이게 된다는 것을 의미하며 함수의 뒷쪽에 놓이는 것보다
37 | 훨씬 더 분명해 보입니다. 지연 함수(the deferred function)에서
38 | 인자값들은(만약 함수가 메소드라면 수신자(receiver)를 포함해서) 호출이 실행될 때가 아니라
39 | defer문이 실행되어 질 때 평가되어 집니다.
40 |
41 | 반면, 함수 실행시에 변수값들의 변화에 대한 문제를 피한다는 측면에서,
42 | 이것은 하나의 지연된 호출이 여러개의 함수 실행을 지연시킬 수 있다는 의미를 가집니다.
43 | 여기 아주 쉬운 예가 있습니다.
44 | */
45 | for i := 0; i < 5; i++ {
46 | defer fmt.Printf("%d ", i)
47 | }
48 |
49 | /*
50 | 지연된 함수들은 LIFO의 순서로 실행되어 집니다.
51 | 그러므로 이 코드는 함수가 종료되었을 때 4 3 2 1 0의 순서로 프린트되어질 것입니다.
52 |
53 | 좀 더 괜찮은 예로 프로그램을 통해 함수 실행을 추적해보는 쉬운 방법이 있습니다.
54 | 우리는 다음과 같이 단순히 경로를 추적하는 몇개의 코드를 작성할 수 있습니다.
55 | */
56 | func trace(s string) { fmt.Println("entering:", s) }
57 | func untrace(s string) { fmt.Println("leaving:", s) }
58 |
59 | // Use them like this:
60 | func a() {
61 | trace("a")
62 | defer untrace("a")
63 | // do something....
64 | }
65 | /*
66 | 우리는 지연된 함수에서 인자값들이 defer문이 실행되어질 때 평가되어진다는 사실을 이용해서
67 | 더 좋은 결과를 얻을 수 있습니다. 경로 추적은 루틴에 인자값을 정함으로서 할 수 있습니다.
68 | */
69 | func trace(s string) string {
70 | fmt.Println("entering:", s)
71 | return s
72 | }
73 |
74 | func un(s string) {
75 | fmt.Println("leaving:", s)
76 | }
77 |
78 | func a() {
79 | defer un(trace("a"))
80 | fmt.Println("in a")
81 | }
82 |
83 | func b() {
84 | defer un(trace("b"))
85 | fmt.Println("in b")
86 | a()
87 | }
88 |
89 | func main() {
90 | b()
91 | }
92 | /*
93 | prints
94 |
95 | entering: b
96 | in b
97 | entering: a
98 | in a
99 | leaving: a
100 | leaving: b
101 | 프로그래머들이 다른 언어에서는 차단되어져있는(block-level) 자원의 관리에 익숙하기 때문에,
102 | defer문은 이상하게 보일지도 모릅니다.하지만 defer문의 가장 흥미롭고 강력한 적용은 block기반이 아니라
103 | function 기반으로부터 온다는 것 입니다.
104 |
105 | 혼란과 복구(panic and recover) 부분에서 우리는 defer문의 또 다른 예를 보게 될 것 입니다.
106 |
107 | */
--------------------------------------------------------------------------------
/gobyexample/38_Stateful고루틴들.Go.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/stateful-goroutines
4 |
5 | Go by Example: stateful-goroutines
6 |
7 | 지난 예제에서 mutexes로 명백한 락킹을 하여, 멀티플고루틴에서 공유된 상태에대한 동기화된 접근을 하였다.
8 | 또다른 선택은 내장된 고루틴과 채널의 동기화특성을 이용하여 같은 결과를 얻는 것이다.
9 | 이 채널기반 접근법은 정확히 1개의 고루틴들이 가진 각각의 데이터 조각들을 서로 통신하고 가짐으로써
10 | Go의 메모리공유 목적(ideas)들을 조정한다.
11 | (번역이 잘 됬는지 모르겠다. 원래 그냥 소스를 보고 실행되는 모습을 봐야할것같다;;:역주)
12 | */
13 |
14 | package main
15 |
16 | import (
17 | "fmt"
18 | "math/rand"
19 | "sync/atomic"
20 | "time"
21 | )
22 |
23 | // 이 예제에서 우리의 상태는 단일 고루틴에 의해 소유될 것이다.
24 | // 이것은 데이터가 동시성 접근에 의한 방해를 받지 않을 것이란 것을 보장한다.
25 | // 상태를 읽거나 쓰기 위해, 다른 고루틴들은 소유하고 있는 고루틴에게 메시지를 보낼 것이며,
26 | // 그에 상응하는 답변을 받을 것이다.
27 | // 이러한 'readOp'과 'writeOp' 구조체는 이러한 요청들과
28 | // 소유하고있는 고루틴이 응답할 방법을 요약(encapsulate)한다.
29 | type readOp struct {
30 | key int
31 | resp chan int
32 | }
33 | type writeOp struct {
34 | key int
35 | val int
36 | resp chan bool
37 | }
38 |
39 | func main() {
40 |
41 | // 전에서 우리는 얼마나 많은 작업이 수행되는지 카운트 했었다.
42 | var ops int64 = 0
43 |
44 | // reads 와 writes채널은 읽고 쓰는 요청을 각각 발행하기 위해 ,
45 | // 다른 고루틴들에 의해 사용될 것이다.
46 | reads := make(chan *readOp)
47 | writes := make(chan *writeOp)
48 |
49 | // 여기 상태를 소유하고있는 고루틴이 있으며, 이것(상태)은 예전의 예제와 같이 맵이지만,
50 | // 지금은 stateful 고루틴에 private 하다.
51 | // 이 고루틴은 반복적으로 reads, writes채널에서 selects하여, 요청이 도착하면 응답한다.
52 | // 응답은 첫번째 요청작업을 수행하며 실행되고 그후 응답채널 resp 에 성공했다고 알리는 값을 전송한다.
53 | go func() {
54 | var state = make(map[int]int)
55 | for {
56 | select {
57 | case read := <-reads:
58 | read.resp <- state[read.key]
59 | case write := <-writes:
60 | state[write.key] = write.val
61 | write.resp <- true
62 | }
63 | }
64 | }()
65 |
66 | // 이것은 100개의 고루틴을 실행하여서 reads채널을 통해 state-owning고루틴에게 reads를 발행한다.
67 | // 각각의 read는 readOp 를 만들어, reads채널로 보내지길 운한다. 그리고
68 | // 제공된 resp채널을 통해 결과를 받기를 원한다.
69 | for r := 0; r < 100; r++ {
70 | go func() {
71 | for {
72 | read := &readOp{
73 | key: rand.Intn(5),
74 | resp: make(chan int)}
75 | reads <- read
76 | <-read.resp
77 | atomic.AddInt64(&ops, 1)
78 | }
79 | }()
80 | }
81 |
82 | // 우리는 10개의 writes를 또한 시작하며, 비슷한 접근을 사용할 것이다.
83 | for w := 0; w < 10; w++ {
84 | go func() {
85 | for {
86 | write := &writeOp{
87 | key: rand.Intn(5),
88 | val: rand.Intn(100),
89 | resp: make(chan bool)}
90 | writes <- write
91 | <-write.resp
92 | atomic.AddInt64(&ops, 1)
93 | }
94 | }()
95 | }
96 |
97 | // 1초동안 고루틴들이 일하게 하자
98 | time.Sleep(time.Second)
99 |
100 | //마지막으로, ops카운트를 캡쳐하고 보고하게 하자.
101 |
102 | opsFinal := atomic.LoadInt64(&ops)
103 | fmt.Println("ops:", opsFinal)
104 |
105 | //우리의 프로그램을 실행하는 것은 고루틴기반한 관리예제로 초당 800,000작업을 수행했다.
106 | // 이 특별한 케이스에서 고루틴기반접근은 뮤텍스기반접근보다 좀 더 관여한다.(밑에 원문 남김)
107 | //For this particular case the goroutine-based approach was a bit more involved than the mutex-based one
108 |
109 | // 그러나 특정한 케이스에서 이것은 좀 더 유용할 것이다. 예를 들자면 다른 채널을 가진 곳에서나
110 | // mutexes들이 에러를 발생하려는 경향이 있는 멀티플한 것을 관리할 때 말이다.
111 | //당신은 어떠한 접근이건, 좀 더 자연스러운 접근을 해야하며 특히 당신의 프로그램에 올바른 것이 무엇인지 이해하는 것이 중요하다
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/gobyexample/47_JSON.go:
--------------------------------------------------------------------------------
1 | /*
2 | author twitter : @mmcgrana
3 | https://gobyexample.com/json
4 | Go by Example: json
5 |
6 | Go는 내장된 내장된 커스텀 데이터타입으로의 JSON 인코딩과 디코딩을 내장형태로 지원한다.
7 | */
8 |
9 | package main
10 |
11 | import "encoding/json"
12 | import "fmt"
13 | import "os"
14 |
15 | // 우리는 이 두가지 구조체를 사용하여 커스텀타입의 인코딩과 디코딩을 해볼 것이다.
16 | type Response1 struct {
17 | Page int
18 | Fruits []string
19 | }
20 | type Response2 struct {
21 | Page int `json:"page"`
22 | Fruits []string `json:"fruits"`
23 | }
24 |
25 | func main() {
26 |
27 | //먼저 우리는 기본데이터타입을 JSON 문자열로 인코딩하는 것을 살펴볼 것이다.
28 | // 여기 원자값(atomic)을 위한 몇가지 예제가 있다.
29 | bolB, _ := json.Marshal(true)
30 | fmt.Println(string(bolB))
31 |
32 | intB, _ := json.Marshal(1)
33 | fmt.Println(string(intB))
34 |
35 | fltB, _ := json.Marshal(2.34)
36 | fmt.Println(string(fltB))
37 |
38 | strB, _ := json.Marshal("gopher")
39 | fmt.Println(string(strB))
40 |
41 | // 그리고 여기에 슬라이스와 맵을 위한 몇가지 것들이 있는데,
42 | // 당신이 기대한 JSON 배열과 오브젝트들로 인코딩해준다.
43 | slcD := []string{"apple", "peach", "pear"}
44 | slcB, _ := json.Marshal(slcD)
45 | fmt.Println(string(slcB))
46 |
47 | mapD := map[string]int{"apple": 5, "lettuce": 7}
48 | mapB, _ := json.Marshal(mapD)
49 | fmt.Println(string(mapB))
50 |
51 | // JSON 패키지들은 자동으로 당신의 커스텀 데이터타입을 인코딩할 수있다.
52 | // 그것은 인코딩결과에서 오직 exported된 필드만 포함하고, 기본적으로 그것들의 이름을 JSON 키로 이용한다.
53 | res1D := &Response1{
54 | Page: 1,
55 | Fruits: []string{"apple", "peach", "pear"}}
56 | res1B, _ := json.Marshal(res1D)
57 | fmt.Println(string(res1B))
58 |
59 | // 당신은 구조체필드선언에서 태그를 사용하여서 인코딩된 JSON 키이름을 커스터마이징할수 있다.
60 | // 이러한 태그의 예를 보기 위해 Response2의 정의를 체크해봐라.
61 | res2D := &Response2{
62 | Page: 1,
63 | Fruits: []string{"apple", "peach", "pear"}}
64 | res2B, _ := json.Marshal(res2D)
65 | fmt.Println(string(res2B))
66 |
67 | //이제 JSON데이터가 Go 값으로 디코딩되는 것을 살펴보자.
68 | //여기 일반적인 데이터구조를 위한 예제가 있다.
69 | byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
70 |
71 | // 우리는 JSON 패키지가 디코딩된 데이터를 놓는 곳에 변수를 제공할 필요가 있다
72 | // 이 map[string]interface{}는 무작위 데이터에 대한 문자열맵을 가지고 있다.
73 |
74 | var dat map[string]interface{}
75 |
76 | //여기 실제 디코딩이 있고 연관된 에러를 체크한다.
77 | if err := json.Unmarshal(byt, &dat); err != nil {
78 | panic(err)
79 | }
80 | fmt.Println(dat)
81 |
82 | // 디코딩된 맵에서 값을 사용하기 위해 우리는 적절한 타입으로 형변환을 해줘야 한다.
83 | // 예를 들자면 여기서는 우리는 `num`값을 우리가 예상한 `float64`타입으로 형변환해준다.
84 | num := dat["num"].(float64)
85 | fmt.Println(num)
86 |
87 | // 중첨된 데이터에 접근하는 것은 형변환의 연속을 필요로 한다.
88 | strs := dat["strs"].([]interface{})
89 | str1 := strs[0].(string)
90 | fmt.Println(str1)
91 |
92 | //우리는 또한 JSON 을 커스텀 데이터 타입에 디코딩할 수 있다.
93 | // 이것은 추가적인 타입안전(type-safety)을 우리 프로그램에 더하는 것의 장점을 가지고,
94 | // 디코딩된 데이터에 접근할 떄, type assertions들에 대한 필요성을 제거해준다.
95 | str := `{"page": 1, "fruits": ["apple", "peach"]}`
96 | res := &Response2{}
97 | json.Unmarshal([]byte(str), &res)
98 | fmt.Println(res)
99 | fmt.Println(res.Fruits[0])
100 |
101 | // 예제에서 우리는 언제나 bytes와 string을 data와 JSON표현을 중재하는 데 썼지만,
102 | // 우리는 또한 JSON 인코딩을 직접적으로 `os.Stdout`나 심지어 HTTP 응답몸체같은 `os.Writer`에 데이터전송을 할 수 있다.
103 | enc := json.NewEncoder(os.Stdout)
104 | d := map[string]int{"apple": 5, "lettuce": 7}
105 | enc.Encode(d)
106 | }
107 |
--------------------------------------------------------------------------------
/effectivego/07_데이터/07_출력.go:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | 원글 링크 : https://code.google.com/p/golang-korea/wiki/EffectiveGo
4 |
5 |
6 | 출력 (Printing)
7 | Go언어에서 일반적인 출력은 C언어에서 printf와 비슷한 형태를 사용합니다.
8 | 하지만 더 많은 옵션을 제공하며 일반화되어 있습니다.
9 | 출력 관련 함수들은 fmt 펙케지 안에 있으며 대문자 이름으로 되어 있습니다:
10 | fmt.Printf, fmt, Fprintf, fmt.Sprintf 등등. string 관련 함수들(Sprintf 등)은
11 | 제공된 버퍼를 체우기 보다는 string을 반환합니다.
12 |
13 | 형식적인 string을 제공할 필요가 없습니다.
14 | 각 Printf, Fprintf, Sprintf 함수에는 또 다른 쌍의 함수가 있습니다.
15 | 예를 들면, Print와 Println 입니다. 이러한 함수들은 형식화된 string을 취하지 않지만
16 | 대신, 각각의 인자로 기본 형태의 string을 만듭니다.
17 | Println 함수는 인자와 새로운 라인을 추가하는 사이에 빈공간을 추가합니다.
18 | 반면, Print 함수의 경우는 오직 양쪽 피연산자가 둘다 string이 아닌 경우만 blank를 추가 합니다.
19 | 여기 예제에서 각 라인은 같은 결과를 출력합니다.
20 | */
21 |
22 | fmt.Printf("Hello %d\n", 23)
23 | fmt.Fprint(os.Stdout, "Hello ", 23, "\n")
24 | fmt.Println("Hello", 23)
25 | fmt.Println(fmt.Sprint("Hello ", 23))
26 | /*tutorial에서 말했던 것 처럼, fmt.Fprint와 그와 비슷한 함수들은
27 | io.Writer 인터페이스를 구현하는 어떤 오브젝트의 첫번째 인자처럼 받아들입니다.
28 | os.Stdout과 os.Stderr 변수들과 비슷한 경우 입니다.
29 |
30 | 여기 있는 예제는 C언어와 달라지기 시작하는 것을 보여줍니다.
31 | 첫번째로, %d와 같은 숫자 형식은 부호나 크기를 위한 flag를 취하지 않습니다.
32 | 대신 출력 루틴은 이런 속성들을 결정하기 위해 인자 타입을 사용합니다.
33 | */
34 |
35 | var x uint64 = 1<<64 - 1
36 | fmt.Printf("%d %x; %d %x\n", x, x, int64(x), int64(x))
37 | prints
38 |
39 | 18446744073709551615 ffffffffffffffff; -1 -1
40 | /*
41 | 만약 10진수 정수와 같은 기본 변환을 원한다면, 포괄적인 형태의 %v를 사용할 수 있습니다.
42 | (값을 위해서) 결과는 Print와 Println이 만들어 내는 것과 정확히 같습니다.
43 | 더욱이 그런 형식으로 어떤 값이든 출력할 수 있습니다.(심지어 배열, 구조체,map 까지도)
44 | 여기 앞의 예제에 정의되어 있는 time zone map을 사용하는 print문 예제가 있습니다.
45 |
46 | fmt.Printf("%v\n", timeZone) // or just fmt.Println(timeZone)
47 |
48 | 출력:
49 | map[CST:-21600 PST:-28800 EST:-18000 UTC:0 MST:-25200]
50 | 물론, map에서 key는 순서없이 출력될 것 입니다. 구조체를 출력할 때, 변형 포맷인 %+v는
51 | 구조체 필드의 이름을 표시할 것입니다. 그리고 어떤 값에 대해서든 %#v 형식은 전체 Go 구문을 출력할 것 입니다.
52 | */
53 | type T struct {
54 | a int
55 | b float
56 | c string
57 | }
58 | t := &T{ 7, -2.35, "abc\tdef" }
59 | fmt.Printf("%v\n", t)
60 | fmt.Printf("%+v\n", t)
61 | fmt.Printf("%#v\n", t)
62 | fmt.Printf("%#v\n", timeZone)
63 | prints
64 |
65 | &{7 -2.35 abc def}
66 | &{a:7 b:-2.35 c:abc def}
67 | &main.T{a:7, b:-2.35, c:"abc\tdef"}
68 | map[string] int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200}
69 | /*
70 | (&기호에 주목하십시오.) 인용부호로("") 둘러쌓인 문자열 형식은 string 또는 byte 배열(byte) 형태의
71 | 값을 적용할 때 %q를 통해서도 가능 합니다. %#q 형식은 만약 가능하다면 인용부호("") 대신 backquote(`)를
72 | 사용할 것 입니다. 또한 %x 옵션은 integer뿐만 아니라 문자열과 byte 배열에서도 동작 합니다.
73 |
74 | 그것은 긴 16진 문자열을 생성하며, %x에서 space를 사용하는 것(% x)은 byte 사이에 space를 넣게 됩니다.
75 | 또다른 유용한 형태는 값의 타입을 출력하는 %T 옵션 입니다.
76 | */
77 | fmt.Printf("%T\n", timeZone)
78 | prints
79 |
80 | map[string] int
81 | /*
82 | 만약 custom 타입을 기본 형태로 제어하기를 원한다면, 모든 요구사항은
83 | String() string 메소드에 그 타입을 정의해야 합니다. T 타입은 다음 예제와 같이 보여질 것 입니다.
84 | */
85 | func (t *T) String() string {
86 | return fmt.Sprintf("%d/%g/%q", t.a, t.b, t.c)
87 | }
88 | fmt.Printf("%v\n", t)
89 | /*
90 | to print in the format
91 |
92 | 7/-2.35/"abc\tdef"
93 | String() 메소드는 Sprintf를 호출 하는 것이 가능합니다. 왜냐하면 print 루틴은 재귀적으로 사용될 수 있기 때문입니다.
94 |
95 | 이제 한단게 더 나갈 수 있습니다. 그리고 print 루틴의 인자들을 바로 다른 루틴에 넘겨줄 수 있습니다.
96 | Printf 함수의 특징은 포맷 이후에 나타날 수도 있는 임의의 개수의 파라미터(또는 임의의 형태의 파라미터)들을
97 | 명시하기 위해 마지막 인자로 ...interface{} 타입을 사용한다는 것 입니다.
98 |
99 | */
100 | func Printf(format string, v ...interface{}) (n int, errno os.Error) {
101 | /*
102 | Printf 함수 내부에서, v는 interface{} 타입의 변수처럼 동작합니다. 하지만 만약 또 다른 가변인자 함수로 넘겨진다면,
103 | 그것은 일반적인 인자 리스트 처럼 동작할 것 입니다. 여기 log.Println을 구현한 예제가 있습니다.(위에서 사용한)
104 | 이 함수는 실제 설정을 위해 인자값들을 바로 fmt.Sprintln 함수로 넘깁니다.
105 |
106 |
107 | // Println prints to the standard logger in the manner of fmt.Println.
108 | */
109 | func Println(v ...interface{}) {
110 | std.Output(2, fmt.Sprintln(v...)) // Output takes parameters (int, string)
111 | }
112 | /*
113 | 인자 리스트로서 v를 취급하도록 컴파일러에 알려주기 위해, Sprintln에 대한 내부 호출에서 v 뒤에 ...을 사용 합니다.
114 | 그렇지 않다면, 단순히 v를 싱글 slice 인자로 넘겨줄 것 입니다.
115 |
116 | 출력 관련해서는 이 문서에서 다루고 있는 것 이상의 내용이 있습니다.
117 | fmt 팩키지에 대한 더 자세한 내용을 알고 싶다면 godoc 문서를 보십시오.
118 |
119 | 어쨌거나 ... 파라미터는 특정 타입이 될 수 있습니다. 예를 들면 integer
120 | 리스트에서 최소값을 고르는 min 함수를 위해 ...int를 사용할 수 있습니다.
121 | */
122 | func Min(a ...int) int {
123 | min := int(^uint(0) >> 1) // largest int
124 | for _, i := range a {
125 | if i < min {
126 | min = i
127 | }
128 | }
129 | return min
130 | }
--------------------------------------------------------------------------------
/effectivego/05_제어구조.go:
--------------------------------------------------------------------------------
1 | // 05_제어구조.go
2 | // https://code.google.com/p/golang-korea/wiki/EffectiveGo#제어구조(Control_structures)
3 |
4 | /*
5 |
6 | Go언어의 제어문은 C와 연관성이 있지만 중요한 차이가 있습니다.
7 | Go언어의 제어문에는 do와 while 루프가 없습니다.
8 | 오직 좀 더 일반화된 for 루프와 switch문이 있으며 더 탄력적입니다.
9 |
10 | if와 switch문은 for루프와 같이 추가적인 초기화를 지원하며,
11 | type switch와 multiway communications multiplexer, select와 같은 추가적인 새로운 제어문이 있습니다.
12 | 문법 또한 조금 다릅니다. 괄호()는 필요하지 않으며 body는 항상 중괄호({})로 구분되어져야 합니다.
13 |
14 | If
15 | Go 언어에서 if문의 간단한 예는 다음과 같습니다
16 | */
17 | if x > 0 {
18 | return y
19 | }
20 | /*
21 | 중괄호({})의 의무적인 사용은 다중 라인에서 if 문을 단순하게 만들어줍니다.
22 | 특히, body안에 return이나 break같은 제어문을 포함하고 있는 경우에는 괜찮은 방법입니다.
23 |
24 | if나 switch 문이 초기화를 지원하기 때문에, if나 switch문에서 지역변수를 설정하기 위해
25 | 이 방법을 사용하는 것을 쉽게 발견할 수 있습니다.
26 | */
27 | if err := file.Chmod(0664); err != nil {
28 | log.Print(err)
29 | return err
30 | }
31 | /*
32 | Go언어의 라이브러리에서 if문이 다음 명령문으로 진행되지 않는 경우
33 | (break, continue, goto 또는 return 때문에 body가 종료되는 상황)
34 | 불필요한 else는 생략되는 것을 발견하게 될 것 입니다.
35 | */
36 |
37 | f, err := os.Open(name, os.O_RDONLY, 0)
38 | if err != nil {
39 | return err
40 | }
41 | codeUsing(f)
42 |
43 | /*
44 | 다음은 일련의 error에 대응하기 위해 code가 보호되어야 하는 일반적인 상황에 대한 예제입니다.
45 | 만약 제어의 흐름이 성공적이라면 그 코드는 잘 동작할 것이고, error가 발생할 때마다
46 | error를 제거할 것입니다. error는 return문에서 발생하는 경향이 있기 때문에 결과 code는 else문이 필요 없습니다.
47 | */
48 |
49 | f, err := os.Open(name, os.O_RDONLY, 0)
50 | if err != nil {
51 | return err
52 | }
53 | d, err := f.Stat()
54 | if err != nil {
55 | return err
56 | }
57 | codeUsing(f, d)
58 | /*
59 | For
60 | Go언어에서 for 루프는 C언어의 for 루프와 비슷하지만 같지는 않습니다.
61 | for문과 while문은 구분되어지며 do-while문은 없습니다.
62 | 세가지 형태가 있으며 그중 하나만 세미콜론을 가지고 있습니다.
63 | */
64 |
65 | // C언어와 유사한 형태의 for문
66 | for init; condition; post { }
67 |
68 | // C언어와 유사한 형태의 while문
69 | for condition { }
70 |
71 | // C언어와 유사한 형태의 for(;;)
72 | for { }
73 |
74 | //루프에서는 짧은 선언이 index 변수를 선언하기 쉽게 만듭니다.
75 |
76 | sum := 0
77 | for i := 0; i < 10; i++ {
78 | sum += i
79 | }
80 | //만약 당신이 배열,slice, string, map, reading을 넘어서 루프를 돌고 있다면,
81 | //range문이 당신을 대신해서 루프를 관리해줄 것 입니다.
82 |
83 | var m map[string]int
84 | sum := 0
85 | for _, value := range m { // key is unused
86 | sum += value
87 | }
88 | //string의 경우, range문은 UTF-8 파싱에 의한 개별적인 유니코드 문자를 해결하는데 더욱 유익할 것입니다.
89 | //잘못된 encoding은 하나의 byte를 제거하고 U+FFFD 문자로 대체할 것입니다.
90 |
91 | //아래 루프는
92 |
93 | for pos, char := range "日本語" {
94 | fmt.Printf("character %c starts at byte position %d\n", char, pos)
95 | }
96 | //다음과 같이 출력됩니다.
97 |
98 | character 日 starts at byte position 0
99 | character 本 starts at byte position 3
100 | character 語 starts at byte position 6
101 | //마지막으로 Go언어는 콤마(,) 오퍼레이터가 없으며 ++, --는 표현식이 아니라 명령문입니다.
102 | //그러므로 만약 for문 안에서 다중 변수(multiple variable)를 사용하려 한다면 병렬 할당(parallel assignment)을 사용해야만 합니다.
103 |
104 | // Reverse a
105 | for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
106 | a[i], a[j] = a[j], a[i]
107 | }
108 | Switch
109 | Go언어에서 switch문은 C언어에서 보다 더 일반적입니다. 표현식은 상수이거나 integer일 필요가 없습니다. case문은 맨위에서 밑에까지 맞는 값을 찾을 때까지 계속 값을 비교할 것입니다. 그리고 switch문에서는 switch문을 true로 하는 표현식이 없기 때문에 switch문 대신 if-else-if-else 체인을 사용하는 것도 가능합니다.
110 |
111 | func unhex(c byte) byte {
112 | switch {
113 | case '0' <= c && c <= '9':
114 | return c - '0'
115 | case 'a' <= c && c <= 'f':
116 | return c - 'a' + 10
117 | case 'A' <= c && c <= 'F':
118 | return c - 'A' + 10
119 | }
120 | return 0
121 | }
122 | Go언어에서 switch문의 경우 자동으로 통과하는 방법을(case문을 통과하는 경우를 말함) 사용할 수 없지만 콤마(,)를 사용하여 아래 예문과 같이 각 case를 구분할 수 있습니다.
123 |
124 | func shouldEscape(c byte) bool {
125 | switch c {
126 | case ' ', '?', '&', '=', '#', '+', '%':
127 | return true
128 | }
129 | return false
130 | }
131 | 여기에 두개의 switch문을 사용하여 byte 배열을 비교하는 루틴의 예가 있습니다.
132 |
133 | // Compare 함수는 두 byte의 배열들을 비교하여 하나의 integer값을 리턴해준다.
134 | // 결과값은 만약 a == b라면 0, a < b라면 -1, a > b라면 +1을 리턴할 것이다.
135 | func Compare(a, b []byte) int {
136 | for i := 0; i < len(a) && i < len(b); i++ {
137 | switch {
138 | case a[i] > b[i]:
139 | return 1
140 | case a[i] < b[i]:
141 | return -1
142 | }
143 | }
144 | switch {
145 | case len(a) < len(b):
146 | return -1
147 | case len(a) > len(b):
148 | return 1
149 | }
150 | return 0
151 | }
152 | 또한, switch문은 동적인 형태의 interface 변수를 찾는데 사용할 수 있습니다. 그런 형태의 switch문은 괄호() 안에서 키워드의 type과 assertion type의 문법을 사용할 수 있습니다. 만약 switch문이 expression에서 변수를 선언했다면, 변수는 각 문장에 대응하는 type을 가지게 될 것입니다.
153 |
154 | switch t := interfaceValue.(type) {
155 | default:
156 | fmt.Printf("unexpected type %T", t) // %T prints type
157 | case bool:
158 | fmt.Printf("boolean %t\n", t)
159 | case int:
160 | fmt.Printf("integer %d\n", t)
161 | case *bool:
162 | fmt.Printf("pointer to boolean %t\n", *t)
163 | case *int:
164 | fmt.Printf("pointer to integer %d\n", *t)
165 | }
166 |
167 | */
--------------------------------------------------------------------------------
/packages/net/00_오버뷰.go:
--------------------------------------------------------------------------------
1 | /*
2 | http://golang.org/pkg/net/
3 |
4 | net패키지는 네트워크 입출력을 위한 휴대용(portable) 인터페이스를 제공합니다.
5 | TCP/IP , UDP , 도메인네임 추출(원래 영어단어는 resolution으로 적었다), 유닉스 도메인소켓같은 것들을 포함합니다.
6 |
7 | 비록 패키지가 low레벨 네트워크 요소들에 대한 접근을 제공하지만,
8 | 대부분의 클라이언트들은 Dial, Listen, Accect function들이 제공하는
9 | 기초적 인터페이스들만을 필요로 할 것입니다. (맞게 적었나;;)
10 |
11 |
12 | crypto/tls 패키지는 같은 인터페이스를 사용하고, 비슷한 Dial , Listen function을 이용합니다.
13 | Dial function은 서버로 접속합니다.
14 |
15 | */
16 | conn, err := net.Dial("tcp", "google.com:80")
17 | if err != nil {
18 | // handle error
19 | }
20 | fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
21 | status, err := bufio.NewReader(conn).ReadString('\n')
22 | // ...
23 |
24 | /* Listen function은 서버를 생성합니다 */
25 | ln, err := net.Listen("tcp", ":8080")
26 | if err != nil {
27 | // handle error
28 | }
29 | for {
30 | conn, err := ln.Accept()
31 | if err != nil {
32 | // handle error
33 | }
34 | go handleConnection(conn)
35 | }
36 |
37 | /*
38 | API
39 |
40 | Constants
41 | Variables
42 | func InterfaceAddrs() ([]Addr, error)
43 | func Interfaces() ([]Interface, error)
44 | func JoinHostPort(host, port string) string
45 | func LookupAddr(addr string) (name []string, err error)
46 | func LookupCNAME(name string) (cname string, err error)
47 | func LookupHost(host string) (addrs []string, err error)
48 | func LookupIP(host string) (addrs []IP, err error)
49 | func LookupMX(name string) (mx []*MX, err error)
50 | func LookupNS(name string) (ns []*NS, err error)
51 | func LookupPort(network, service string) (port int, err error)
52 | func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error)
53 | func LookupTXT(name string) (txt []string, err error)
54 | func SplitHostPort(hostport string) (host, port string, err error)
55 | type Addr
56 | type AddrError
57 | func (e *AddrError) Error() string
58 | func (e *AddrError) Temporary() bool
59 | func (e *AddrError) Timeout() bool
60 | type Conn
61 | func Dial(network, address string) (Conn, error)
62 | func DialTimeout(network, address string, timeout time.Duration) (Conn, error)
63 | func FileConn(f *os.File) (c Conn, err error)
64 | func Pipe() (Conn, Conn)
65 | type DNSConfigError
66 | func (e *DNSConfigError) Error() string
67 | func (e *DNSConfigError) Temporary() bool
68 | func (e *DNSConfigError) Timeout() bool
69 | type DNSError
70 | func (e *DNSError) Error() string
71 | func (e *DNSError) Temporary() bool
72 | func (e *DNSError) Timeout() bool
73 | type Dialer
74 | func (d *Dialer) Dial(network, address string) (Conn, error)
75 | type Error
76 | type Flags
77 | func (f Flags) String() string
78 | type HardwareAddr
79 | func ParseMAC(s string) (hw HardwareAddr, err error)
80 | func (a HardwareAddr) String() string
81 | type IP
82 | func IPv4(a, b, c, d byte) IP
83 | func ParseCIDR(s string) (IP, *IPNet, error)
84 | func ParseIP(s string) IP
85 | func (ip IP) DefaultMask() IPMask
86 | func (ip IP) Equal(x IP) bool
87 | func (ip IP) IsGlobalUnicast() bool
88 | func (ip IP) IsInterfaceLocalMulticast() bool
89 | func (ip IP) IsLinkLocalMulticast() bool
90 | func (ip IP) IsLinkLocalUnicast() bool
91 | func (ip IP) IsLoopback() bool
92 | func (ip IP) IsMulticast() bool
93 | func (ip IP) IsUnspecified() bool
94 | func (ip IP) MarshalText() ([]byte, error)
95 | func (ip IP) Mask(mask IPMask) IP
96 | func (ip IP) String() string
97 | func (ip IP) To16() IP
98 | func (ip IP) To4() IP
99 | func (ip *IP) UnmarshalText(text []byte) error
100 | type IPAddr
101 | func ResolveIPAddr(net, addr string) (*IPAddr, error)
102 | func (a *IPAddr) Network() string
103 | func (a *IPAddr) String() string
104 | type IPConn
105 | func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error)
106 | func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error)
107 | func (c *IPConn) Close() error
108 | func (c *IPConn) File() (f *os.File, err error)
109 | func (c *IPConn) LocalAddr() Addr
110 | func (c *IPConn) Read(b []byte) (int, error)
111 | func (c *IPConn) ReadFrom(b []byte) (int, Addr, error)
112 | func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error)
113 | func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error)
114 | func (c *IPConn) RemoteAddr() Addr
115 | func (c *IPConn) SetDeadline(t time.Time) error
116 | func (c *IPConn) SetReadBuffer(bytes int) error
117 | func (c *IPConn) SetReadDeadline(t time.Time) error
118 | func (c *IPConn) SetWriteBuffer(bytes int) error
119 | func (c *IPConn) SetWriteDeadline(t time.Time) error
120 | func (c *IPConn) Write(b []byte) (int, error)
121 | func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error)
122 | func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error)
123 | func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error)
124 | type IPMask
125 | func CIDRMask(ones, bits int) IPMask
126 | func IPv4Mask(a, b, c, d byte) IPMask
127 | func (m IPMask) Size() (ones, bits int)
128 | func (m IPMask) String() string
129 | type IPNet
130 | func (n *IPNet) Contains(ip IP) bool
131 | func (n *IPNet) Network() string
132 | func (n *IPNet) String() string
133 | type Interface
134 | func InterfaceByIndex(index int) (*Interface, error)
135 | func InterfaceByName(name string) (*Interface, error)
136 | func (ifi *Interface) Addrs() ([]Addr, error)
137 | func (ifi *Interface) MulticastAddrs() ([]Addr, error)
138 | type InvalidAddrError
139 | func (e InvalidAddrError) Error() string
140 | func (e InvalidAddrError) Temporary() bool
141 | func (e InvalidAddrError) Timeout() bool
142 | type Listener
143 | func FileListener(f *os.File) (l Listener, err error)
144 | func Listen(net, laddr string) (Listener, error)
145 | type MX
146 | type NS
147 | type OpError
148 | func (e *OpError) Error() string
149 | func (e *OpError) Temporary() bool
150 | func (e *OpError) Timeout() bool
151 | type PacketConn
152 | func FilePacketConn(f *os.File) (c PacketConn, err error)
153 | func ListenPacket(net, laddr string) (PacketConn, error)
154 | type ParseError
155 | func (e *ParseError) Error() string
156 | type SRV
157 | type TCPAddr
158 | func ResolveTCPAddr(net, addr string) (*TCPAddr, error)
159 | func (a *TCPAddr) Network() string
160 | func (a *TCPAddr) String() string
161 | type TCPConn
162 | func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error)
163 | func (c *TCPConn) Close() error
164 | func (c *TCPConn) CloseRead() error
165 | func (c *TCPConn) CloseWrite() error
166 | func (c *TCPConn) File() (f *os.File, err error)
167 | func (c *TCPConn) LocalAddr() Addr
168 | func (c *TCPConn) Read(b []byte) (int, error)
169 | func (c *TCPConn) ReadFrom(r io.Reader) (int64, error)
170 | func (c *TCPConn) RemoteAddr() Addr
171 | func (c *TCPConn) SetDeadline(t time.Time) error
172 | func (c *TCPConn) SetKeepAlive(keepalive bool) error
173 | func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error
174 | func (c *TCPConn) SetLinger(sec int) error
175 | func (c *TCPConn) SetNoDelay(noDelay bool) error
176 | func (c *TCPConn) SetReadBuffer(bytes int) error
177 | func (c *TCPConn) SetReadDeadline(t time.Time) error
178 | func (c *TCPConn) SetWriteBuffer(bytes int) error
179 | func (c *TCPConn) SetWriteDeadline(t time.Time) error
180 | func (c *TCPConn) Write(b []byte) (int, error)
181 | type TCPListener
182 | func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error)
183 | func (l *TCPListener) Accept() (Conn, error)
184 | func (l *TCPListener) AcceptTCP() (*TCPConn, error)
185 | func (l *TCPListener) Addr() Addr
186 | func (l *TCPListener) Close() error
187 | func (l *TCPListener) File() (f *os.File, err error)
188 | func (l *TCPListener) SetDeadline(t time.Time) error
189 | type UDPAddr
190 | func ResolveUDPAddr(net, addr string) (*UDPAddr, error)
191 | func (a *UDPAddr) Network() string
192 | func (a *UDPAddr) String() string
193 | type UDPConn
194 | func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error)
195 | func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error)
196 | func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error)
197 | func (c *UDPConn) Close() error
198 | func (c *UDPConn) File() (f *os.File, err error)
199 | func (c *UDPConn) LocalAddr() Addr
200 | func (c *UDPConn) Read(b []byte) (int, error)
201 | func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error)
202 | func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error)
203 | func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error)
204 | func (c *UDPConn) RemoteAddr() Addr
205 | func (c *UDPConn) SetDeadline(t time.Time) error
206 | func (c *UDPConn) SetReadBuffer(bytes int) error
207 | func (c *UDPConn) SetReadDeadline(t time.Time) error
208 | func (c *UDPConn) SetWriteBuffer(bytes int) error
209 | func (c *UDPConn) SetWriteDeadline(t time.Time) error
210 | func (c *UDPConn) Write(b []byte) (int, error)
211 | func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error)
212 | func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error)
213 | func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error)
214 | type UnixAddr
215 | func ResolveUnixAddr(net, addr string) (*UnixAddr, error)
216 | func (a *UnixAddr) Network() string
217 | func (a *UnixAddr) String() string
218 | type UnixConn
219 | func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error)
220 | func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error)
221 | func (c *UnixConn) Close() error
222 | func (c *UnixConn) CloseRead() error
223 | func (c *UnixConn) CloseWrite() error
224 | func (c *UnixConn) File() (f *os.File, err error)
225 | func (c *UnixConn) LocalAddr() Addr
226 | func (c *UnixConn) Read(b []byte) (int, error)
227 | func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error)
228 | func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err error)
229 | func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error)
230 | func (c *UnixConn) RemoteAddr() Addr
231 | func (c *UnixConn) SetDeadline(t time.Time) error
232 | func (c *UnixConn) SetReadBuffer(bytes int) error
233 | func (c *UnixConn) SetReadDeadline(t time.Time) error
234 | func (c *UnixConn) SetWriteBuffer(bytes int) error
235 | func (c *UnixConn) SetWriteDeadline(t time.Time) error
236 | func (c *UnixConn) Write(b []byte) (int, error)
237 | func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error)
238 | func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error)
239 | func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err error)
240 | type UnixListener
241 | func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error)
242 | func (l *UnixListener) Accept() (c Conn, err error)
243 | func (l *UnixListener) AcceptUnix() (*UnixConn, error)
244 | func (l *UnixListener) Addr() Addr
245 | func (l *UnixListener) Close() error
246 | func (l *UnixListener) File() (f *os.File, err error)
247 | func (l *UnixListener) SetDeadline(t time.Time) (err error)
248 | type UnknownNetworkError
249 | func (e UnknownNetworkError) Error() string
250 | func (e UnknownNetworkError) Temporary() bool
251 | func (e UnknownNetworkError) Timeout() bool
252 | Bugs
253 |
254 | */
--------------------------------------------------------------------------------