├── 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 | */ --------------------------------------------------------------------------------